From c8f884e0d802b9456f960d0c11a249e142c6bbbd Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Tue, 26 May 2026 17:54:59 -0500 Subject: [PATCH 1/8] fix ROSS_BUILD_SHARED_LIBS behavior --- CLAUDE.md | 2 ++ CMakeLists.txt | 9 +++++++++ core/CMakeLists.txt | 5 +++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 700e8e26..a6e9b7ea 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,6 +16,8 @@ Models are **not** built by default — pass `-DROSS_BUILD_MODELS=ON` to include MPI is required and auto-discovered via `find_package(MPI)` — do not set `CC=mpicc` or `-DCMAKE_C_COMPILER=mpicc`. For non-standard installs, hint with `-DMPI_HOME=...` or `module load ` before configuring. The top-level `CMakeLists.txt` does per-arch detection via `CMAKE_SYSTEM_PROCESSOR` and falls back to a `gtod` clock if unrecognized. Set `-DROSS_CLOCK_OVERRIDE=YES` to force the gtod clock. +Default is a static library. Pass `-DROSS_BUILD_SHARED_LIBS=ON` to build shared. The option defaults from `BUILD_SHARED_LIBS` if a parent project set it (e.g., a superbuild), otherwise OFF. + ## Running a model Models accept `--synch=N` to pick the scheduler: diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c996f64..e827c10b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,15 @@ ENDIF(VALID_ARCH AND NOT ${ROSS_CLOCK_OVERRIDE}) # `module load ` before configuring. find_package(MPI REQUIRED COMPONENTS C) +# ROSS's own static/shared knob. Defaults from BUILD_SHARED_LIBS so a +# superbuild parent that sets the standard variable at the top gets ROSS +# to follow the convention; an explicit -DROSS_BUILD_SHARED_LIBS=... is +# the per-ROSS override. +option(ROSS_BUILD_SHARED_LIBS + "Build ROSS libraries as shared instead of static" + ${BUILD_SHARED_LIBS}) +set(BUILD_SHARED_LIBS ${ROSS_BUILD_SHARED_LIBS}) + # Code coverage instrumentation (GCC/Clang only). Applied at directory scope # so flags propagate to core/ and models/. Collect with lcov/gcovr after ctest. option(ROSS_ENABLE_COVERAGE "Enable code coverage instrumentation" OFF) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 5c74bc96..03d1edc6 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -117,10 +117,11 @@ ENDIF(CMAKE_BUILD_TYPE MATCHES Debug) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DROSS_OPTION_LIST='\"${OPTIONS}\"'") # Generate Library -OPTION(ROSS_BUILD_SHARED_LIBS "Build shared libraries instead of static" OFF) -SET(BUILD_SHARED_LIBS ${ROSS_BUILD_SHARED_LIBS}) +# Library type (static vs shared) is selected at top-level via +# ROSS_BUILD_SHARED_LIBS, which propagates here as BUILD_SHARED_LIBS. ADD_LIBRARY(ROSS ${ross_srcs}) SET_TARGET_PROPERTIES(ROSS PROPERTIES OUTPUT_NAME ROSS) + # MPI is PUBLIC because core/ross.h does `#include ` — consumers must # inherit the MPI include path and link against MPI when they link ROSS. target_link_libraries(ROSS PUBLIC MPI::MPI_C) From 56bd109913ec410881869922ae710ab78001e204 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Wed, 27 May 2026 15:22:52 -0500 Subject: [PATCH 2/8] CMake: modernize target hygiene - No nested project() call - use BUILD_INTERFACE and INSTALL_INTERFACE in target_include_directories call - Improve/simplify phold's cmake as well as drop BPGM since BG/Q doesn't exist anymore :) --- core/CMakeLists.txt | 26 +++++++++++------- models/phold/CMakeLists.txt | 53 +++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 03d1edc6..2cbf358f 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,6 +1,3 @@ -PROJECT(ROSS C) -INCLUDE_DIRECTORIES(${ROSS_SOURCE_DIR} ${ROSS_BINARY_DIR}) - SET(ross_srcs queue/tw-queue.h @@ -117,16 +114,27 @@ ENDIF(CMAKE_BUILD_TYPE MATCHES Debug) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DROSS_OPTION_LIST='\"${OPTIONS}\"'") # Generate Library -# Library type (static vs shared) is selected at top-level via # ROSS_BUILD_SHARED_LIBS, which propagates here as BUILD_SHARED_LIBS. -ADD_LIBRARY(ROSS ${ross_srcs}) -SET_TARGET_PROPERTIES(ROSS PROPERTIES OUTPUT_NAME ROSS) +add_library(ROSS ${ross_srcs}) +add_library(ROSS::ROSS ALIAS ROSS) # MPI is PUBLIC because core/ross.h does `#include ` — consumers must # inherit the MPI include path and link against MPI when they link ROSS. target_link_libraries(ROSS PUBLIC MPI::MPI_C) target_link_libraries(ROSS PRIVATE m) +# Public include dirs travel with the target: +# BUILD_INTERFACE — in-tree models find both +# the source dir (ross.h, ross-base.h, etc.) and the binary dir +# (generated config.h). +# INSTALL_INTERFACE — installed consumers find headers at /include/ross +target_include_directories(ROSS + PUBLIC + $ + $ + $ +) + # Build Specific Config Header CONFIGURE_FILE(config.h.in config.h) SET(ross_srcs ${ross_srcs} config.h) @@ -142,9 +150,9 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ross.pc PROPERTIES GENER # Make Install -INSTALL(FILES ${ROSS_BINARY_DIR}/config.h DESTINATION include) -INSTALL(DIRECTORY ${ROSS_SOURCE_DIR}/ DESTINATION include FILES_MATCHING PATTERN "*.h") +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include) +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include FILES_MATCHING PATTERN "*.h") INSTALL(TARGETS ROSS EXPORT ROSS-targets DESTINATION lib) INSTALL(EXPORT ROSS-targets DESTINATION lib) INSTALL(FILES ROSSConfig.cmake DESTINATION lib) -INSTALL(FILES ${ROSS_BINARY_DIR}/ross.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ross.pc DESTINATION lib/pkgconfig) diff --git a/models/phold/CMakeLists.txt b/models/phold/CMakeLists.txt index 7c9833e2..0acf3aec 100644 --- a/models/phold/CMakeLists.txt +++ b/models/phold/CMakeLists.txt @@ -1,33 +1,30 @@ -INCLUDE_DIRECTORIES(${ROSS_BINARY_DIR}) -IF(BGPM) - INCLUDE_DIRECTORIES(${ROSS_SOURCE_DIR} ${BGPM_LIB}) -ELSE(NOT(BGPM)) - INCLUDE_DIRECTORIES(${ROSS_SOURCE_DIR}) -ENDIF(BGPM) - -SET(phold_srcs - phold.h +set(phold_srcs + phold.h ) +set(phold_targets + phold + phold_comm_test + phold_gvt_hook_test + phold_gvt_hook_model_test + phold_gvt_hook_timestamp_test + phold_gvt_hook_comm_test +) -ADD_EXECUTABLE(phold phold.main.c ${phold_srcs}) -ADD_EXECUTABLE(phold_comm_test phold.main.c ${phold_srcs}) -ADD_EXECUTABLE(phold_gvt_hook_test phold-gvt-hook.main.c ${phold_srcs}) -ADD_EXECUTABLE(phold_gvt_hook_model_test phold-gvt-hook.main.c ${phold_srcs}) -ADD_EXECUTABLE(phold_gvt_hook_timestamp_test phold-gvt-hook.main.c ${phold_srcs}) -ADD_EXECUTABLE(phold_gvt_hook_comm_test phold-gvt-hook.main.c ${phold_srcs}) - -IF(BGPM) - TARGET_LINK_LIBRARIES(phold ROSS imp_bgpm m) - TARGET_LINK_LIBRARIES(phold_comm_test ROSS imp_bgpm m) -ELSE(NOT(BGPM)) - TARGET_LINK_LIBRARIES(phold ROSS m) - TARGET_LINK_LIBRARIES(phold_comm_test ROSS m) - TARGET_LINK_LIBRARIES(phold_gvt_hook_test ROSS m) - TARGET_LINK_LIBRARIES(phold_gvt_hook_model_test ROSS m) - TARGET_LINK_LIBRARIES(phold_gvt_hook_timestamp_test ROSS m) - TARGET_LINK_LIBRARIES(phold_gvt_hook_comm_test ROSS m) -ENDIF(BGPM) +add_executable(phold phold.main.c ${phold_srcs}) +add_executable(phold_comm_test phold.main.c ${phold_srcs}) +add_executable(phold_gvt_hook_test phold-gvt-hook.main.c ${phold_srcs}) +add_executable(phold_gvt_hook_model_test phold-gvt-hook.main.c ${phold_srcs}) +add_executable(phold_gvt_hook_timestamp_test phold-gvt-hook.main.c ${phold_srcs}) +add_executable(phold_gvt_hook_comm_test phold-gvt-hook.main.c ${phold_srcs}) + +# Include dirs ride along ROSS's INTERFACE_INCLUDE_DIRECTORIES, so this +# directory no longer needs its own INCLUDE_DIRECTORIES block. The legacy +# BGPM branch keyed on a variable that was never set (the actual option is +# USE_BGPM, gated to bgq builds) and is dropped. +foreach(t ${phold_targets}) + target_link_libraries(${t} PRIVATE ROSS m) +endforeach() ROSS_TEST_SCHEDULERS(phold) ROSS_TEST_INSTRUMENTATION(phold) @@ -47,4 +44,4 @@ ROSS_TEST_SCHEDULERS(phold_gvt_hook_timestamp_test) SET_TARGET_PROPERTIES(phold_gvt_hook_comm_test PROPERTIES COMPILE_DEFINITIONS TEST_COMM_ROSS) ROSS_TEST_SCHEDULERS(phold_gvt_hook_comm_test) -INSTALL(FILES ${ROSS_BINARY_DIR}/../models/phold/phold DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(TARGETS ${phold_targets} RUNTIME DESTINATION bin) From 96218eb4a6665c0d206693604b48c6ec8a467610 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Wed, 27 May 2026 16:21:52 -0500 Subject: [PATCH 3/8] make find_package(ROSS) self-contained and modern The previous hand-written ROSSConfig.cmake had no version file, no find_dependency(MPI), no namespaced target, and lived at /lib/ where consumers needed a -DROSS_DIR hint to discover it. Out-of-tree projects had to re-run find_package(MPI) themselves and link the bare ROSS target. After this change consumers can write: find_package(ROSS REQUIRED) target_link_libraries(myapp PRIVATE ROSS::ROSS) and get include dirs, the MPI dependency, and link libs propagated transparently. The config installs at the canonical /lib/cmake/ROSS/ which CMake discovers from CMAKE_PREFIX_PATH without any explicit hint, and a generated ROSSConfigVersion.cmake makes version-constrained discovery (find_package(ROSS 8.0)) work. A back-compat ALIAS keeps legacy target_link_libraries(... ROSS) call sites working without modification, and a tiny shim at the old /lib/ROSSConfig.cmake location preserves -DROSS_DIR=/lib callers, emitting a deprecation warning and delegating to the canonical config, while also setting the ROSS_INCLUDE_DIRS variable master used to export. --- core/CMakeLists.txt | 51 +++++++++++++++++++++++-- core/ROSSConfig.cmake | 3 -- core/cmake/ROSSConfig-legacy-shim.cmake | 25 ++++++++++++ core/cmake/ROSSConfig.cmake.in | 36 +++++++++++++++++ 4 files changed, 108 insertions(+), 7 deletions(-) delete mode 100644 core/ROSSConfig.cmake create mode 100644 core/cmake/ROSSConfig-legacy-shim.cmake create mode 100644 core/cmake/ROSSConfig.cmake.in diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 2cbf358f..3098b28e 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -149,10 +149,53 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/ross.pc.in PROPERTIES GE SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ross.pc PROPERTIES GENERATED TRUE) -# Make Install +# Install +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include FILES_MATCHING PATTERN "*.h") -INSTALL(TARGETS ROSS EXPORT ROSS-targets DESTINATION lib) -INSTALL(EXPORT ROSS-targets DESTINATION lib) -INSTALL(FILES ROSSConfig.cmake DESTINATION lib) + +# Library target + namespaced export. +install(TARGETS ROSS + EXPORT ROSSTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +install(EXPORT ROSSTargets + FILE ROSSTargets.cmake + NAMESPACE ROSS:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ROSS) + +# Canonical ROSSConfig.cmake + ROSSConfigVersion.cmake. +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ROSSConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/ROSSConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ROSS) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/ROSSConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/ROSSConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/ROSSConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ROSS) + +# Build-tree export so consumers can use +# find_package(ROSS) against the build dir without installing. +export(EXPORT ROSSTargets + FILE ${CMAKE_CURRENT_BINARY_DIR}/ROSSTargets.cmake + NAMESPACE ROSS::) + +# Legacy-location shim at /${CMAKE_INSTALL_LIBDIR}/ROSSConfig.cmake +# delegates to the canonical config above. Catches users still passing +# -DROSS_DIR=/lib. RENAME because both files are named ROSSConfig.cmake +# but live in different directories. +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ROSSConfig-legacy-shim.cmake + RENAME ROSSConfig.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ross.pc DESTINATION lib/pkgconfig) diff --git a/core/ROSSConfig.cmake b/core/ROSSConfig.cmake deleted file mode 100644 index 380fde8a..00000000 --- a/core/ROSSConfig.cmake +++ /dev/null @@ -1,3 +0,0 @@ -GET_FILENAME_COMPONENT(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -INCLUDE(${SELF_DIR}/ROSS-targets.cmake) -GET_FILENAME_COMPONENT(ROSS_INCLUDE_DIRS "${SELF_DIR}/../include" ABSOLUTE) diff --git a/core/cmake/ROSSConfig-legacy-shim.cmake b/core/cmake/ROSSConfig-legacy-shim.cmake new file mode 100644 index 00000000..b213c158 --- /dev/null +++ b/core/cmake/ROSSConfig-legacy-shim.cmake @@ -0,0 +1,25 @@ +# ROSSConfig.cmake — legacy-location shim +# +# Installed at /${CMAKE_INSTALL_LIBDIR}/ROSSConfig.cmake to preserve +# compatibility with callers that hint find_package(ROSS) via +# -DROSS_DIR=/lib (where master's hand-written ROSSConfig.cmake used +# to live). The canonical config now ships at +# /${CMAKE_INSTALL_LIBDIR}/cmake/ROSS/ROSSConfig.cmake, which CMake +# discovers automatically from CMAKE_PREFIX_PATH. + +message(DEPRECATION + "find_package(ROSS) via -DROSS_DIR=/lib is deprecated. " + "ROSSConfig.cmake now installs at /lib/cmake/ROSS/; drop the " + "-DROSS_DIR hint and CMake will find it via CMAKE_PREFIX_PATH=. " + "This shim will be removed in a future ROSS release.") + +include(${CMAKE_CURRENT_LIST_DIR}/cmake/ROSS/ROSSConfig.cmake) + +# The previously hand-written ROSSConfig.cmake set ROSS_INCLUDE_DIRS. The new +# canonical config deliberately does NOT (imported-targets-only is the modern +# convention), but legacy callers reading ${ROSS_INCLUDE_DIRS} directly keep +# working through this shim. Derived from the target so it always matches the +# real install path. +get_target_property(_ross_inc_dirs ROSS::ROSS INTERFACE_INCLUDE_DIRECTORIES) +set(ROSS_INCLUDE_DIRS ${_ross_inc_dirs}) +unset(_ross_inc_dirs) diff --git a/core/cmake/ROSSConfig.cmake.in b/core/cmake/ROSSConfig.cmake.in new file mode 100644 index 00000000..e7cee4f8 --- /dev/null +++ b/core/cmake/ROSSConfig.cmake.in @@ -0,0 +1,36 @@ +@PACKAGE_INIT@ + +# ROSSConfig.cmake — ROSS package configuration for find_package(ROSS) +# +# Usage: +# find_package(ROSS REQUIRED) +# target_link_libraries(myapp PRIVATE ROSS::ROSS) +# +# The ROSS::ROSS imported target carries include dirs, the MPI dependency, +# and link libraries — no legacy ROSS_LIBRARIES / ROSS_FOUND variables to +# read. If you need the include path explicitly: +# get_target_property(dirs ROSS::ROSS INTERFACE_INCLUDE_DIRECTORIES) +# +# Path B consumer contract for headers: +# #include — supported +# #include — supported (any top-level ross-*.h) +# #include — NOT INSTALLED (*-internal.h excluded +# from the install rule; never public) +# #include — UNSUPPORTED (subdirectory and other +# internal headers ship today but may +# be hidden in a future release). + +include(CMakeFindDependencyMacro) +find_dependency(MPI REQUIRED COMPONENTS C) + +include("${CMAKE_CURRENT_LIST_DIR}/ROSSTargets.cmake") + +# Bare-target back-compat. Master's hand-written ROSSConfig.cmake exported the +# library with no namespace, so legacy target_link_libraries(... ROSS) callers +# expected a plain ROSS target. The new export uses NAMESPACE ROSS::; this +# alias bridges the gap until the bare name is dropped. +if(NOT TARGET ROSS AND TARGET ROSS::ROSS) + add_library(ROSS ALIAS ROSS::ROSS) +endif() + +check_required_components(ROSS) From cdd2a11704be9518abe1d38cb533ac0772837ce0 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Wed, 27 May 2026 16:31:18 -0500 Subject: [PATCH 4/8] move CMake helper modules to top-level cmake/ Top-level is the place for project-level build infrastructure, not among core C files. --- CMakeLists.txt | 2 +- .../cmake => cmake}/GetGitRevisionDescription.LICENSE_1_0.txt | 0 {core/cmake => cmake}/GetGitRevisionDescription.cmake | 0 {core/cmake => cmake}/GetGitRevisionDescription.cmake.in | 0 {core/cmake => cmake}/ROSSConfig-legacy-shim.cmake | 0 {core/cmake => cmake}/ROSSConfig.cmake.in | 0 core/CMakeLists.txt | 4 ++-- 7 files changed, 3 insertions(+), 3 deletions(-) rename {core/cmake => cmake}/GetGitRevisionDescription.LICENSE_1_0.txt (100%) rename {core/cmake => cmake}/GetGitRevisionDescription.cmake (100%) rename {core/cmake => cmake}/GetGitRevisionDescription.cmake.in (100%) rename {core/cmake => cmake}/ROSSConfig-legacy-shim.cmake (100%) rename {core/cmake => cmake}/ROSSConfig.cmake.in (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e827c10b..4c4fc200 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ if(NOT ROSS_DETECTED_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$") "Expected semantic version X.Y.Z (no leading 'v').") endif() -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/core/cmake/") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") include(GetGitRevisionDescription) git_describe_working_tree(ROSS_GIT_DESCRIBE --tags --dirty) if(ROSS_GIT_DESCRIBE MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+(.*)$") diff --git a/core/cmake/GetGitRevisionDescription.LICENSE_1_0.txt b/cmake/GetGitRevisionDescription.LICENSE_1_0.txt similarity index 100% rename from core/cmake/GetGitRevisionDescription.LICENSE_1_0.txt rename to cmake/GetGitRevisionDescription.LICENSE_1_0.txt diff --git a/core/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake similarity index 100% rename from core/cmake/GetGitRevisionDescription.cmake rename to cmake/GetGitRevisionDescription.cmake diff --git a/core/cmake/GetGitRevisionDescription.cmake.in b/cmake/GetGitRevisionDescription.cmake.in similarity index 100% rename from core/cmake/GetGitRevisionDescription.cmake.in rename to cmake/GetGitRevisionDescription.cmake.in diff --git a/core/cmake/ROSSConfig-legacy-shim.cmake b/cmake/ROSSConfig-legacy-shim.cmake similarity index 100% rename from core/cmake/ROSSConfig-legacy-shim.cmake rename to cmake/ROSSConfig-legacy-shim.cmake diff --git a/core/cmake/ROSSConfig.cmake.in b/cmake/ROSSConfig.cmake.in similarity index 100% rename from core/cmake/ROSSConfig.cmake.in rename to cmake/ROSSConfig.cmake.in diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 3098b28e..aaea26e7 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -170,7 +170,7 @@ install(EXPORT ROSSTargets # Canonical ROSSConfig.cmake + ROSSConfigVersion.cmake. configure_package_config_file( - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ROSSConfig.cmake.in + ${CMAKE_SOURCE_DIR}/cmake/ROSSConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/ROSSConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ROSS) @@ -194,7 +194,7 @@ export(EXPORT ROSSTargets # delegates to the canonical config above. Catches users still passing # -DROSS_DIR=/lib. RENAME because both files are named ROSSConfig.cmake # but live in different directories. -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ROSSConfig-legacy-shim.cmake +install(FILES ${CMAKE_SOURCE_DIR}/cmake/ROSSConfig-legacy-shim.cmake RENAME ROSSConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}) From 4928f88bcba64eb6ecd85c2aef16ff3ce1160140 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Wed, 27 May 2026 16:54:05 -0500 Subject: [PATCH 5/8] scope installed headers under include/ross/ Previously every *.h was installed flat into /include/, polluting the consumer's include namespace with common names (config.h, buddy.h, lz4.h, io.h). Moving them under /include/ross/ contains the namespace; the exported target's INSTALL_INTERFACE still resolves #include transparently for consumers. --- CLAUDE.md | 9 +++++++++ cmake/ROSSConfig.cmake.in | 10 +++++++--- core/CMakeLists.txt | 22 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a6e9b7ea..921a87c9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,6 +91,15 @@ The de facto C style in `core/` is: - **Line length**: soft ~100 chars. No hard cap. - **Comments**: both `//` and `/* */` appear; `/** ... */` Doxygen-style is used for some function-level docs but isn't required. +## Consumer-facing API surface + +Installed headers live under `/include/ross/`. External consumers can `#include ` (the umbrella) or any top-level `ross-*.h`. The supported entry-point set is intentionally narrow: + +- **Supported**: `` and any top-level `` (e.g. ``, ``). +- **Unsupported but installed**: `*-internal.h` siblings (`ross-gvt-internal.h`, `ross-random-internal.h`) ship because supported public headers transitively `#include` them. Do not include directly. Subdirectory headers (``, ``, ``, ``) and other internals (``, ``, ``) likewise ship but are not part of the supported surface and may be hidden in the future. + +CMake consumers do `find_package(ROSS REQUIRED)` + `target_link_libraries(... ROSS::ROSS)` and inherit the include path automatically. pkg-config consumers do `pkg_check_modules(ROSS REQUIRED IMPORTED_TARGET ross)` and get the same path via `${ROSS_INCLUDE_DIRS}`. + ## Consumer compatibility (CODES) CODES discovers ROSS via `pkg_check_modules(ROSS REQUIRED IMPORTED_TARGET ross)` using `ross.pc`. It relies on the `ROSS_INCLUDE_DIRS` variable and links `PkgConfig::ROSS`. Any install-layout change (header paths, pkg-config contents) must preserve that surface or CODES breaks. diff --git a/cmake/ROSSConfig.cmake.in b/cmake/ROSSConfig.cmake.in index e7cee4f8..3c64e304 100644 --- a/cmake/ROSSConfig.cmake.in +++ b/cmake/ROSSConfig.cmake.in @@ -13,9 +13,13 @@ # # Path B consumer contract for headers: # #include — supported -# #include — supported (any top-level ross-*.h) -# #include — NOT INSTALLED (*-internal.h excluded -# from the install rule; never public) +# #include — supported (any top-level ross-*.h +# except *-internal.h) +# #include — UNSUPPORTED (ships today because +# public headers like ross-gvt.h +# transitively need it; do not +# include directly. A public/private +# header split is deferred work) # #include — UNSUPPORTED (subdirectory and other # internal headers ship today but may # be hidden in a future release). diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index aaea26e7..5837b1ed 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -153,8 +153,26 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ross.pc PROPERTIES GENER include(GNUInstallDirs) include(CMakePackageConfigHelpers) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h DESTINATION include) -INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include FILES_MATCHING PATTERN "*.h") +# Headers ship under /include/ross/ rather than flat in +# /include/ to avoid polluting the consumer namespace with common +# names (config.h, buddy.h, lz4.h, io.h, etc.). The exported target's +# INSTALL_INTERFACE attaches the right -I flag so #include still +# resolves transparently for consumers. +# +# *-internal.h headers ship despite the name because the supported public +# headers (ross-gvt.h, rand-clcg4.h, ross-random.h, ross-kernel-inline.h) +# transitively #include them. A proper public/private split requires +# refactoring those public headers first. +# +# risa is excluded since Damaris was disabled. +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ross) + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ross + FILES_MATCHING + PATTERN "*.h" + PATTERN "risa" EXCLUDE) # Library target + namespaced export. install(TARGETS ROSS From 5cbcc9967b01d4cea5fba1a1e44624e79c59965c Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Tue, 2 Jun 2026 15:42:50 -0500 Subject: [PATCH 6/8] align ross.pc with the include/ross/ layout Installed headers were moved under /include/ross/, but ross.pc.in still pointed Cflags at the flat /include/ so any pkg-config consumer (CODES today) would emit the wrong -I and miss the headers. Rewriting includedir to point at the new location keeps the pkg-config flow transparent for downstream consumers; no source changes needed on their side. Install destination uses ${CMAKE_INSTALL_LIBDIR}/pkgconfig so multilib (lib64) and Spack-style overrides work. --- core/CMakeLists.txt | 17 +++++++++-------- core/ross.pc.in | 16 +++++++--------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 5837b1ed..d74920eb 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -142,17 +142,17 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in PROPERTIES G SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/config.h PROPERTIES GENERATED TRUE) -# CODES config bin -STRING(REPLACE " " "\\ " CMAKE_INSTALL_PREFIX_ESCAPED "\"${CMAKE_INSTALL_PREFIX}\"") -CONFIGURE_FILE(ross.pc.in ross.pc @ONLY) -SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/ross.pc.in PROPERTIES GENERATED FALSE) -SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/ross.pc PROPERTIES GENERATED TRUE) - - # Install include(GNUInstallDirs) include(CMakePackageConfigHelpers) +# pkg-config file — back-compat surface for consumers that haven't migrated +# to find_package(ROSS) yet. Must run after include(GNUInstallDirs) so the +# CMAKE_INSTALL_LIBDIR / CMAKE_INSTALL_INCLUDEDIR substitutions are +# populated. +string(REPLACE " " "\\ " ROSS_PC_PREFIX "\"${CMAKE_INSTALL_PREFIX}\"") +configure_file(ross.pc.in ross.pc @ONLY) + # Headers ship under /include/ross/ rather than flat in # /include/ to avoid polluting the consumer namespace with common # names (config.h, buddy.h, lz4.h, io.h, etc.). The exported target's @@ -216,4 +216,5 @@ install(FILES ${CMAKE_SOURCE_DIR}/cmake/ROSSConfig-legacy-shim.cmake RENAME ROSSConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ross.pc DESTINATION lib/pkgconfig) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ross.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/core/ross.pc.in b/core/ross.pc.in index 30125d01..483e74aa 100644 --- a/core/ross.pc.in +++ b/core/ross.pc.in @@ -1,13 +1,11 @@ -prefix = @CMAKE_INSTALL_PREFIX_ESCAPED@ - -ross_cflags=-I${prefix}/include -ross_ldflags=-L${prefix}/lib -Wl,-rpath,${prefix}/lib -ross_libs=-lROSS -lm +prefix=@ROSS_PC_PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/ross Name: ROSS Description: Rensselaer's Optimistic Simulation System -Version: @VERSION_SHORT@ URL: https://github.com/ROSS-org/ROSS -Requires: -Libs: ${ross_ldflags} ${ross_libs} -Cflags: ${ross_cflags} +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lROSS -lm +Cflags: -I${includedir} From 0e3d731f0a3cce97d2f6c0fb9df25511a486092d Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Tue, 2 Jun 2026 17:35:18 -0500 Subject: [PATCH 7/8] honor GNUInstallDirs in the RPATH and phold install rules Hoist include(GNUInstallDirs) to the top-level CMakeLists.txt so the install-RPATH stanza can resolve ${CMAKE_INSTALL_LIBDIR} instead of forcing /lib. The phold install rule likewise switches from literal "bin" to ${CMAKE_INSTALL_BINDIR}, completing the sweep that earlier commits had started in core/. On macOS and standard Linux layouts the resulting paths are unchanged; the difference shows up on Debian multiarch (lib/x86_64-linux-gnu) and RHEL/Fedora multilib (lib64), where installed binaries now find libROSS through the correct directory. --- CMakeLists.txt | 6 ++++-- core/CMakeLists.txt | 7 +++---- models/phold/CMakeLists.txt | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c4fc200..e079f772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,8 @@ set(VERSION_SHORT "${PROJECT_VERSION}") set(CMAKE_POSITION_INDEPENDENT_CODE ON) +include(GNUInstallDirs) + # ROSS Configuration Options ENABLE_TESTING() @@ -77,9 +79,9 @@ SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # the RPATH to be used when installing, but only if it's not a system directory -LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) +LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir) IF("${isSystemDir}" STREQUAL "-1") - SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") ENDIF("${isSystemDir}" STREQUAL "-1") # end of spack-related addition diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d74920eb..d1bfeed5 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -143,13 +143,12 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/config.h PROPERTIES GENE # Install -include(GNUInstallDirs) include(CMakePackageConfigHelpers) # pkg-config file — back-compat surface for consumers that haven't migrated -# to find_package(ROSS) yet. Must run after include(GNUInstallDirs) so the -# CMAKE_INSTALL_LIBDIR / CMAKE_INSTALL_INCLUDEDIR substitutions are -# populated. +# to find_package(ROSS) yet. GNUInstallDirs is included at top level so the +# CMAKE_INSTALL_LIBDIR / CMAKE_INSTALL_INCLUDEDIR substitutions are populated +# by the time we get here. string(REPLACE " " "\\ " ROSS_PC_PREFIX "\"${CMAKE_INSTALL_PREFIX}\"") configure_file(ross.pc.in ross.pc @ONLY) diff --git a/models/phold/CMakeLists.txt b/models/phold/CMakeLists.txt index 0acf3aec..b6a4b1ff 100644 --- a/models/phold/CMakeLists.txt +++ b/models/phold/CMakeLists.txt @@ -44,4 +44,4 @@ ROSS_TEST_SCHEDULERS(phold_gvt_hook_timestamp_test) SET_TARGET_PROPERTIES(phold_gvt_hook_comm_test PROPERTIES COMPILE_DEFINITIONS TEST_COMM_ROSS) ROSS_TEST_SCHEDULERS(phold_gvt_hook_comm_test) -install(TARGETS ${phold_targets} RUNTIME DESTINATION bin) +install(TARGETS ${phold_targets} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) From 961dd65c687fdb7d8dd80fa88fcc3cca133ac9f2 Mon Sep 17 00:00:00 2001 From: Caitlin Ross Date: Tue, 2 Jun 2026 17:13:35 -0500 Subject: [PATCH 8/8] add release notes --- Documentation/dev/find-package-ross.build.md | 14 ++++++++++++++ Documentation/dev/headers-under-ross.build.md | 9 +++++++++ Documentation/dev/multilib-install-dirs.build.md | 10 ++++++++++ .../dev/phold-install-all-variants.build.md | 5 +++++ 4 files changed, 38 insertions(+) create mode 100644 Documentation/dev/find-package-ross.build.md create mode 100644 Documentation/dev/headers-under-ross.build.md create mode 100644 Documentation/dev/multilib-install-dirs.build.md create mode 100644 Documentation/dev/phold-install-all-variants.build.md diff --git a/Documentation/dev/find-package-ross.build.md b/Documentation/dev/find-package-ross.build.md new file mode 100644 index 00000000..36975c31 --- /dev/null +++ b/Documentation/dev/find-package-ross.build.md @@ -0,0 +1,14 @@ +`find_package(ROSS REQUIRED)` is now a fully-functional CMake package, +exporting the `ROSS::ROSS` imported target with include directories, +the MPI dependency (re-resolved on the consumer's machine via +`find_dependency(MPI)`), and link libraries propagated transparently. +The canonical config installs at `/lib/cmake/ROSS/`, which +CMake discovers from `CMAKE_PREFIX_PATH=` without any explicit +hint; a generated `ROSSConfigVersion.cmake` enables version-constrained +discovery (`find_package(ROSS 8.0)`). + +Callers passing `-DROSS_DIR=/lib` (master's install location) +keep working through a deprecation shim that prints a warning and +delegates to the canonical config; legacy `target_link_libraries(... ROSS)` +callers keep working through a back-compat ALIAS shipped inside +`ROSSConfig.cmake`. Both shims will be removed in a future release. diff --git a/Documentation/dev/headers-under-ross.build.md b/Documentation/dev/headers-under-ross.build.md new file mode 100644 index 00000000..a12a7b3a --- /dev/null +++ b/Documentation/dev/headers-under-ross.build.md @@ -0,0 +1,9 @@ +**[Breaking]** Installed headers moved from flat `/include/` to +`/include/ross/` so common names (`config.h`, `buddy.h`, +`lz4.h`, `io.h`, etc.) no longer pollute the consumer include +namespace. The CMake exported target and `ross.pc` both point at the +new location automatically, so consumers using `find_package(ROSS)` + +`ROSS::ROSS` or `pkg_check_modules(ROSS ross)` see the change +transparently with no source edits. Consumers that hard-coded +`-I/include` outside those mechanisms need to update to +`-I/include/ross`. diff --git a/Documentation/dev/multilib-install-dirs.build.md b/Documentation/dev/multilib-install-dirs.build.md new file mode 100644 index 00000000..7d761cba --- /dev/null +++ b/Documentation/dev/multilib-install-dirs.build.md @@ -0,0 +1,10 @@ +All install destinations now honor `GNUInstallDirs`: the library, +pkg-config file, CMake config files, and headers use +`${CMAKE_INSTALL_LIBDIR}` / `${CMAKE_INSTALL_INCLUDEDIR}`, and the +phold binaries use `${CMAKE_INSTALL_BINDIR}`. On multilib systems +(RHEL/Fedora-style `lib64`), these artifacts install under +`/lib64/` instead of being forced to `/lib/`; +Spack-style per-component install-dir overrides also work. The +install-RPATH stanza was likewise updated to use +`${CMAKE_INSTALL_LIBDIR}` so installed binaries resolve `libROSS` +through the correct multilib directory. diff --git a/Documentation/dev/phold-install-all-variants.build.md b/Documentation/dev/phold-install-all-variants.build.md new file mode 100644 index 00000000..19118302 --- /dev/null +++ b/Documentation/dev/phold-install-all-variants.build.md @@ -0,0 +1,5 @@ +All six phold model executables (`phold`, `phold_comm_test`, +`phold_gvt_hook_test`, `phold_gvt_hook_model_test`, +`phold_gvt_hook_timestamp_test`, `phold_gvt_hook_comm_test`) now +install with `cmake --install`. Previously only `phold` was +installed; the other five had to be run out of the build tree.