Cmake cannot find library using link_directories
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:
Note that this command [
link_directories
] is rarely necessary. Library locations returned
byfind_package()
andfind_library()
are absolute paths. Pass these
absolute library file paths directly to thetarget_link_libraries()
command. CMake will ensure the linker finds them.
So instead, always pass absolute paths to target_link_libraries
and use find_library
to resolve the link directory:
find_library(PROTOBUF_LIBRARY protobuf HINTS /usr/lib/x86_64-linux-gnu)
target_link_libraries(test PUBLIC ${PROTOBUF_LIBRARY})
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.
Linking with CMakeLists: ld cannot find library
That's because when linking, the linker doesn't look in the current directory but only in a set of predefined directories.
You need to tell CMake where the library is, for example by giving the full path to the library in the target_link_library
command, or adding it as an imported library.
CMake TARGET_LINK_LIBRARIES cannot find -lfoo but it is in the same directory as another library
Not sure, but it seems to me that CMake is looking for libfoo1.so
whereas the file is actually foo1.so
(the same applies for foo2
and foo3
)
Try "importing" the libs:
add_library(foo1 SHARED IMPORTED)
set_property(TARGET foo1 PROPERTY IMPORTED_LOCATION "/home/sources/lib/libfoo1.so")
# same thing for foo2 and foo3 ...
target_link_libraries(MyProj foo1 foo2 foo3)
EDIT
There's also the possibility to provide the full path to the library:
target_link_libraries(MyProj "/home/sources/lib/libfoo1.so"
"/home/sources/lib/libfoo2.so"
"/home/sources/lib/libfoo3.so")
Can not find object file with cmake link_directories
Documentation for target_link_libraries
doesn't allow a relative path (audioconvert.o
) to be a parameter to that command. It should be either absolute path (/home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/audioconvert.o
) or a plain library name (like z
for libz.a
library).
Because the object file audioconvert.o
is not a library, it cannot be specified with a plain library name. You have no other choice than specify an absolute path for the object files.
For specify several object files in some directory you may use foreach
loop:
foreach(obj audioconvert.o foo.o bar.o)
target_link_libraries(FFMPEGTest /home/stiv2/jsoft/nv-ffmpeg/ffmpeg/libswresample/${obj})
endforeach()
Actually, every parameter <param>
to target_link_libraries
, which doesn't look like an absolute path (and doesn't corresponds to a library target), is transformed into -l<param>
option for the linker.
The linker interprets this parameter as a plain library name, and searches for a file named lib<param>.a
or lib<param>.so
in the link directories.
So, with parameter -laudioconvert.o
the linker searches a file with a name libaudioconvert.o.a
- obviously, this is not what do you want.
cmake: cannot find the shared library when coming to link stage
Many thanks to Tsyvarev.
Let me sum up the issue and solution:
The linker can not find the library due to the incorrect path. I used link_directories(absolute/path/to/lib)
, and it returned a duplicate path. Instead, using link_directories(${PROJECT_SOURCE_DIR}/lib)
solved the problem. The linker has the correct path and find the library.
In the meantime, I remove the -static
option for CFLAGS
. This option may also cause the linker not finding the library.
Related Topics
Std::Endl Is of Unknown Type When Overloading Operator≪≪
How to Make My Program Watch For File Modification in C++
Are Members of a C++ Struct Initialized to 0 by Default
Scope Resolution Operator Without a Scope
How to Link C++ Program With Boost Using Cmake
Dynamical Two Dimension Array According to Input
How to Turn on (Literally) All of Gcc'S Warnings
When Can Outer Braces Be Omitted in an Initializer List
What Is the Partial Ordering Procedure in Template Deduction
When Should I Use Std::Thread::Detach
Random Number Generation in C++11: How to Generate, How Does It Work
Why Does C++ Allow Us to Surround the Variable Name in Parentheses When Declaring a Variable
How to Find the Index of Current Object in Range-Based For Loop