'How to make my project find header file from my own separate library imported with FetchContent?

I'm trying to use my own library in a different project using CMake and FetchContent. My library is a static one that's built with CMake in a separate git repo, and it works fine when built with a demo in the same repo. When I use FetchContent to use it in a separate project it can't find the header files and I don't know how to include them.

dynamic-shadow-lib tree:

.
├── CMakeLists.txt
├── demo
│   ├── CMakeLists.txt
│   └── main.cpp
├── include
│   ├── line2D.hpp
│   ├── math.hpp
│   ├── mathplotUtil.hpp
│   ├── shape2D.hpp
│   ├── square2D.hpp
│   ├── triangle2D.hpp
│   └── vec2f.hpp
├── LICENSE
├── README.md
├── src
│   ├── line2D.cpp
│   ├── math.cpp
│   ├── square2D.cpp
│   ├── triangle2D.cpp
│   └── vec2f.cpp
└── tests
    ├── CMakeLists.txt
    ├── unit_tests
    │   ├── CMakeLists.txt
    │   ├── line2DTests.cpp
    │   ├── main.cpp
    │   ├── mathTests.cpp
    │   ├── square2DTests.cpp
    │   └── vec2fTests.cpp
    └── visual_tests
        ├── CMakeLists.txt
        ├── main.cpp
        └── visualTests.hpp

dynamic-shadow-lib root CmakeLists.txt:

cmake_minimum_required(VERSION 3.16)

project(
    dynamic-shadows
    VERSION 1.0
    LANGUAGES CXX
)

# Build config variables
set(BUILD_DEMO FALSE)
set(BUILD_TESTS FALSE)

# Set C++ to version 14
set(CMAKE_CXX_STANDARD 14)

# Set binary destinations
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# Set header dir
set(HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${HEADERS_DIR})

# Set source dir
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)

# Set a name for the target
set(TARGET_LIB ${CMAKE_PROJECT_NAME}-lib)

# Make library ${TARGET_LIB}
add_library(
    ${TARGET_LIB} STATIC
    ${SOURCE_DIR}/math.cpp
    ${SOURCE_DIR}/vec2f.cpp
    ${SOURCE_DIR}/line2D.cpp
    ${SOURCE_DIR}/square2D.cpp
    ${SOURCE_DIR}/triangle2D.cpp
)

if (${BUILD_TESTS})
    # Enable testing (GoogleTests)
    include(CTest)
    enable_testing()
    add_subdirectory(tests)
endif()

if (${BUILD_DEMO})
    # Demo
    add_subdirectory(demo)
endif()

Project that I'm trying to include my lib in (tree):

.
├── CMakeLists.txt
├── include
│   ├── Game.hpp
│   └── Primitive.hpp
├── LICENSE
├── README.md
├── src
│   ├── Game.cpp
│   └── main.cpp
└── tests
    ├── CMakeLists.txt
    └── main.cpp

Projects root CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(realtime-light-shadow-2D
  LANGUAGES CXX
  VERSION 1.0
)

# Set extra compiler flags
set(CMAKE_CXX_FLAGS "-W -Wall -std=c++14 -fopenmp")

# Set binary destinations
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# Dependencies
include(FetchContent)
set (FETCHCONTENT_QUIET FALSE)

# SFML
message (STATUS "Adding SFML..")
FetchContent_Declare(
  sfml
  GIT_REPOSITORY "https://github.com/SFML/SFML"
  GIT_TAG 218154cf0098de3f495e31ced489da24b7318638 # Latest
  GIT_PROGRESS TRUE
)

# No need to build audio and network modules
set(SFML_BUILD_AUDIO FALSE)
set(SFML_BUILD_NETWORK FALSE)

FetchContent_MakeAvailable(sfml)

# ImGui
message (STATUS "Adding ImGui")
FetchContent_Declare(
  imgui
  GIT_REPOSITORY https://github.com/ocornut/imgui
  GIT_TAG 5c8f8d031166765d2f1e2ac2de27df6d3691c05a # Latest
  GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(imgui)

# ImGui-SFML
message (STATUS "Adding ImGui-SFML")
FetchContent_Declare(
  imgui-sfml
  GIT_REPOSITORY https://github.com/eliasdaler/imgui-sfml
  GIT_TAG 4129d276d45845581b6ba99ede50db6f761e5089 # Latest
  GIT_PROGRESS TRUE
)
set(IMGUI_DIR ${imgui_SOURCE_DIR})
set(IMGUI_SFML_FIND_SFML OFF)
set(IMGUI_SFML_IMGUI_DEMO ON)

FetchContent_MakeAvailable(imgui-sfml)

# dynamic-shadows-lib
message( STATUS "Adding dynamic-shadow-lib")
FetchContent_Declare(
  dynamic-shadows-lib
  GIT_REPOSITORY https://github.com/JesperGlas/dynamic-shadows-lib/
  GIT_TAG 59c7884caac7cc98f902fd880ccb1c9b0f50cca0 # Latest
  GIT_PROGRESS TRUE
)

FetchContent_MakeAvailable(dynamic-shadows-lib)

# Set header dir
set(HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${HEADERS_DIR})

# Set source dir
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)

set(TARGET_BIN ${CMAKE_PROJECT_NAME})

add_executable(
  ${TARGET_BIN}
  ${SOURCE_DIR}/main.cpp
  ${SOURCE_DIR}/Game.cpp
)

target_link_libraries(
  ${TARGET_BIN}
  PUBLIC
    sfml-system
    sfml-graphics
    ImGui-SFML::ImGui-SFML
    dynamic-shadows-lib
)

When I try to build the project (sfml-dynamic-light-demo) I get the following error:

[build] /home/jesper/dev/cpp/sfml-dynamic-light-demo/include/Primitive.hpp:4:10: fatal error: vec2f.hpp: No such file or directory
[build]     4 | #include "vec2f.hpp"

Which tells me that the libraries include folder might not be available to the project. I've tried to include it as an install(DIRECTORY ${HEADER_DIR}) in the libs root CMakeLists, but it has no effect. I suspect I'm using it wrong since when I build the project I still get "No install step for 'dynamic-shadows-lib-populate'".

What am I doing wrong? If it's a concept that I'm missing, what should I read up on to make it work?



Solution 1:[1]

Thanks to the comments I was able to solve this. In my library (Built with CMake) I used the variable CMAKE_PROJECT_NAME when creating my library (CMAKE_PROJECT_NAME-lib). This variable references the top root CMakeLists.txt which resultet in my library getting the wrong name when I used it in another project. By changing all of those variables to PROJECT_NAME, and other similar ones, everything worked as it should.

TLDR: Make sure to use local variables when you want to use a CMake project as a subproject. (In this case PROJECT_NAME, instead of CMAKE_PROJECT_NAME etc...).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jesper