I was reading through the CMake Importing and Exporting Guide and wanted to adapt one of the examples to make use of FetchContent instead of find_package. But I receive errors related to target not being found and headers not being found.
I have two directories; one called MathFunctions and another called Downstream. MathFunctions exports targets for Downstream to use. The directories for each are as follows:
MathFunctions Downstream
∟ CMakeLists.txt ∟ CMakeLists.txt
∟ Config.cmake.in ∟ main.cc
∟ MathFunctions.cxx
∟ MathFunctions.h
The following are the CMakeLists.txt files in the respective directories.
# MathFunctions/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MathFunctions)
# make cache variables for install destinations
include(GNUInstallDirs)
# create library
add_library(MathFunctions STATIC MathFunctions.cxx)
add_library(MathFunctions::MathFunctions ALIAS MathFunctions)
target_compile_features(MathFunctions PRIVATE cxx_std_17)
# add include directories
target_include_directories(MathFunctions
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
# install the target and create export-set
install(TARGETS MathFunctions
EXPORT MathFunctionsTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# install header file
install(FILES MathFunctions.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# generate and install export file
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
NAMESPACE MathFunctions::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions
)
# include CMakePackageConfigHelpers macro
include(CMakePackageConfigHelpers)
# set version
set(version 3.4.1)
set_property(TARGET MathFunctions PROPERTY VERSION ${version})
set_property(TARGET MathFunctions PROPERTY SOVERSION 3)
set_property(TARGET MathFunctions PROPERTY
INTERFACE_MathFunctions_MAJOR_VERSION 3)
set_property(TARGET MathFunctions APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING MathFunctions_MAJOR_VERSION
)
# generate the version file for the config file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
VERSION "${version}"
COMPATIBILITY AnyNewerVersion
)
# create config file
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions
)
# install config files
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions
)
# generate the export targets for the build tree
export(EXPORT MathFunctionsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/MathFunctionsTargets.cmake"
NAMESPACE MathFunctions::
)
# Downstream/CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(Downstream)
# find MathFunctions
include(FetchContent)
FetchContent_Declare(
MathFunctions
GIT_REPOSITORY "/path_to_dir/MathFunctions"
GIT_TAG master
)
FetchContent_MakeAvailable(MathFunctions)
# create executable
add_executable(myexe main.cc)
target_compile_features(myexe PRIVATE cxx_std_17)
target_link_libraries(myexe PRIVATE MathFunctions::MathFunctions)
When I run cmake -S . -B ./build in the Downstream directory, I receive the following error:
-- Configuring done
CMake Error at CMakeLists.txt:15 (add_executable):
Target "myexe" links to target "MathFunctions::MathFunctions" but the
target was not found. Perhaps a find_package() call is missing for an
IMPORTED target, or an ALIAS target is missing?
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
What is the right way to do this?
EDIT (28/4/2021):
It seems to work fine when I remove the namespace in the call to target_link_libraries to target_link_libraries(myexe PRIVATE MathFunctions) and also add target_include_directories(myexe PUBLIC ${MathFunctions_SOURCE_DIR}) right after. However, this is still not what I want since I'd like the exported target to be namespace and also avoid the call to target_include_directories.