Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cmake: target_link_libraries propagation of include directories

Tags:

cmake

I have a small static library that requires boost headers and that requires the "include" directory in the include directories.

...
add_library(alib STATIC ...)
target_include_directories(alib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(alib PRIVATE ${Boost_INCLUDE_DIRS})
...

I have another installation on the system of alib, exactly where ${Boost_INCLUDE_DIRS} point to, but this is an older version, required by other packages of my system. The point is that I want to build a custom version of alib as a target of my project. So this is very important that nothing from the system alib is being included or linked against.

Now I have another library mylib that depends on alib, so I do the following:

...
add_library(mylib STATIC ...)
target_link_libraries(mylib PUBLIC alib)
target_include_directories(mylib PRIVATE ${EXPAT_INCLUDE_DIRS})
...

The target_link_libraries(mylib PUBLIC alib) call properly add includes from alib but it includes them AFTER the includes specified by the second line target_include_directories(mylib PRIVATE ${EXPAT_INCLUDE_DIRS}), even though they are specified afterwards.

Problem is that ${EXPAT_INCLUDE_DIRS} points to the include path where the system alib is located.

It shouldn't matter if Cmake would correctly append include directories in the order they are provided, that is, the ones of target_link_libraries(mylib PUBLIC alib)then the ones of target_include_directories(mylib PRIVATE ${EXPAT_INCLUDE_DIRS}).

However cmake does not respect this order and appends the include directories from the call of target_link_libraries in the end of the command line, resulting in the system headers being picked up instead of my alib version headers.

I cannot change the name of directories of alib in any way. My current solution is to hack a custom call to target_include_directories by referencing the alib target manually:

target_include_directories(mylib PUBLIC $<TARGET_PROPERTY:alib,INCLUDE_DIRECTORIES>)

Is there a better way of doing so? How can I force Cmake to include directories of alib right-away in the target_link_directories call, and not after ?

like image 264
Lex Avatar asked Nov 08 '17 09:11

Lex


Video Answer


1 Answers

No, your "hack" is more or less the recommended way in the documentation:

For example, if the linked libraries for a target must be specified in the order lib1 lib2 lib3, but the include directories must be specified in the order lib3 lib1 lib2:

target_link_libraries(myExe lib1 lib2 lib3)
target_include_directories(myExe
  PRIVATE $<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>)
like image 119
Florian Avatar answered Nov 16 '22 02:11

Florian