Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include headers with a library in CMake

Tags:

c++

cmake

My project has two utility library in it. I am looking for the best way to write CMake configurations for the libraries.

/my_project
 --> CMakeLists.txt
 --> main.cpp
 --> /utils
      --> CMakeLists.txt
      --> common.h
      --> /base_c
           --> CMakeLists.txt
           --> base_c.c
           --> base_c.h
      --> /base_cpp
           --> CMakeLists.txt
           --> base_cpp.cpp
           --> base_cpp.hpp

My current CMake files:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8)
project(my_project)

add_subdirectory(utils)

add_executable(main main.c)
target_link_libraries(main utils base_c base_cpp)

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c)
add_subdirectory(base_cpp)

add_library(utils)
target_sources(utils PUBLIC common.h)

/my_project/utils/base_c/CMakeLists.txt

add_library(base_c base_c.c)
target_sources(base_c PUBLIC base_c.h)

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp)
target_sources(base_cpp PUBLIC base_cpp.hpp)

find_library(BASEC base_c ../base_c)
target_link_libraries(base_cpp BASEC)

The problem is that base_cpp does not find includes from base_c. How should I fix the configuration?

I managed to make it work with target_include_directories(base_cpp PRIVATE ../base_c), but that's ugly and shouldn't be necessary, according to INTERFACE_INCLUDE_DIRECTORIES documentation.

like image 285
voddan Avatar asked Jun 19 '26 10:06

voddan


1 Answers

As @Anedar mentioned, to resolve this situation one needs target_include_directories with PUBLIC or INTERFACE options in the library CMakeLists.txt. That populates INTERFACE_INCLUDE_DIRECTORIES of the library target, which is used by target_link_libraries on the consuming side.

My working configuration:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8)
project(my_project)

add_subdirectory(utils)

add_executable(main main.c)
target_link_libraries(main utils base_c base_cpp)

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c)
add_subdirectory(base_cpp)

add_library(utils)
target_sources(utils PUBLIC common.h)
target_include_directories(utils INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

/my_project/utils/base_c/CMakeLists.txt

add_library(base_c base_c.c)
target_sources(base_c PUBLIC base_c.h)
target_include_directories(base_c INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp)
target_sources(base_cpp PUBLIC base_cpp.hpp)
target_include_directories(base_cpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries(base_cpp base_c)
like image 186
voddan Avatar answered Jun 21 '26 22:06

voddan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!