I'm trying to use CMake v3.30.5 to create a C++ project building with VS2022. I would like to include 3rd party code via FetchContent so I do not need to add them to my source tree. The code will be placed in a directory called SDKs
in the project root and consumed by a project Core
also placed in the root. For the first one, I want to add FastDelegate (https://github.com/dreamcat4/FastDelegate) as a header-only library, so I've declared it INTERFACE since it doesn't compile any sources.
My root CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.24)
project(MyProj
LANGUAGES CXX
VERSION 0.0.1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
set(SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/SDKs")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
add_subdirectory(SDKs)
add_subdirectory(Core)
The SDKs CMakeLists.txt successfully grabs the source, places it in the SDKs/FastDelegate folder, and runs find_package
as I expect:
include (FetchContent)
FetchContent_Declare(FastDelegate
GIT_REPOSITORY https://github.com/dreamcat4/FastDelegate.git
GIT_PROGRESS true
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/FastDelegate"
BINARY_DIR "${CMAKE_BINARY_DIR}/SDKs/FastDelegate"
FIND_PACKAGE_ARGS)
FetchContent_MakeAvailable(FastDelegate)
The FindFastDelegate.cmake for find_package
creates an INTERFACE library with the headers and sets the include directory:
cmake_minimum_required(VERSION 3.24)
set(SRC_DIR "${SDK_DIR}/FastDelegate")
add_library(FastDelegate INTERFACE
"${SRC_DIR}/FastDelegate.h"
"${SRC_DIR}/FastDelegateBind.h")
add_library(SDK::FastDelegate ALIAS FastDelegate)
target_include_directories(FastDelegate INTERFACE ${SRC_DIR})
set_target_properties(FastDelegate PROPERTIES FOLDER "SDKs/FastDelegate")
and my Core CMakeLists.txt links to the FastDelegate INTERFACE library:
cmake_minimum_required(VERSION 3.24)
add_library(Core STATIC
Core_defines.h)
set_target_properties(Core PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(Core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(Core
PUBLIC
SDK::FastDelegate)
# added this to make sure include directories are correct
file(GENERATE OUTPUT "$<CONFIG>output.txt"
CONTENT "$<TARGET_PROPERTY:Core,INCLUDE_DIRECTORIES>")
The test output does indeed show that the include directories for the Core
library are
C:/Projects/MyProj/Core;C:/Projects/MyProj/SDKs/FastDelegate
as I would expect. However, the MSVC project does not list either of those in the include directories and I cannot #include
the FastDelegate files.
Have I missed something or done something wrong, or is there an issue with CMake?
Thanks to @ixSci for asking the good question that lead me on the path:
My Core
library that was linking to the INTERFACE library did not have any source files in it, only other headers, so there was no compilation output. This causes either CMake or VS (not sure which) to not bring in the additional include directories. Once I added an empty TestSource.cpp into Core and ran CMake again, the include directories appear in the project properties as I expect and I can #include the headers in my files.