I have the main CMake file for my project that looks like this:
cmake_minimum_required(VERSION 3.19...3.25 FATAL_ERROR)
project(
Turingforge
VERSION 0.1.0
LANGUAGES CXX C
)
#add_compile_options(-Wundef -Wcast-align -Wchar-subscripts -Wnon-virtual-dtor -Wunused-local-typedefs -Wpointer-arith
# -Wwrite-strings -Wformat-security -Wlogical-op -Wenum-conversion -Wdouble-promotion -Wconversion -Wshadow
# -Wno-psabi -Wno-variadic-macros -Wno-long-long -fno-check-new -fno-common -fstrict-aliasing)
#Make sure that custom modules are found
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake)
# Only do these if this is the main project, and not if it is included through add_subdirectory
if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# Ensure -std=c++xx instead of -std=g++xx
set(CMAKE_CXX_EXTENSIONS OFF)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Testing only available if this is the main app
# Note this needs to be done in the main CMakeLists
# since it calls enable_testing, which must be in the
# main CMakeLists.
include(CTest)
# Docs only available if this is the main app
find_package(Doxygen)
if(Doxygen_FOUND)
add_subdirectory(docs)
else()
message(STATUS "Doxygen not found, not building docs")
endif()
endif()
##############################################
# Add subdirectories
add_subdirectory(src)
# The executable code is here
#add_subdirectory(apps)
set(BUILD_TESTING ON)
# Testing only available if this is the main app
# Emergency override TURINGFORGE_CMAKE_BUILD_TESTING provided as well
if ((PROJECT_IS_TOP_LEVEL OR TURINGFORGE_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()
Inside src/
I have another CMake file that builds my library:
##############################################
# Find/Install system dependencies
include(FetchContent)
include(ExternalProject)
# Formatting library
FetchContent_Declare(
fmtlib
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.1.1)
set(FMT_INSTALL ON)
# Adds fmt::fmt
FetchContent_MakeAvailable(fmtlib)
# Eigen
FetchContent_Declare(
Eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
set(EIGEN_BUILD_DOC OFF)
set(BUILD_TESTING OFF)
set(EIGEN_BUILD_PKGCONFIG OFF)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
FetchContent_MakeAvailable(Eigen)
find_package (Eigen3 3.4 REQUIRED NO_MODULE)
# Fast float
FetchContent_Declare(
fast_float
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
GIT_TAG tags/v6.0.0
GIT_SHALLOW TRUE)
set(FASTFLOAT_INSTALL OFF)
# Adds fast_float
FetchContent_MakeAvailable(fast_float)
# Fast unordered map and set
FetchContent_Declare(
unordered_dense
GIT_REPOSITORY https://github.com/martinus/unordered_dense.git
GIT_TAG tags/v4.3.1
GIT_SHALLOW TRUE)
# Adds unordered_dense::unordered_dense
FetchContent_MakeAvailable(unordered_dense)
# SIMD vector operations
FetchContent_Declare(
vectorclass
GIT_REPOSITORY https://github.com/vectorclass/version2.git
GIT_TAG tags/v2.02.01
GIT_SHALLOW 1)
FetchContent_MakeAvailable(vectorclass)
# Fast hash Functions
FetchContent_Declare(
xxhash
GIT_REPOSITORY https://github.com/Cyan4973/xxHash.git
GIT_TAG tags/v0.8.2
GIT_SHALLOW TRUE)
set(XXHASH_BUNDLED_MODE ON)
set(XXH_INLINE_ALL ON)
# Adds xxhash
FetchContent_MakeAvailable(xxHash)
file(GLOB XXHASH_SOURCES ${xxhash_SOURCE_DIR}/*.c)
list(REMOVE_ITEM XXHASH_SOURCES ${xxhash_SOURCE_DIR}/xxhsum.c)
list(REMOVE_ITEM XXHASH_SOURCES ${xxhash_SOURCE_DIR}/xxh_x86dispatch.c)
add_library(xxhash STATIC ${XXHASH_SOURCES})
target_include_directories(xxhash PUBLIC ${xxhash_SOURCE_DIR})
##############################################
# Create target and set properties
file(GLOB_RECURSE HEADER_LIST CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/include/turing_forge/*/*.hpp"
"${PROJECT_SOURCE_DIR}/include/vstat/*.hpp"
"${PROJECT_SOURCE_DIR}/include/csv/*.hpp"
)
file(GLOB_RECURSE SRC_LIST CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/src/*/*.cpp"
)
add_library(turingforge
${SRC_LIST}
${HEADER_LIST}
)
#Add an alias so that library can be used inside the build tree, e.g. when testing
add_library(Turingforge::turingforge ALIAS turingforge)
#Set target properties
target_include_directories(turingforge
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
${PROJECT_SOURCE_DIR}/include
PRIVATE
${vectorclass_SOURCE_DIR}
)
target_compile_features(turingforge PRIVATE cxx_auto_type)
target_compile_options(turingforge PRIVATE
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Wall -Wextra -pedantic -Werror>)
target_link_libraries(turingforge
PUBLIC
fmt::fmt Eigen3::Eigen unordered_dense::unordered_dense
PRIVATE
xxhash vectorclass fast_float
)
##############################################
# Installation instructions
# TODO: fix libraries not being in any export set
option(TURINGFORGE_INSTALL "Enable install" OFF)
set(TURINGFORGE_INSTALL OFF)
if (TURINGFORGE_INSTALL)
include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Turingforge)
install(TARGETS turingforge
EXPORT turingforge-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# This is required so that the exported target has the name Turingforge and not turingforge
set_target_properties(turingforge PROPERTIES EXPORT_NAME Turingforge)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Export the targets to a script
install(EXPORT turingforge-targets
FILE
TuringforgeTargets.cmake
NAMESPACE
Turingforge::
DESTINATION
${INSTALL_CONFIGDIR}
)
# Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/TuringforgeConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/../cmake/TuringforgeConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/TuringforgeConfig.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
# Install the config, configversion and custom find modules if any
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/TuringforgeConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/TuringforgeConfigVersion.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)
##############################################
## Exporting from the build tree
#configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/SOMECUSTOM.cmake
# ${CMAKE_CURRENT_BINARY_DIR}/SOMECUSTOM.cmake
# COPYONLY)
export(EXPORT turingforge-targets
FILE ${CMAKE_CURRENT_BINARY_DIR}/TuringforgeTargets.cmake
NAMESPACE Turingforge::)
# Register package in the User Package Registry
export(PACKAGE Turingforge)
# Make sure IDEs put the headers in a nice place
source_group(
TREE "${PROJECT_SOURCE_DIR}/include"
PREFIX "Header Files"
FILES ${HEADER_LIST}
)
endif()
and finally I try to run tests built by this CMake file inside tests/
:
# Testing library
FetchContent_Declare(
catch
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.5.0)
# Adds Catch2::Catch2
FetchContent_MakeAvailable(catch)
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
set(TEST_SOURCES
test_evaluation.cpp
test_expression.cpp
)
string(REPLACE ".cpp" "" BASENAMES "${TEST_SOURCES}")
set(TARGETS ${BASENAMES})
foreach(name ${TARGETS})
add_executable(${name} ${name}.cpp)
target_link_libraries(${name} turingforge Catch2::Catch2WithMain)
target_compile_features(${name} PRIVATE cxx_std_20)
endforeach()
include(ParseAndAddCatchTests)
ParseAndAddCatchTests(${TARGETS})
When I try to run a test I get:
FAILED: tests/test_expression
: && /usr/bin/c++ -g tests/CMakeFiles/test_expression.dir/test_expression.cpp.o -o tests/test_expression src/libturingforge.a _deps/catch-build/src/libCatch2Maind.a _deps/fmtlib-build/libfmtd.a -lvectorclass src/libxxhash.a _deps/catch-build/src/libCatch2d.a && :
/usr/bin/ld: cannot find -lvectorclass: No such file or directory
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
I think I am not building vectorclass
correctly and as such it is not found here. I’m not sure though and I was wondering if someone can identify the reason behind the error.
Additionally, if I set TURINGFORGE_INSTALL
I get the following errors:
CMake Error in src/CMakeLists.txt:
Target "turingforge" INTERFACE_INCLUDE_DIRECTORIES property contains path:
"/home/user/Downloads/research/SymbolicRegression/deletmeee/include"
which is prefixed in the source directory.
CMake Error: install(EXPORT "turingforge-targets" ...) includes target "turingforge" which requires target "unordered_dense" that is not in any export set.
CMake Error: install(EXPORT "turingforge-targets" ...) includes target "turingforge" which requires target "xxhash" that is not in any export set.
CMake Error: install(EXPORT "turingforge-targets" ...) includes target "turingforge" which requires target "fast_float" that is not in any export set.
CMake Error in src/CMakeLists.txt:
export called with target "turingforge" which requires target
"unordered_dense" that is not in any export set.
CMake Error in src/CMakeLists.txt:
export called with target "turingforge" which requires target "xxhash" that
is not in any export set.
CMake Error in src/CMakeLists.txt:
export called with target "turingforge" which requires target "fast_float"
that is not in any export set.
How can I include the needed targets on the export set?