Cmake link library target link error
The syntax for target_link_libraries
is:
target_link_libraries(your_executable_name libraries_list)
And you don't have to add add_definition
statements (target_link_libraries
adds this options)
There are also some useful variables provided by OpenGL and GLEW packages.
Your CMakeLists.txt should be like:
cmake_minimum_required (VERSION 2.6)
project (test)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS})
add_executable(test
main.cpp
)
target_link_libraries(test ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES})
One important detail to keep in mind is to place the target_link_libraries
after the add_executable
(or add_library
) line.
Getting a CMake Error: Cannot specify link libraries for target which is not built by the project
The first argument of target_link_libraries
is the target name:
target_link_libraries(eCAD Qt5::Widgets Qt5::Core)
How to get target_link_libraries throw miss or errors
A simple solution is to check if it's a target. Probably somewhere on the end of your file, at least after add_subdirectory(libC)
if(NOT TARGET libC)
message(FATAL_ERROR "Och nuu, libC is not a target")
endif()
A great solution would be to implement a target_link_targets
functionality, which would allow linking only with targets. While sounds trivial, it's not so easy - static libraries can be linked circular and can be before they are defined. So you have to check if all are targets on the end of CMake file after we know every target is defined.
I did such implementation, my implementation is available here. The function k_target_link_targets
checks if all arguments are targets. From CMake 3.19.0 it uses cmake_language(DEFER
to defer execution of a checking function to the end of CMake scripts, before 3.19.0 a manual call to k_target_link_targets_check
function is needed on the end of a CMake file.
CMake target_link_libraries converting path which results in linker not found error
You should link against targets, not files if those targets are part of your project. In your case it would be target_link_libraries(mytest mymodule)
.
But if for some reason the need arises to link against a full path, CMake has some peculiarities which are described in the docs. So in your case it converts the full path to -lmymodule
because it is a behavior CMake exhibits if the full path provided to the library w/o proper soname.
cmake target_link_libraries(), when should we use?
target_link_libraries
does different things depending on the parameter passed. If you should use it or not depends on what exactly you're trying to achieve. (I'd recommend using target_include_directories
instead of include_directories
though, since it limits the use of the include dir to a single target and also allows you to make include dirs available to linking cmake library targets, if the headers are used in public headers of a library target.)
- You can pass the name of a library target. Passing an
INTERFACE
library target is an option which can be used with header only libraries. Furthermore for installed external libraries providing cmake find/configuration scripts (usually) allows you to gain access toIMPORTED
library targets that automatically make include dirs and dependencies for the target available to the target linking viatarget_link_libraries
, if set up properly. I strongly recommend using this option with boost. - You can pass the full path to a library file. I recommend creating an imported library target instead though; this may be a bit more work, but it also allows you to attach info to the target such as include directories which puts related info in the same place and allows for easier reuse.
- You can pass names of libraries the linker is able to find, e.g.
target_link_libraries(executable pthread)
on Linux. - ... (Some other options I don't really consider relevant here.)
My recommendation in your case would be:
- Make sure you've installed boost
- Use
find_package
+target_link_libraries
to "link" the header lib which in this case is just a clean way of making the headers available to your target. (I assume you're using boost as a header only lib, not the static or shared version of the lib.)
find_package(Boost REQUIRED COMPONENTS headers CONFIG PATHS "/your/boost/install/path")
target_link_libraries(executable PRIVATE Boost::headers)
Note that the program won't be any faster of slower compared to using include_directories
to specify the input directory; the speed of the cmake configuration may change a bit, but I don't recommend cutting any corners there.
Need help understanding linking with cmake
I had a basic understanding that libraries were a collection of objects/symbols, so I had assumed that by linking foo to bar, bar would also have those objects/symbols, but that is not the case, so I am wondering if I am missing something or if I am doing something wrong.
Indeed this is not quite the case. The C/C++ language standards do not define the contents of static libraries, but on most platforms they are archives containing specific object files. If those object files collectively depend on external symbols, then that static library depends on some other library or object file and all must be linked into the final executable.
"Linking" one static library to another in CMake merely declares the dependency between them. There is no platform-independent mechanism for merging them nor, within CMake, is there a pressing need to do so.
I do not want to use SHARED libraries, I would prefer to stay with STATIC libraries, how can I have my libraries keep all the objects/symbols? Am I forced to link both bar and foo?
There are many questions and answers on StackOverflow detailing how to use OBJECT
libraries to accomplish this. Here's, say, five:
- https://stackoverflow.com/a/11448878/2137996
- https://stackoverflow.com/a/10635366/2137996
- https://stackoverflow.com/a/68866472/2137996
- https://stackoverflow.com/a/67435497/2137996
- https://stackoverflow.com/a/68406028/2137996
Yet, I would say that all of these questions are misguided. CMake handles linking library dependencies just fine.
Related Topics
Should "Delete This" Be Called from Within a Member Method
With C++, I Get Pointer with 0Xcdcdcdcd When Creating a Class - What Is Happening
How to Check If a File Is Gzip Compressed
Will Consteval Allow Using Static_Assert on Function Arguments
How to Config Cmake for Strip File
Check If Class Is Derived from a Specific Class (Compile, Runtime Both Answers Available)
C++: Function Pointer to Functions with Variable Number of Arguments
How to Execute a Clion Program in Gnome Terminal
C++ Copy Constructor Gets Called Instead of Initializer_List<>
Stl Map Containing References Does Not Compile
Cmake Imported Library Behaviour
Compiling and Linking Third Party Libraries in VS 2015
Why Isn't Operator Overloading for Pointers Allowed to Work
Why Does My Stl Code Run So Slowly When I Have the Debugger/Ide Attached
How to Statically-Initialize a Dynamically-Allocated Array in C++