From ef6d2ac69d48965759ab6635343afbf94e3613d8 Mon Sep 17 00:00:00 2001 From: petlenz Date: Sun, 23 Aug 2026 00:58:19 +0200 Subject: [PATCH 1/2] cmake: make the installed package consumable Two defects, both invisible to every in-tree build because those use BUILD_INTERFACE, which was always correct. 1. include(GNUInstallDirs) sat 18 lines AFTER the $ that depends on it. ${} expands when the line is read, so the variable was empty and the generator expression collapsed to $. The exported target carried no include directory at all: consumers could find the package and not compile against it. An empty INSTALL_INTERFACE is legal, so nothing warned. The install(FILES ... DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/...) call is after the include, which is why the headers landed correctly and only the export was wrong. 2. install(FILES) flattened the tree: include/numsim-core/property_graph/*.h was installed beside the top-level headers, so #include could not resolve. It also only installed the files listed in ${PROJECT_NAME}_HEADER -- 13 of the 23 headers present. install(DIRECTORY ... FILES_MATCHING PATTERN "*.h") installs all 23 and preserves the structure. Verified end to end: an external project that calls find_package(numsim-core) and includes a property_graph header now configures, compiles and runs. Before, it failed at configure on the missing include directory and then, past that, on the missing subdirectory. Fixes #18. --- CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6443366..55b23ca 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,14 @@ set(${PROJECT_NAME}_HEADER add_library(${PROJECT_NAME} INTERFACE) add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) +# GNUInstallDirs BEFORE the target_include_directories() below, not after it. +# CMAKE_INSTALL_INCLUDEDIR is expanded when the line is read, so with the +# include further down the INSTALL_INTERFACE expanded EMPTY and the exported +# target carried no include directory at all -- consumers of the installed +# package could find it and not compile against it. An empty INSTALL_INTERFACE +# is legal, so nothing warned. +include(GNUInstallDirs) + # Headers are reachable from the build tree and from the install tree. target_include_directories(${PROJECT_NAME} INTERFACE @@ -78,7 +86,6 @@ option(DOWNLOAD_GTEST "Download and build GTest" OFF) option(DOWNLOAD_GBENCHMARK "Download and build Google Benchmark" OFF) # Installation logic -include(GNUInstallDirs) if(${PROJECT_NAME}_INSTALL_LIBRARY) install( TARGETS ${PROJECT_NAME} @@ -89,8 +96,14 @@ if(${PROJECT_NAME}_INSTALL_LIBRARY) ) # Install header files - install(FILES ${${PROJECT_NAME}_HEADER} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + # install(DIRECTORY), not install(FILES): FILES flattens everything into + # one directory, so include/numsim-core/property_graph/*.h landed beside + # the top-level headers and #include + # could not resolve. It also only installed the files listed in + # ${PROJECT_NAME}_HEADER -- 13 of the 23 headers in the tree. + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h") # Create and install package config files include(CMakePackageConfigHelpers) From b75a462ef9a11f92e2db0af7bc8bb803e60e62f9 Mon Sep 17 00:00:00 2001 From: petlenz Date: Sun, 23 Aug 2026 09:19:36 +0200 Subject: [PATCH 2/2] cmake: drop the now-dead header list install(DIRECTORY) replaced the only use of ${PROJECT_NAME}_HEADER, leaving it set and referenced nowhere. Removing it is the point of the change: a hand-maintained list of headers that must be edited whenever a file is added is exactly what silently installed 13 of 23. --- CMakeLists.txt | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55b23ca..9d91bf0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,21 +27,6 @@ set(${PROJECT_NAME}_VERSION ${project_version}) message(STATUS "Building v${${PROJECT_NAME}_VERSION}") # Header files -set(${PROJECT_NAME}_HEADER - ${${PROJECT_NAME}_INCLUDE_DIR}/factory_base_bones.h - ${${PROJECT_NAME}_INCLUDE_DIR}/registry_bones.h - ${${PROJECT_NAME}_INCLUDE_DIR}/warehouse_bones.h - ${${PROJECT_NAME}_INCLUDE_DIR}/input_parameter_controller.h - ${${PROJECT_NAME}_INCLUDE_DIR}/input_parser.h - ${${PROJECT_NAME}_INCLUDE_DIR}/static_indexing.h - ${${PROJECT_NAME}_INCLUDE_DIR}/numsim_core_utility.h - ${${PROJECT_NAME}_INCLUDE_DIR}/query_map.h - ${${PROJECT_NAME}_INCLUDE_DIR}/parameter_handler.h - ${${PROJECT_NAME}_INCLUDE_DIR}/any_printer.h - ${${PROJECT_NAME}_INCLUDE_DIR}/wrapper.h - ${${PROJECT_NAME}_INCLUDE_DIR}/input_parameter_enum_utils.h - ${${PROJECT_NAME}_INCLUDE_DIR}/function_registry.h -) # numsim-core is header-only: no sources, no compiled artefacts, just an # INTERFACE target carrying include paths + a C++23 feature requirement @@ -100,7 +85,7 @@ if(${PROJECT_NAME}_INSTALL_LIBRARY) # one directory, so include/numsim-core/property_graph/*.h landed beside # the top-level headers and #include # could not resolve. It also only installed the files listed in - # ${PROJECT_NAME}_HEADER -- 13 of the 23 headers in the tree. + # a hand-maintained list -- 13 of the 23 headers in the tree. install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h")