I Ubuntu, I am learning about cmake and make, and just trying a simple example. I have two directories: src
and build
. In src
, I have two files: main.cpp
, and CMakeLists.txt
, which has (only) the following text:
add_executable(test main.cpp)
link_directories(/usr/lib/x86_64-linux-gnu)
target_link_libraries(test protobuf)
In /usr/lib/x86_64-linux-gnu
, there is a shared library called libprotobuf.so
, which I want to link against. My main.cpp
uses functions in this library, by including the releveant header file, #include <google/protobuf/message.h>
.
Now, in my build
directory, I run cmake ../src
, and then make
. However, I then get linker errors telling me that there are undefined references to some of the functions in the protobuf library. If I do a search through all the files and subdirectories in build
, there is not mention of anything related to protobuf.
However, if I remove the link_directories
line in my CMakeLists.txt
file, and instead write the full path to the library when specifying the executable, i.e. target_link_libraries(test /usr/lib/x86_64-linux-gnu/libprotobuf.so)
, it compiles and links fine.
Why is link_directories
not allowing cmake to find this library?
Make sure that the order will be link_directories, set PROJECT_LINK_LIBS, add_executable and then target_link_libraries.
Below is example to demonstarte it:
Do not use
link_directories
like this in CMake.This is a common beginner's mistake, as many other build environments work like this, but in CMake it's just asking for trouble. Even the manpage specifically advises against it:
So instead, always pass absolute paths to
target_link_libraries
and usefind_library
to resolve the link directory:This has the huge benefit that you will probably get a diagnostic at CMake configure time if the expected library cannot be found, instead of a random linker error at compile time. Also, this allows the user to specify a library location via the GUI if the target machine has a non-standard directory layout.
So if it doesn't work right away, be sure to check the result of the
find_library
call and consult the manpage to track down why it doesn't find your library as intended.Make sure that your call to
link_directories
takes place before your call to the relevantadd_executable
.I had mistakenly believed it only needed to be before the call to
target_link_libraries
, but that's not the case. After moving the call, the library is linked properly.Here is an extract from the documentation:
the command
creates a target names test. Also you musst put link_directories command above the add_executable.