Skip to content

Commit 7ee9633

Browse files
authored
build(install): adopt Tiered Install Degradation pattern (#553)
Replace the blanket CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR guard with IMPORTED property detection on each PUBLIC dependency target. Tiered behavior: - Tier 1 (ALWAYS): Header installs (database/ and include/ directories) - Tier 2+3 (conditional): Target install with EXPORT, install(EXPORT), and export(EXPORT) — only when all deps are IMPORTED - Tier 2 fallback: Target install without EXPORT when deps are non-IMPORTED, with diagnostic message naming the specific deps - Tier 4 (ALWAYS): Config + version file generation and install Also add EXISTS guard around targets include in the config template so config files work even when install(EXPORT) was skipped. Closes #552
1 parent c53f553 commit 7ee9633

2 files changed

Lines changed: 99 additions & 31 deletions

File tree

CMakeLists.txt

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -354,46 +354,118 @@ endif()
354354
##################################################
355355
# Installation Rules
356356
#
357-
# Only generate install/export rules when database_system is the top-level
358-
# project. In subdirectory builds (e.g., via pacs_system), transitive
359-
# dependencies (thread_base, simdutf, etc.) may not be in any export set,
360-
# which causes CMake generation errors.
357+
# Uses Tiered Install Degradation: headers and config files are always
358+
# installed, but install(EXPORT) / export(EXPORT) are conditional on all
359+
# PUBLIC dependencies being IMPORTED targets (i.e., already in an export
360+
# set). This allows subdirectory builds to get headers + library + config
361+
# while avoiding CMake generation errors from non-IMPORTED transitive deps.
361362
##################################################
362363

363364
include(GNUInstallDirs)
364365

365-
if(BUILD_DATABASE AND CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
366-
# Install header files
366+
if(BUILD_DATABASE)
367+
# --- Determine export capability via IMPORTED property detection ------
368+
set(_DB_CAN_EXPORT TRUE)
369+
set(_DB_NON_IMPORTED_DEPS "")
370+
371+
# Check common_system (required dependency)
372+
foreach(_target common_system::common_system common_system)
373+
if(TARGET ${_target})
374+
get_target_property(_imp ${_target} IMPORTED)
375+
if(NOT _imp)
376+
set(_DB_CAN_EXPORT FALSE)
377+
list(APPEND _DB_NON_IMPORTED_DEPS "${_target}")
378+
endif()
379+
break()
380+
endif()
381+
endforeach()
382+
383+
# Check thread_system (optional ecosystem dependency)
384+
foreach(_target thread_system::thread_system thread_system)
385+
if(TARGET ${_target})
386+
get_target_property(_imp ${_target} IMPORTED)
387+
if(NOT _imp)
388+
set(_DB_CAN_EXPORT FALSE)
389+
list(APPEND _DB_NON_IMPORTED_DEPS "${_target}")
390+
endif()
391+
break()
392+
endif()
393+
endforeach()
394+
395+
# Check monitoring_system (optional ecosystem dependency)
396+
foreach(_target monitoring_system::monitoring_system monitoring_system)
397+
if(TARGET ${_target})
398+
get_target_property(_imp ${_target} IMPORTED)
399+
if(NOT _imp)
400+
set(_DB_CAN_EXPORT FALSE)
401+
list(APPEND _DB_NON_IMPORTED_DEPS "${_target}")
402+
endif()
403+
break()
404+
endif()
405+
endforeach()
406+
407+
# Check container_system (optional ecosystem dependency)
408+
foreach(_target container_system::container_system container_system)
409+
if(TARGET ${_target})
410+
get_target_property(_imp ${_target} IMPORTED)
411+
if(NOT _imp)
412+
set(_DB_CAN_EXPORT FALSE)
413+
list(APPEND _DB_NON_IMPORTED_DEPS "${_target}")
414+
endif()
415+
break()
416+
endif()
417+
endforeach()
418+
419+
list(REMOVE_DUPLICATES _DB_NON_IMPORTED_DEPS)
420+
421+
# --- Tier 1: Headers (ALWAYS) ----------------------------------------
367422
install(DIRECTORY database/
368423
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/database_system/database
369424
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
370425
PATTERN "tests" EXCLUDE
371426
PATTERN "samples" EXCLUDE
372427
)
373428

374-
# Install kcenon-namespaced facade headers
375429
install(DIRECTORY include/
376430
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
377431
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
378432
)
379433

380-
# Install library target with export set
381-
install(TARGETS database
382-
EXPORT database_system-targets
383-
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
384-
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
385-
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
386-
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/database_system
387-
)
388-
389-
# Install export set with database_system:: namespace
390-
install(EXPORT database_system-targets
391-
FILE database_system-targets.cmake
392-
NAMESPACE database_system::
393-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/database_system
394-
)
434+
# --- Tier 2+3: Targets + conditional export --------------------------
435+
if(_DB_CAN_EXPORT)
436+
# Tier 2: Install library target with export set
437+
install(TARGETS database
438+
EXPORT database_system-targets
439+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
440+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
441+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
442+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/database_system
443+
)
444+
445+
# Tier 3: Install + build-tree export sets
446+
install(EXPORT database_system-targets
447+
FILE database_system-targets.cmake
448+
NAMESPACE database_system::
449+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/database_system
450+
)
451+
452+
export(EXPORT database_system-targets
453+
FILE "${CMAKE_CURRENT_BINARY_DIR}/database_system-targets.cmake"
454+
NAMESPACE database_system::
455+
)
456+
else()
457+
# Tier 2 only: Install library without EXPORT (no export set)
458+
install(TARGETS database
459+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
460+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
461+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
462+
)
463+
464+
message(STATUS "database_system: install(EXPORT) skipped — non-IMPORTED deps: "
465+
"${_DB_NON_IMPORTED_DEPS}. Headers and library are installed.")
466+
endif()
395467

396-
# Generate and install package config files
468+
# --- Tier 4: Config + version files (ALWAYS) -------------------------
397469
include(CMakePackageConfigHelpers)
398470

399471
configure_package_config_file(
@@ -414,12 +486,6 @@ if(BUILD_DATABASE AND CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
414486
"${CMAKE_CURRENT_BINARY_DIR}/database_system-config-version.cmake"
415487
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/database_system
416488
)
417-
418-
# Build-tree export for FetchContent/add_subdirectory users
419-
export(EXPORT database_system-targets
420-
FILE "${CMAKE_CURRENT_BINARY_DIR}/database_system-targets.cmake"
421-
NAMESPACE database_system::
422-
)
423489
endif()
424490

425491
##################################################

cmake/database_system-config.cmake.in

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ if(@USE_CONTAINER_SYSTEM@)
3939
find_dependency(container_system CONFIG REQUIRED)
4040
endif()
4141

42-
# Include targets
43-
include("${CMAKE_CURRENT_LIST_DIR}/database_system-targets.cmake")
42+
# Include targets (may not exist if install(EXPORT) was skipped in subdirectory builds)
43+
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/database_system-targets.cmake")
44+
include("${CMAKE_CURRENT_LIST_DIR}/database_system-targets.cmake")
45+
endif()
4446

4547
# Verify targets exist
4648
check_required_components(database_system)

0 commit comments

Comments
 (0)