Possible to add an imported library to target_link_libraries that takes care of include directories too?
The difference between the INCLUDE_DIRECTORIES
property and the INTERFACE_INCLUDE_DIRECTORIES
property is transitivity.
Set INTERFACE_INCLUDE_DIRECTORIES
instead.
http://www.cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#transitive-usage-requirements
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.
CMake Include dependencies of imported library without linking
I have given you example a try. You should change the code in your example to:
set_target_properties(
Foo::Foo PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES
"/path/to/include/blah;/path/to/include/other"
IMPORTED_LINK_INTERFACE_LIBRARIES "blah.a"
IMPORTED_LOCATION "/path/to/libfoo.a-or-so"
)
The call to set_target_properties()
only accepts "property" / "value" pairs (with spaces as delimiter). And your example just wasn't throwing any errors because you can always define your own properties (with any naming).
Please transfer your include directory list into a "CMake List" (string with semicolon separated elements).
Alternative
If you just want to "reset" the transitive libraries you can do this with e.g.:
target_link_libraries(bar Foo::Foo)
set_target_properties(bar PROPERTIES INTERFACE_LINK_LIBRARIES "")
I've used this approach when I was building a shared library in the same project as I was linking against the same (and I did not want the library dependencies of the shared library also being linked into the target using the shared library).
References
target_link_libraries()
How to make static imported library dependent on another static imported library in CMake?
The feature which I was looking for (add dependency of static import library on other import libraries) is called transitive linking. It is implemented by setting target property IMPORTED_LINK_INTERFACE_LIBRARIES. They say this property is depricated and recommend using INTERFACE_LINK_LIBRARIES, but in my case (cmake version 2.8.11.2) only IMPORTED_LINK_INTERFACE_LIBRARIES is working.
So for example above the end of CMakeLists.tst for LibA should look like this:
add_library(LibC STATIC IMPORTED)
a̶d̶d̶_̶d̶e̶p̶e̶n̶d̶e̶n̶c̶i̶e̶s̶(̶L̶i̶b̶A̶ ̶L̶i̶b̶C̶)̶
set_property(TARGET LibC PROPERTY IMPORTED_LOCATION /path/to/LibC)
set_property(TARGET LibA PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES LibC)
Hope this information will be useful for someone.
Related Topics
Stl Map Should Use Find() or [N] Identifier to Find Element in Map
Const Pointer Assign to a Pointer
Pointers as Keys in Map C++ Stl
Best Way to Do Variant Visitation with Lambdas
Calling Function Template Specialization Using C Calling Conventions
How to Set Application Icon in a Qt-Based Project
Why Can't I Put a Variable Declaration in the Test Portion of a While Loop
Fast Implementation of Trigonometric Functions for C++
How to Detect Possible/Potential Stack Overflow Problems in a C/C++ Program
Creating a New Object from Dynamic Type Info
Direct Boost Serialization to Char Array
C++ Unordered_Map Fail When Used with a Vector as Key
Correct Way to Inherit from Std::Exception
Qt 4.X: How to Implement Drag-And-Drop Onto the Desktop or into a Folder
How to Build a Full Path String (Safely) from Separate Strings