1
votes

Based on this stackoverflow answer to a similar question (Cmake include header only target from header only target), I am creating a header only library and trying to use it in an executable.

My folder structure is below:

├── CMakeLists.txt   // root folder CMake file
├── srcs             // this is the hdr only library
│   ├── src1.hpp
│   ├── CMakeLists.txt
│   ├── src2.hpp
│   └── src3.hpp
│   └── ...
└── test             // this is the executable project
    ├── CMakeLists.txt
    └── main.cpp

Root level CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project (MyProj CXX) 

add_subdirectory(srcs)
add_subdirectory(test)

src level CMakeLists.txt (for header only library)

add_library(MyLib INTERFACE)
target_sources(MyLib  INTERFACE
  "${CMAKE_CURRENT_SOURCE_DIR}/src1.hpp"
  "${CMAKE_CURRENT_SOURCE_DIR}/src2.hpp"
  "${CMAKE_CURRENT_SOURCE_DIR}/src3.hpp"
  )
target_include_directories(MyLib 
  INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(plugins)

CMake file for executable test project

add_executable(MyTest main.cpp)

target_sources(MyTest 
    PRIVATE main.cpp
)

target_include_directories(MyTest PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)

target_link_libraries(MyTest PUBLIC MyLib)

Though this configures cmake without warnings/error, running the make fails, indicating that the executable project is unable to find the header file(s) from library.

/.../nettu2/test/main.cpp:6:10: fatal error: src1.hpp: No such file or directory #include "src1.hpp" ^~~~~~~~~~~~~~~~ compilation terminated. test/CMakeFiles/MyTest.dir/build.make:62: recipe for target 'test/CMakeFiles/MyTest.dir/main.cpp.o' failed make[2]: * [test/CMakeFiles/MyTest.dir/main.cpp.o] Error 1 CMakeFiles/Makefile2:126: recipe for target 'test/CMakeFiles/MyTest.dir/all' failed make[1]: * [test/CMakeFiles/MyTest.dir/all] Error 2 Makefile:129: recipe for target 'all' failed make: *** [all] Error 2

I am sure that I am missing some crucial but trivial thing here, but yet unable to figure out, what is going wrong here. How can I get this build working?

1

1 Answers

1
votes

You have a minor mistake in this line:

target_include_directories(MyLib 
  INTERFACE ${CMAKE_CURRENT_BINARY_DIR})

The include directory you specify for MyLib expands to the build directory corresponding to srcs, i.e. it results in an invocation like

clang++ /path/to/build/test/test.cpp -I /path/to/build/srcs ...

but you want to pass the actual source directory to the preprocessor. To fix this, try

target_include_directories(MyLib 
   INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})