Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <mpi>` 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:
Expand Down Expand Up @@ -89,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 `<prefix>/include/ross/`. External consumers can `#include <ross.h>` (the umbrella) or any top-level `ross-*.h`. The supported entry-point set is intentionally narrow:

- **Supported**: `<ross.h>` and any top-level `<ross-*.h>` (e.g. `<ross-extern.h>`, `<ross-types.h>`).
- **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 (`<instrumentation/...>`, `<check-revent/...>`, `<queue/...>`, `<rio/...>`) and other internals (`<buddy.h>`, `<lz4.h>`, `<hash-quadratic.h>`) 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.
17 changes: 14 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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]+(.*)$")
Expand Down Expand Up @@ -50,6 +50,8 @@ set(VERSION_SHORT "${PROJECT_VERSION}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(GNUInstallDirs)

# ROSS Configuration Options

ENABLE_TESTING()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -188,6 +190,15 @@ ENDIF(VALID_ARCH AND NOT ${ROSS_CLOCK_OVERRIDE})
# `module load <mpi>` 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)
Expand Down
14 changes: 14 additions & 0 deletions Documentation/dev/find-package-ross.build.md
Original file line number Diff line number Diff line change
@@ -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 `<prefix>/lib/cmake/ROSS/`, which
CMake discovers from `CMAKE_PREFIX_PATH=<prefix>` without any explicit
hint; a generated `ROSSConfigVersion.cmake` enables version-constrained
discovery (`find_package(ROSS 8.0)`).

Callers passing `-DROSS_DIR=<prefix>/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.
9 changes: 9 additions & 0 deletions Documentation/dev/headers-under-ross.build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**[Breaking]** Installed headers moved from flat `<prefix>/include/` to
`<prefix>/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<prefix>/include` outside those mechanisms need to update to
`-I<prefix>/include/ross`.
10 changes: 10 additions & 0 deletions Documentation/dev/multilib-install-dirs.build.md
Original file line number Diff line number Diff line change
@@ -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
`<prefix>/lib64/` instead of being forced to `<prefix>/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.
5 changes: 5 additions & 0 deletions Documentation/dev/phold-install-all-variants.build.md
Original file line number Diff line number Diff line change
@@ -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.
25 changes: 25 additions & 0 deletions cmake/ROSSConfig-legacy-shim.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# ROSSConfig.cmake — legacy-location shim
#
# Installed at <prefix>/${CMAKE_INSTALL_LIBDIR}/ROSSConfig.cmake to preserve
# compatibility with callers that hint find_package(ROSS) via
# -DROSS_DIR=<prefix>/lib (where master's hand-written ROSSConfig.cmake used
# to live). The canonical config now ships at
# <prefix>/${CMAKE_INSTALL_LIBDIR}/cmake/ROSS/ROSSConfig.cmake, which CMake
# discovers automatically from CMAKE_PREFIX_PATH.

message(DEPRECATION
"find_package(ROSS) via -DROSS_DIR=<prefix>/lib is deprecated. "
"ROSSConfig.cmake now installs at <prefix>/lib/cmake/ROSS/; drop the "
"-DROSS_DIR hint and CMake will find it via CMAKE_PREFIX_PATH=<prefix>. "
"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)
40 changes: 40 additions & 0 deletions cmake/ROSSConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@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 <ross.h> — supported
# #include <ross-extern.h> — supported (any top-level ross-*.h
# except *-internal.h)
# #include <ross-gvt-internal.h> — 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 <instrumentation/...> — 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)
112 changes: 91 additions & 21 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
PROJECT(ROSS C)
INCLUDE_DIRECTORIES(${ROSS_SOURCE_DIR} ${ROSS_BINARY_DIR})

SET(ross_srcs

queue/tw-queue.h
Expand Down Expand Up @@ -117,33 +114,106 @@ 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})
ADD_LIBRARY(ROSS ${ross_srcs})
SET_TARGET_PROPERTIES(ROSS PROPERTIES OUTPUT_NAME ROSS)
# ROSS_BUILD_SHARED_LIBS, which propagates here as BUILD_SHARED_LIBS.
add_library(ROSS ${ross_srcs})
add_library(ROSS::ROSS ALIAS ROSS)

# MPI is PUBLIC because core/ross.h does `#include <mpi.h>` — 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 <prefix>/include/ross
target_include_directories(ROSS
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:include/ross>
)

# Build Specific Config Header
CONFIGURE_FILE(config.h.in config.h)
SET(ross_srcs ${ross_srcs} config.h)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in PROPERTIES GENERATED FALSE)
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)


# Make Install
INSTALL(FILES ${ROSS_BINARY_DIR}/config.h DESTINATION include)
INSTALL(DIRECTORY ${ROSS_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
include(CMakePackageConfigHelpers)

# pkg-config file — back-compat surface for consumers that haven't migrated
# 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)

# Headers ship under <prefix>/include/ross/ rather than flat in
# <prefix>/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 <ross.h> 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
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_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 <prefix>/${CMAKE_INSTALL_LIBDIR}/ROSSConfig.cmake
# delegates to the canonical config above. Catches users still passing
# -DROSS_DIR=<prefix>/lib. RENAME because both files are named ROSSConfig.cmake
# but live in different directories.
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 ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
3 changes: 0 additions & 3 deletions core/ROSSConfig.cmake

This file was deleted.

16 changes: 7 additions & 9 deletions core/ross.pc.in
Original file line number Diff line number Diff line change
@@ -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}
Loading
Loading