numsim-core::numsim-core installs without an include directory, so a consumer of the installed package can find it but cannot compile against it.
Symptom
Installing numsim-core and building anything that includes its headers:
fatal error: numsim-core/property_graph/property_traits.h: No such file or directory
The generated numsim-coreTargets.cmake carries no include path at all:
set_target_properties(numsim-core::numsim-core PROPERTIES
INTERFACE_COMPILE_FEATURES "cxx_std_23"
)
The headers are installed — <prefix>/include/numsim-core/... is fully populated. Only the exported target's INTERFACE_INCLUDE_DIRECTORIES is missing, so nothing tells a consumer where they are.
Cause
CMakeLists.txt uses CMAKE_INSTALL_INCLUDEDIR at line 63:
target_include_directories(${PROJECT_NAME}
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
but include(GNUInstallDirs) — which is what defines that variable — is at line 81, eighteen lines later.
${...} is expanded when the line is read, not when the generator expression is evaluated. At line 63 the variable is still empty, so the expression becomes $<INSTALL_INTERFACE:> and contributes nothing. The install(FILES ... DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/...) call at line 93 is after the include, which is why the headers land correctly and only the export is wrong.
Nothing warns: an empty INSTALL_INTERFACE is legal.
Fix
Move include(GNUInstallDirs) above the target_include_directories() call. Verified on a standalone checkout — same source, only the include hoisted:
set_target_properties(numsim-core::numsim-core PROPERTIES
INTERFACE_COMPILE_FEATURES "cxx_std_23"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
How it surfaced
Found while making the installed numsim-materials package consumable. That package had its own, separate defect — its generated Config re-found none of its dependencies, so find_package() failed outright with numsim-core::numsim-core missing. With that fixed (NumSim-Stack/numsim-materials#10), a consumer configures successfully and then fails to compile, because the numsim-core target it now resolves carries no header path.
So the two are independent: fixing one exposed the other. This is the remaining blocker to consuming an installed numsim-materials.
Worth checking alongside
Neither project's CI runs install or builds a consumer against the result, which is why both defects sat unnoticed while every in-tree build stayed green — in-tree builds use BUILD_INTERFACE, which was always correct. A CI step that installs and compiles a three-line consumer would have caught both.
numsim-core::numsim-coreinstalls without an include directory, so a consumer of the installed package can find it but cannot compile against it.Symptom
Installing numsim-core and building anything that includes its headers:
The generated
numsim-coreTargets.cmakecarries no include path at all:The headers are installed —
<prefix>/include/numsim-core/...is fully populated. Only the exported target'sINTERFACE_INCLUDE_DIRECTORIESis missing, so nothing tells a consumer where they are.Cause
CMakeLists.txtusesCMAKE_INSTALL_INCLUDEDIRat line 63:but
include(GNUInstallDirs)— which is what defines that variable — is at line 81, eighteen lines later.${...}is expanded when the line is read, not when the generator expression is evaluated. At line 63 the variable is still empty, so the expression becomes$<INSTALL_INTERFACE:>and contributes nothing. Theinstall(FILES ... DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/...)call at line 93 is after the include, which is why the headers land correctly and only the export is wrong.Nothing warns: an empty
INSTALL_INTERFACEis legal.Fix
Move
include(GNUInstallDirs)above thetarget_include_directories()call. Verified on a standalone checkout — same source, only the include hoisted:How it surfaced
Found while making the installed numsim-materials package consumable. That package had its own, separate defect — its generated Config re-found none of its dependencies, so
find_package()failed outright withnumsim-core::numsim-coremissing. With that fixed (NumSim-Stack/numsim-materials#10), a consumer configures successfully and then fails to compile, because the numsim-core target it now resolves carries no header path.So the two are independent: fixing one exposed the other. This is the remaining blocker to consuming an installed numsim-materials.
Worth checking alongside
Neither project's CI runs
installor builds a consumer against the result, which is why both defects sat unnoticed while every in-tree build stayed green — in-tree builds useBUILD_INTERFACE, which was always correct. A CI step that installs and compiles a three-line consumer would have caught both.