'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 |
