How to create cmake-only headers library that depends on external header files?

I have a project with the following structure:

project | |-------> lib1 | |----> lib1.h | |-------> lib2 | |----> lib2.h | |-------> main.cc 

The two libs lib1 and lib2 contain only header files, and lib2.h includes lib1.h , and main.cc includes lib2.h

How do I write a cmake file for this project now? I tried to create an interface library for lib2 , but the compiler cannot find lib1.h Here are the contents of my cmake files:

CMakeLists.txt for lib2:

 add_library(lib2 INTERFACE) target_sources(lib2 INTERFACE lib2.h) target_include_directories(lib2 INTERFACE ../lib1/lib1.h) 

CMakeLists.txt for the whole project:

 add_executable(project main.cc) target_link_libraries(project lib2) 

What is the problem in cmake files?

+5
source share
2 answers

As pointed out in the comments, target_include_directories should specify the path to the directory, not the file.

In addition, if you want to create a dependency for lib2 on lib1 , you must do this through target_link_libraries : the dependency depends not only on the inclusion directories, but also on compilation options, definitions, target properties ...

target_sources does not work with interface libraries. From this answer , you can use a custom target without commands to bind sources to the target without affecting the build process (for msvc, this makes sources available through the IDE, AFAIK this is useless for other build tools).

Your cmake might look like this:

 add_library(lib1 INTERFACE) target_sources(lib1 INTERFACE lib1.h) target_include_directories(lib1 INTERFACE "${PROJECT_SOURCE_DIR}/lib1" ) add_library(lib2 INTERFACE) if(MSVC) add_custom_target(lib2.headers SOURCES lib2.h) endif() target_include_directories(lib2 INTERFACE "${PROJECT_SOURCE_DIR}/lib2" ) target_link_libraries(lib2 lib1) add_executable(project main.cc) target_link_libraries(project lib2) 

Extended tip: you can specify a different directory in target_include_directories for the assembly tree and installation tree (see the documentation ):

 target_include_directories(lib1 INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib1> $<INSTALL_INTERFACE:${YOUR_INSTALL_DIR}/lib1> ) 
+7
source

I used the empty _only_for_compiling_the_lib.cpp file as the easiest and fastest workaround, but it is clear that this solution is highly recommended.

I just did not know the keyword INTERFACE .

0
source

Source: https://habr.com/ru/post/1257765/


All Articles