Issue
When I pass a target to target_link_libraries(), it worked fine. But when I pass a .a file (the "worked fine target" produced), it worked fine while compiling but produced many errors while linking.
I have a project, and the CMakeFiles.txt is like this:
file (sources a.cc b.cc ...)
add_executable(my_project ${sources})
Now I want to produce a static library using the same source files to support another project. So the CMakeFiles.txt is like this:
file (sources a.cc b.cc ...)
add_library(my_project ${sources})
add_executable(another_project main.cc)
target_link_libraries(another_project my_project)
It works fine, But when I try to link .a file directly like this
target_link_libraries(another_project libmy_project.a)
And it produced lots of "undefined reference to" or "multiple defination to" error when linking the target.
So what exactly happen when pass a target to "target_link_libraries"?
Solution
First, if you link the target against a file, you should first ensure this file exists before linking happens, thus you should add target dependencies between the executable and library targets (provided both are part of the same CMake project)
add_dependencies(another_project my_project)
Second, if you link against an arbitrary file (which is not any of the system libraries), you are supposed either provide full path to the file:
target_link_libraries(another_project ${CMAKE_CURRENT_BINARY_DIR}/libmy_project.a)
Or add the folder where the library is located to the current library search directories list:
link_directories(${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(another_project libmy_project.a)
So what exactly happen when pass a target to "target_link_libraries"?
Simply put, when CMake hits a reference to a library in a form of libName.a
, it just adds -lName
flag and lets the linker locate the library itself. The linker then fails, because it looks for corresponding archives under LIBRARY_PATH
paths only.
Answered By - The Dreams Wind Answer Checked By - Dawn Plyler (WPSolving Volunteer)