How can CMake FetchContent be used to import libraries that work with find_package?

Viewed 1823

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.

0 Answers
Related