4

It has been years since I worked in C++, and I've never used CMake before. I'm trying to compile a program called ngmlr, which uses CMake. It worked seamlessly on other systems I tried to build it on. This time around, CMake finds ZLIB (Found ZLIB: /usr/lib64/libz.so (found version "1.2.3")), as required by ngmlr, but the subsequent make fails with ld: cannot find -lz.

I think I know what's happening: CMake found the dynamic ZLIB library (libz.so), but the CMakeLists.txt file requires static (I found the following option in the file: option(STATIC "Build static binary" ON)). As far as I can tell, the static library (libz.a) is missing on this machine. It's not in the same /usr/lib64 directory as libz.so. locate is not available.

Questions:

  1. Does that seem correct?
  2. For education, assuming this is the problem, can you force CMake to look specifically for static ZLIB? e.g., since the developer required static, it would have been nice to immediately know the missing static library was the problem, rather than the embarrassingly long amount of time it took me to figure it out.

I've looked extensively for a clear answer to both, but didn't find anything conclusive (e.g., Force cmake to use static libraries).

UPDATE I did confirm that the problem is that ld could not find the static library. Now I'm particularly interested to know if the developer can tell CMake to throw an error if the static libraries are not present, and save someone else.

cmake version 2.8.8

Mark Ebbert
  • 441
  • 3
  • 13

3 Answers3

3
  1. Yes
  2. Generally speaking it is up to Find-module authors. Some modules have special "static" option, others do not. Particularly Zlib module has not. That's why cmake global variable is set in subdirectory src/CMakeLists.txt: SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a"). But it is invoked after find_package( ZLIB REQUIRED ) command. Looks like a bug.

Now I'm particularly interested to know if the developer can tell CMake to throw an error if the static libraries are not present, and save someone else.

REQUIRED means that error will be thrown if package was not found. In your case it should be thrown if you move SET(CMAKE_FIND_LIBRARY_SUFFIXES before find_package

Perhaps you can build your project if disable STATIC option

cmake -G"Unix Makefiles" _PATH_ -DSTATIC=OFF
vatosarmat
  • 1,090
  • 10
  • 22
  • 1
    Yes, I moved `SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")` to just before `find_package( ZLIB REQUIRED )` and that throws the appropriate error! I was able to finish building the project by disabling static. – Mark Ebbert Jun 24 '17 at 22:14
  • 1
    I was able to get the static version by doing this, in case this helps anyone else: `set(_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})` `set(CMAKE_FIND_LIBRARY_SUFFIXES "static.lib")` `find_package(ZLIB ${ZLIB_VERSION} REQUIRED MODULE)` `set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CMAKE_FIND_LIBRARY_SUFFIXES})` `unset(_CMAKE_FIND_LIBRARY_SUFFIXES)` – GenericAccountName Aug 27 '19 at 19:30
  • 1
    @GenericAccountName That should really have been written as an answer. – Some programmer dude Jun 08 '20 at 08:17
  • @Someprogrammerdude there was already an accepted answer and I wasn't sure if it would be helpful, but I'm happy to add it as an answer as well. Thanks for the input. – GenericAccountName Jun 09 '20 at 12:50
2

I'm no cmake expert, but in case this helps anyone. I had found setting CMAKE_FIND_LIBRARY_SUFFIXES successfully loaded the static lib, but I only wanted this for finding ZLIB, so I saved the previous value, set CMAKE_FIND_LIBRARY_SUFFIXES and reset it like so:

set(_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES "static.lib") 
find_package(ZLIB ${ZLIB_VERSION} REQUIRED MODULE) 
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CMAKE_FIND_LIBRARY_SUFFIXES}) 
unset(_CMAKE_FIND_LIBRARY_SUFFIXES)
-2

Your CMakeLists.txt probably has this somewhere:

find_library(ZLIB z)

You can replace it with:

find_library(ZLIB libz.a)
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 2
    thank you for the suggestion. I'm not sure if I did something wrong, but that doesn't seem to work. The existing call is `find_package( ZLIB REQUIRED )`. I tried `find_package( ZLIB REQUIRED libz.a )`, but I still see get the following result: `Found ZLIB: /usr/lib64/libz.so (found version "1.2.3")`. I also tried changing `find_package` to `find_library`, but that doesn't appear to find `zlib` at all (nor does CMake throw an error). I do get undefined compiler errors for `zlib` functions (e.g., `gzopen`). – Mark Ebbert Jun 24 '17 at 16:31