diff --git a/.github/workflows/clang-format-fix.yaml b/.github/workflows/clang-format-fix.yaml index e19d86bec..a9c045c9b 100644 --- a/.github/workflows/clang-format-fix.yaml +++ b/.github/workflows/clang-format-fix.yaml @@ -8,7 +8,9 @@ run-name: "${{ github.actor }} fixing C++ code format" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string workflow_call: @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/.github/workflows/clang-tidy-fix.yaml b/.github/workflows/clang-tidy-fix.yaml index f7e850ba4..e7cf74302 100644 --- a/.github/workflows/clang-tidy-fix.yaml +++ b/.github/workflows/clang-tidy-fix.yaml @@ -8,7 +8,9 @@ name: Clang-Tidy Fix workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string tidy-checks: diff --git a/.github/workflows/cmake-format-fix.yaml b/.github/workflows/cmake-format-fix.yaml index 2bb6f6398..6b6269f63 100644 --- a/.github/workflows/cmake-format-fix.yaml +++ b/.github/workflows/cmake-format-fix.yaml @@ -8,7 +8,9 @@ run-name: "${{ github.actor }} fixing CMake format" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string workflow_call: @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index f9bfad776..322cf978d 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -218,13 +218,7 @@ jobs: fi determine-languages: - needs: - [ - pre-check, - detect-changes-cpp, - detect-changes-python, - detect-changes-actions, - ] + needs: [pre-check, detect-changes-cpp, detect-changes-python, detect-changes-actions] if: always() && needs.pre-check.result == 'success' runs-on: ubuntu-latest outputs: diff --git a/.github/workflows/header-guards-fix.yaml b/.github/workflows/header-guards-fix.yaml index 2c0f7fb6a..5abea8d3a 100644 --- a/.github/workflows/header-guards-fix.yaml +++ b/.github/workflows/header-guards-fix.yaml @@ -43,7 +43,9 @@ run-name: "${{ github.actor }} fixing header guards" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/.github/workflows/jsonnet-format-fix.yaml b/.github/workflows/jsonnet-format-fix.yaml index 5a02e4aaa..1f721e9be 100644 --- a/.github/workflows/jsonnet-format-fix.yaml +++ b/.github/workflows/jsonnet-format-fix.yaml @@ -8,7 +8,9 @@ run-name: "${{ github.actor }} fixing Jsonnet format" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string workflow_call: @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/.github/workflows/markdown-fix.yaml b/.github/workflows/markdown-fix.yaml index bee7f76e6..e0150475c 100644 --- a/.github/workflows/markdown-fix.yaml +++ b/.github/workflows/markdown-fix.yaml @@ -43,7 +43,9 @@ run-name: "${{ github.actor }} fixing Markdown format" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/.github/workflows/python-fix.yaml b/.github/workflows/python-fix.yaml index 1f2bcc059..c9961213c 100644 --- a/.github/workflows/python-fix.yaml +++ b/.github/workflows/python-fix.yaml @@ -8,7 +8,9 @@ run-name: "${{ github.actor }} fixing Python code" workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string workflow_call: @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info if: github.event_name == 'issue_comment' && inputs.ref == '' diff --git a/.github/workflows/yaml-fix.yaml b/.github/workflows/yaml-fix.yaml index 36c9f5c51..cbb53491c 100644 --- a/.github/workflows/yaml-fix.yaml +++ b/.github/workflows/yaml-fix.yaml @@ -8,7 +8,9 @@ name: YAML Fix workflow_dispatch: inputs: ref: - description: "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the repository's default branch." + description: + "The branch name to checkout and push fixes to (must be a branch, not a commit SHA). Defaults to the + repository's default branch." required: false type: string workflow_call: @@ -52,8 +54,7 @@ permissions: contents: write env: - local_checkout_path: - ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ inputs.checkout-path || format('{0}-src', github.event.repository.name) }} jobs: pre-check: @@ -70,11 +71,11 @@ jobs: # This covers repo owners, invited collaborators, and all org members. outputs: ref: - ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && - (github.event.inputs.ref || github.ref_name)) || steps.get_pr.outputs.ref }} + ${{ inputs.ref || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref_name)) || + steps.get_pr.outputs.ref }} repo: - ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && - github.repository) || steps.get_pr.outputs.repo }} + ${{ inputs.repo || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo + }} steps: - name: Get PR Info diff --git a/CMakeLists.txt b/CMakeLists.txt index dad564236..17454494d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,21 @@ FetchContent_Declare( FIND_PACKAGE_ARGS ) +# ############################################################################## +# Initial compilation flags for build types we care about +if(NOT CMAKE_CXX_FLAGS_DEBUG) + set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE STRING "" FORCE) +endif() + +if(NOT CMAKE_CXX_FLAGS_RELEASE) + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g0 -DNDEBUG" CACHE STRING "" FORCE) +endif() + +if(NOT CMAKE_CXX_FLAGS_RELWITHDEBINFO) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -fno-omit-frame-pointer -g -DNDEBUG" CACHE STRING "" FORCE) +endif() +# ############################################################################## + # Make cetmodules available FetchContent_MakeAvailable(cetmodules) find_package(cetmodules 4.01.01 REQUIRED) @@ -58,6 +73,8 @@ set(CTEST_TEST_TIMEOUT 90 CACHE STRING "Per-test timeout (s) for CTest") FetchContent_MakeAvailable(Catch2 GSL mimicpp) include(Modules/private/CreateCoverageTargets.cmake) +include(Modules/private/PhlexSymbolVisibility.cmake) +include(Modules/private/PhlexOptimization.cmake) option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) option(ENABLE_ASAN "Enable Address Sanitizer" OFF) diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake new file mode 100644 index 000000000..a0528d7d2 --- /dev/null +++ b/Modules/private/PhlexOptimization.cmake @@ -0,0 +1,175 @@ +# Provides phlex_apply_optimizations(target), which applies safe, +# performance-oriented compiler flags to a Phlex shared library target. +# Also defines the PHLEX_HIDE_SYMBOLS and PHLEX_ENABLE_IPO options and +# documents how they interact. +# +# Two flags are applied (subject to compiler support and platform): +# +# -fno-semantic-interposition (GCC >= 9, Clang >= 8) +# The compiler may assume that exported symbols in this shared library are +# not overridden at runtime by LD_PRELOAD or another DSO. This is the +# natural complement of -fvisibility=hidden: once the exported-symbol +# surface is bounded by explicit export macros, treating those symbols as +# non-interposable allows the compiler to inline, devirtualise, and +# generate direct (non-PLT) calls for same-DSO accesses to exported +# functions. +# +# External plugins continue to call Phlex symbols through the standard +# PLT/GOT mechanism; only code compiled as part of a Phlex shared library +# itself benefits. +# +# Applied only when PHLEX_HIDE_SYMBOLS=ON (export macros are present and +# the exported-symbol set is well-defined). +# +# -fno-plt (GCC >= 7.3, Clang >= 4, ELF platforms) +# Calls FROM a Phlex library TO symbols in other shared libraries (TBB, +# Boost, spdlog, ...) bypass the PLT stub and load the target address +# directly from the GOT. This replaces one level of indirection on every +# cross-DSO call after first resolution. Semantics are unchanged; only +# the dispatch mechanism differs. +# +# Not applied on Apple platforms: Mach-O uses two-level namespaces and the +# PLT abstraction does not map directly to ELF semantics. +# +# Intentionally excluded: +# -ffast-math / -funsafe-math-optimizations +# Physics and numerical code relies on well-defined floating-point +# semantics (NaN propagation, exact rounding, signed-zero behaviour). +# These flags may silently produce incorrect numerical results and are +# therefore not enabled. +# +# Options and their interaction with CMAKE_BUILD_TYPE +# +# Both PHLEX_HIDE_SYMBOLS and PHLEX_ENABLE_IPO are defined here so that their +# defaults can be derived together. The effective defaults are: +# +# CMAKE_BUILD_TYPE PHLEX_ENABLE_IPO PHLEX_HIDE_SYMBOLS +# ───────────────── ─────────────── ───────────────── +# Release ON ON +# RelWithDebInfo ON ON +# Debug / sanitizer OFF OFF +# not set OFF OFF +# +# Both options can be overridden independently on the command line: +# +# -DPHLEX_HIDE_SYMBOLS=ON -DPHLEX_ENABLE_IPO=ON → LTO + -fno-semantic-interposition +# (maximum optimization) +# -DPHLEX_HIDE_SYMBOLS=OFF -DPHLEX_ENABLE_IPO=ON → LTO only; -fno-semantic-interposition +# is NOT applied (valid, useful for +# benchmarking against the ON case) +# -DPHLEX_HIDE_SYMBOLS=ON -DPHLEX_ENABLE_IPO=OFF → -fno-semantic-interposition only +# -DPHLEX_HIDE_SYMBOLS=OFF -DPHLEX_ENABLE_IPO=OFF → no special optimization flags +# +# The per-target flags in phlex_apply_optimizations() self-adjust automatically +# to reflect whichever combination is in effect. +# +# PHLEX_ENABLE_IPO (default ON for Release/RelWithDebInfo, OFF otherwise) +# When ON, enables interprocedural optimization (LTO) for Release and +# RelWithDebInfo configurations. LTO is safe with or without symbol hiding +# because export attributes preserve the complete exported-symbol set. +# External plugins compiled without LTO link against the normal +# exported-symbol table and are unaffected. +# +# PHLEX_HIDE_SYMBOLS (default ON for Release/RelWithDebInfo, OFF otherwise) +# When ON: hidden-by-default visibility; export macros mark the public API. +# When OFF: all symbols visible; _internal targets become thin INTERFACE +# aliases of their public counterparts. + + +include_guard() + +include(CheckCXXCompilerFlag) + +# Probe flag availability once at module-load time (results are cached in the +# CMake cache and reused across reconfigures). +check_cxx_compiler_flag( + "-fno-semantic-interposition" + PHLEX_CXX_HAVE_NO_SEMANTIC_INTERPOSITION +) + +if(NOT APPLE) + check_cxx_compiler_flag("-fno-plt" PHLEX_CXX_HAVE_NO_PLT) +endif() + +# --------------------------------------------------------------------------- +# Interprocedural optimization (LTO) — defined first so its value can inform +# the PHLEX_HIDE_SYMBOLS default below. +# --------------------------------------------------------------------------- +cmake_policy(SET CMP0069 NEW) +include(CheckIPOSupported) + +if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") + set(_phlex_ipo_default ON) +else() + set(_phlex_ipo_default OFF) +endif() + +option( + PHLEX_ENABLE_IPO + [=[Enable interprocedural optimization (LTO) for Release and RelWithDebInfo +builds. Defaults to ON when CMAKE_BUILD_TYPE is Release or RelWithDebInfo. +Can be combined with PHLEX_HIDE_SYMBOLS=ON for maximum optimization, or with +PHLEX_HIDE_SYMBOLS=OFF to benchmark LTO benefit without symbol hiding.]=] + "${_phlex_ipo_default}" +) + +# --------------------------------------------------------------------------- +# Symbol hiding — default follows CMAKE_BUILD_TYPE independently of IPO. +# The two options are orthogonal: both ON/OFF combinations are valid and +# produce different optimization profiles for benchmarking. +# --------------------------------------------------------------------------- +if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") + set(_phlex_hide_default ON) +else() + set(_phlex_hide_default OFF) +endif() + +option( + PHLEX_HIDE_SYMBOLS + [=[Hide non-exported symbols in shared libraries (ON = curated API with +hidden-by-default visibility; OFF = all symbols visible). Defaults to ON for +Release/RelWithDebInfo builds. +Combined with PHLEX_ENABLE_IPO=ON: -fno-semantic-interposition is also applied +for maximum optimization. Setting OFF while PHLEX_ENABLE_IPO=ON is valid and +useful for comparing LTO performance with and without symbol hiding.]=] + "${_phlex_hide_default}" +) + +# --------------------------------------------------------------------------- +# Activate LTO (if enabled and supported) +# --------------------------------------------------------------------------- +if(PHLEX_ENABLE_IPO) + check_ipo_supported( + RESULT _phlex_ipo_supported + OUTPUT _phlex_ipo_output + LANGUAGES CXX + ) + if(_phlex_ipo_supported) + # Set defaults for all targets created in this scope and below. The + # *_RELEASE and *_RELWITHDEBINFO variants leave Debug/Coverage/sanitizer + # builds unaffected (those configs override optimization independently). + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON) + message(STATUS "Phlex: LTO enabled for Release and RelWithDebInfo builds") + else() + message( + WARNING + "Phlex: PHLEX_ENABLE_IPO=ON but LTO is not supported: ${_phlex_ipo_output}" + ) + endif() +endif() + +# --------------------------------------------------------------------------- +function(phlex_apply_optimizations target) + # -fno-semantic-interposition pairs with PHLEX_HIDE_SYMBOLS: the compiler + # may only treat exported symbols as non-interposable once the exported- + # symbol surface has been explicitly bounded by export macros. + if(PHLEX_HIDE_SYMBOLS AND PHLEX_CXX_HAVE_NO_SEMANTIC_INTERPOSITION) + target_compile_options("${target}" PRIVATE "-fno-semantic-interposition") + endif() + + # -fno-plt reduces cross-DSO call overhead on ELF (Linux) platforms. + if(PHLEX_CXX_HAVE_NO_PLT) + target_compile_options("${target}" PRIVATE "-fno-plt") + endif() +endfunction() diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake new file mode 100644 index 000000000..69590f457 --- /dev/null +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -0,0 +1,112 @@ +include(GenerateExportHeader) + +function(phlex_apply_symbol_visibility target) + set(EXPORT_HEADER "${PROJECT_BINARY_DIR}/include/phlex/${target}_export.hpp") + set(EXPORT_MACRO_NAME "${target}_EXPORT") + + generate_export_header( + ${target} + BASE_NAME ${target} + EXPORT_FILE_NAME ${EXPORT_HEADER} + EXPORT_MACRO_NAME ${EXPORT_MACRO_NAME} + STATIC_DEFINE "${target}_STATIC_DEFINE" + ) + + if(PHLEX_HIDE_SYMBOLS) + set_target_properties( + ${target} + PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON + ) + endif() + + target_include_directories(${target} PUBLIC $) + + install(FILES "${EXPORT_HEADER}" DESTINATION include/phlex) +endfunction() + +# Create a companion library _internal: +# +# When PHLEX_HIDE_SYMBOLS is ON (default): a non-installed shared library with +# default (visible) symbol visibility, compiled from the same sources as +# . This allows tests to access non-exported implementation details +# without requiring every internal symbol to carry an EXPORT macro, and enables +# before/after comparison of library/executable sizes and link/load times. +# +# When PHLEX_HIDE_SYMBOLS is OFF: an INTERFACE target that simply links to +# . Since all public library symbols are already visible in this mode, +# no separate compilation is needed and _internal targets are effectively +# identical to their public counterparts. +# +# Usage (in the same CMakeLists.txt that defines ): +# phlex_make_internal_library( LIBRARIES [PUBLIC ...] [PRIVATE ...]) +# +# The LIBRARIES arguments mirror those of the original cet_make_library call but +# may substitute other _internal targets for the corresponding public ones so +# that the full transitive symbol set is visible (PHLEX_HIDE_SYMBOLS=ON only). +function(phlex_make_internal_library target) + cmake_parse_arguments(ARG "" "" "LIBRARIES" ${ARGN}) + + set(internal "${target}_internal") + + if(NOT PHLEX_HIDE_SYMBOLS) + # All public symbols already visible — _internal is a thin INTERFACE wrapper. + add_library(${internal} INTERFACE) + target_link_libraries(${internal} INTERFACE ${target}) + return() + endif() + + # Retrieve sources and source directory from the public target so we don't + # have to maintain a separate source list. + get_target_property(srcs ${target} SOURCES) + if(NOT srcs) + message(FATAL_ERROR "phlex_make_internal_library: ${target} has no SOURCES property") + endif() + get_target_property(src_dir ${target} SOURCE_DIR) + get_target_property(bin_dir ${target} BINARY_DIR) + + # Convert relative paths to absolute. Generated sources (e.g. configure_file + # output) live in the binary directory rather than the source directory. + set(abs_srcs "") + foreach(s IN LISTS srcs) + if(IS_ABSOLUTE "${s}") + list(APPEND abs_srcs "${s}") + elseif(EXISTS "${src_dir}/${s}") + list(APPEND abs_srcs "${src_dir}/${s}") + else() + list(APPEND abs_srcs "${bin_dir}/${s}") + endif() + endforeach() + + # Use add_library directly (not cet_make_library) so that cetmodules does not + # register this target for installation or package export. + add_library(${internal} SHARED ${abs_srcs}) + + if(ARG_LIBRARIES) + target_link_libraries(${internal} ${ARG_LIBRARIES}) + endif() + + # Cetmodules automatically adds $ for + # libraries it manages; replicate that here so consumers (e.g. layer_generator_internal) + # can resolve project headers such as #include "phlex/core/...". + # The _export.hpp headers live in PROJECT_BINARY_DIR/include/phlex. + # Without CXX_VISIBILITY_PRESET hidden the export macros expand to the default + # visibility attribute, making every symbol visible — exactly what we want here. + target_include_directories( + ${internal} + PUBLIC + "$" + "$" + ) + + # Propagate compile definitions and options that the public target carries + # (e.g. BOOST_DLL_USE_STD_FS for run_phlex) so the internal build is equivalent. + get_target_property(defs ${target} COMPILE_DEFINITIONS) + if(defs) + target_compile_definitions(${internal} PRIVATE ${defs}) + endif() + + get_target_property(opts ${target} COMPILE_OPTIONS) + if(opts) + target_compile_options(${internal} PRIVATE ${opts}) + endif() +endfunction() diff --git a/phlex/CMakeLists.txt b/phlex/CMakeLists.txt index f208a812a..76e54ae2e 100644 --- a/phlex/CMakeLists.txt +++ b/phlex/CMakeLists.txt @@ -33,6 +33,8 @@ cet_make_library( Boost::json phlex::core ) +phlex_apply_symbol_visibility(phlex_configuration_internal) +phlex_apply_optimizations(phlex_configuration_internal) cet_make_library( LIBRARY_NAME diff --git a/phlex/app/CMakeLists.txt b/phlex/app/CMakeLists.txt index 3c0a57af0..66c537496 100644 --- a/phlex/app/CMakeLists.txt +++ b/phlex/app/CMakeLists.txt @@ -18,10 +18,20 @@ cet_make_library( ) install(FILES load_module.hpp run.hpp version.hpp DESTINATION include/phlex/app) +phlex_apply_symbol_visibility(run_phlex) +phlex_apply_optimizations(run_phlex) # We'll use C++17's filesystem instead of Boost's target_compile_definitions(run_phlex PRIVATE BOOST_DLL_USE_STD_FS) +phlex_make_internal_library( + run_phlex + LIBRARIES + PUBLIC phlex_core_internal Boost::json Boost::boost +) +# BOOST_DLL_USE_STD_FS is propagated from run_phlex's COMPILE_DEFINITIONS by +# phlex_make_internal_library, so no explicit repeat is needed here. + cet_make_exec( NAME phlex SOURCE phlex.cpp diff --git a/phlex/app/load_module.hpp b/phlex/app/load_module.hpp index 14d3ba1f4..20fbcc3b8 100644 --- a/phlex/app/load_module.hpp +++ b/phlex/app/load_module.hpp @@ -1,23 +1,31 @@ #ifndef PHLEX_APP_LOAD_MODULE_HPP #define PHLEX_APP_LOAD_MODULE_HPP +#include "phlex/run_phlex_export.hpp" + #include "phlex/core/fwd.hpp" #include "phlex/driver.hpp" #include "boost/json.hpp" #include +#include namespace phlex::experimental { namespace detail { // Adjust_config adds the module_label as a parameter, and it checks if the 'py' // parameter exists, inserting the 'cpp: "pymodule"' configuration if necessary. - boost::json::object adjust_config(std::string const& label, boost::json::object raw_config); + run_phlex_EXPORT boost::json::object adjust_config(std::string const& label, + boost::json::object raw_config); } - void load_module(framework_graph& g, std::string const& label, boost::json::object config); - void load_source(framework_graph& g, std::string const& label, boost::json::object config); - detail::next_index_t load_driver(boost::json::object const& config); + run_phlex_EXPORT void load_module(framework_graph& g, + std::string const& label, + boost::json::object config); + run_phlex_EXPORT void load_source(framework_graph& g, + std::string const& label, + boost::json::object config); + run_phlex_EXPORT detail::next_index_t load_driver(boost::json::object const& config); } #endif // PHLEX_APP_LOAD_MODULE_HPP diff --git a/phlex/app/run.hpp b/phlex/app/run.hpp index 96161b773..af4ab113f 100644 --- a/phlex/app/run.hpp +++ b/phlex/app/run.hpp @@ -1,12 +1,14 @@ #ifndef PHLEX_APP_RUN_HPP #define PHLEX_APP_RUN_HPP +#include "phlex/run_phlex_export.hpp" + #include "boost/json.hpp" #include namespace phlex::experimental { - void run(boost::json::object const& configurations, int max_parallelism); + run_phlex_EXPORT void run(boost::json::object const& configurations, int max_parallelism); } #endif // PHLEX_APP_RUN_HPP diff --git a/phlex/app/version.hpp b/phlex/app/version.hpp index ec1dbe940..dfb9b93cc 100644 --- a/phlex/app/version.hpp +++ b/phlex/app/version.hpp @@ -1,7 +1,9 @@ #ifndef PHLEX_APP_VERSION_HPP #define PHLEX_APP_VERSION_HPP +#include "phlex/run_phlex_export.hpp" + namespace phlex::experimental { - char const* version(); + run_phlex_EXPORT char const* version(); } #endif // PHLEX_APP_VERSION_HPP diff --git a/phlex/concurrency.hpp b/phlex/concurrency.hpp index b456b9137..cb98595fb 100644 --- a/phlex/concurrency.hpp +++ b/phlex/concurrency.hpp @@ -1,10 +1,12 @@ #ifndef PHLEX_CONCURRENCY_HPP #define PHLEX_CONCURRENCY_HPP +#include "phlex/phlex_core_export.hpp" + #include namespace phlex { - struct concurrency { + struct phlex_core_EXPORT concurrency { static concurrency const unlimited; static concurrency const serial; diff --git a/phlex/configuration.hpp b/phlex/configuration.hpp index 7dcf3945d..1a5ec1ef0 100644 --- a/phlex/configuration.hpp +++ b/phlex/configuration.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CONFIGURATION_HPP #define PHLEX_CONFIGURATION_HPP +#include "phlex/phlex_configuration_internal_export.hpp" + #include "boost/json.hpp" #include "phlex/core/product_query.hpp" #include "phlex/model/identifier.hpp" @@ -22,8 +24,8 @@ namespace phlex { } // Used later for product_query - std::optional value_if_exists(boost::json::object const& obj, - std::string_view parameter); + phlex_configuration_internal_EXPORT std::optional + value_if_exists(boost::json::object const& obj, std::string_view parameter); // helper for unpacking json array template @@ -34,7 +36,7 @@ namespace phlex { } } - class configuration { + class phlex_configuration_internal_EXPORT configuration { public: configuration() = default; explicit configuration(boost::json::object const& config) : config_{config} {} @@ -89,15 +91,15 @@ namespace phlex { // To enable direct conversions from Boost JSON types to our own types, we implement // tag_invoke(...) function overloads, which are the customization points Boost JSON // provides. - configuration tag_invoke(boost::json::value_to_tag const&, - boost::json::value const& jv); + phlex_configuration_internal_EXPORT configuration + tag_invoke(boost::json::value_to_tag const&, boost::json::value const& jv); - product_query tag_invoke(boost::json::value_to_tag const&, - boost::json::value const& jv); + phlex_configuration_internal_EXPORT product_query + tag_invoke(boost::json::value_to_tag const&, boost::json::value const& jv); namespace experimental { - identifier tag_invoke(boost::json::value_to_tag const&, - boost::json::value const& jv); + phlex_configuration_internal_EXPORT identifier + tag_invoke(boost::json::value_to_tag const&, boost::json::value const& jv); } template diff --git a/phlex/core/CMakeLists.txt b/phlex/core/CMakeLists.txt index 36fd293a3..fce6340f3 100644 --- a/phlex/core/CMakeLists.txt +++ b/phlex/core/CMakeLists.txt @@ -81,6 +81,8 @@ install( DESTINATION include/phlex/core/detail ) target_include_directories(phlex_core PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_core) +phlex_apply_optimizations(phlex_core) # AppleClang 15.0 still treats std::views::join as experimental if( @@ -90,6 +92,14 @@ if( target_compile_options(phlex_core PRIVATE "-fexperimental-library") endif() +phlex_make_internal_library( + phlex_core + LIBRARIES + PUBLIC TBB::tbb phlex::metaprogramming phlex_model_internal phlex_utilities_internal + PRIVATE Boost::json spdlog::spdlog +) +add_library(phlex::core_internal ALIAS phlex_core_internal) + # Interface library cet_make_library( LIBRARY_NAME diff --git a/phlex/core/consumer.hpp b/phlex/core/consumer.hpp index fbd38b055..bc4c70a00 100644 --- a/phlex/core/consumer.hpp +++ b/phlex/core/consumer.hpp @@ -1,13 +1,15 @@ #ifndef PHLEX_CORE_CONSUMER_HPP #define PHLEX_CORE_CONSUMER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/model/algorithm_name.hpp" #include #include namespace phlex::experimental { - class consumer { + class phlex_core_EXPORT consumer { public: consumer(algorithm_name name, std::vector predicates); diff --git a/phlex/core/declared_fold.hpp b/phlex/core/declared_fold.hpp index 4a6415324..429a252d3 100644 --- a/phlex/core/declared_fold.hpp +++ b/phlex/core/declared_fold.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_FOLD_HPP #define PHLEX_CORE_DECLARED_FOLD_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/fold/send.hpp" @@ -34,7 +36,7 @@ #include namespace phlex::experimental { - class declared_fold : public products_consumer { + class phlex_core_EXPORT declared_fold : public products_consumer { public: declared_fold(algorithm_name name, std::vector predicates, diff --git a/phlex/core/declared_observer.hpp b/phlex/core/declared_observer.hpp index d1bea85e8..fc3e6d0eb 100644 --- a/phlex/core/declared_observer.hpp +++ b/phlex/core/declared_observer.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_OBSERVER_HPP #define PHLEX_CORE_DECLARED_OBSERVER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/input_arguments.hpp" @@ -30,7 +32,7 @@ namespace phlex::experimental { - class declared_observer : public products_consumer { + class phlex_core_EXPORT declared_observer : public products_consumer { public: declared_observer(algorithm_name name, std::vector predicates, diff --git a/phlex/core/declared_output.hpp b/phlex/core/declared_output.hpp index 7ca82f4f2..4e2643583 100644 --- a/phlex/core/declared_output.hpp +++ b/phlex/core/declared_output.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_OUTPUT_HPP #define PHLEX_CORE_DECLARED_OUTPUT_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/consumer.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/message.hpp" @@ -20,7 +22,7 @@ namespace phlex::experimental { namespace detail { using output_function_t = std::function; } - class declared_output : public consumer { + class phlex_core_EXPORT declared_output : public consumer { public: declared_output(algorithm_name name, std::size_t concurrency, diff --git a/phlex/core/declared_predicate.hpp b/phlex/core/declared_predicate.hpp index 72643c7da..755d8b295 100644 --- a/phlex/core/declared_predicate.hpp +++ b/phlex/core/declared_predicate.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_PREDICATE_HPP #define PHLEX_CORE_DECLARED_PREDICATE_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/concepts.hpp" #include "phlex/core/detail/filter_impl.hpp" #include "phlex/core/fwd.hpp" @@ -32,7 +34,7 @@ namespace phlex::experimental { - class declared_predicate : public products_consumer { + class phlex_core_EXPORT declared_predicate : public products_consumer { public: declared_predicate(algorithm_name name, std::vector predicates, diff --git a/phlex/core/declared_provider.hpp b/phlex/core/declared_provider.hpp index 33576de6e..9ade62ef1 100644 --- a/phlex/core/declared_provider.hpp +++ b/phlex/core/declared_provider.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_PROVIDER_HPP #define PHLEX_CORE_DECLARED_PROVIDER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/message.hpp" @@ -22,7 +24,7 @@ namespace phlex::experimental { - class declared_provider { + class phlex_core_EXPORT declared_provider { public: declared_provider(algorithm_name name, product_query output_product); virtual ~declared_provider(); diff --git a/phlex/core/declared_transform.hpp b/phlex/core/declared_transform.hpp index 34358cd8d..8e9586c2b 100644 --- a/phlex/core/declared_transform.hpp +++ b/phlex/core/declared_transform.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_TRANSFORM_HPP #define PHLEX_CORE_DECLARED_TRANSFORM_HPP +#include "phlex/phlex_core_export.hpp" + // FIXME: Add comments explaining the process. For each implementation, explain what part // of the process a given section of code is addressing. @@ -36,7 +38,7 @@ namespace phlex::experimental { - class declared_transform : public products_consumer { + class phlex_core_EXPORT declared_transform : public products_consumer { public: declared_transform(algorithm_name name, std::vector predicates, diff --git a/phlex/core/declared_unfold.hpp b/phlex/core/declared_unfold.hpp index 8d5010cf5..8952f6f36 100644 --- a/phlex/core/declared_unfold.hpp +++ b/phlex/core/declared_unfold.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DECLARED_UNFOLD_HPP #define PHLEX_CORE_DECLARED_UNFOLD_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/input_arguments.hpp" @@ -32,7 +34,7 @@ namespace phlex::experimental { - class generator { + class phlex_core_EXPORT generator { public: explicit generator(product_store_const_ptr const& parent, algorithm_name node_name, @@ -53,7 +55,7 @@ namespace phlex::experimental { std::map child_counts_; }; - class declared_unfold : public products_consumer { + class phlex_core_EXPORT declared_unfold : public products_consumer { public: declared_unfold(algorithm_name name, std::vector predicates, diff --git a/phlex/core/detail/filter_impl.hpp b/phlex/core/detail/filter_impl.hpp index 4d6dcd2de..0277ee876 100644 --- a/phlex/core/detail/filter_impl.hpp +++ b/phlex/core/detail/filter_impl.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DETAIL_FILTER_IMPL_HPP #define PHLEX_CORE_DETAIL_FILTER_IMPL_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/fwd.hpp" #include "phlex/core/product_query.hpp" #include "phlex/model/product_store.hpp" @@ -29,7 +31,7 @@ namespace phlex::experimental { return value == true_value; } - class decision_map { + class phlex_core_EXPORT decision_map { using decisions_t = oneapi::tbb::concurrent_hash_map; public: @@ -47,7 +49,7 @@ namespace phlex::experimental { decisions_t results_; }; - class data_map { + class phlex_core_EXPORT data_map { using stores_t = oneapi::tbb::concurrent_hash_map>; diff --git a/phlex/core/detail/make_algorithm_name.hpp b/phlex/core/detail/make_algorithm_name.hpp index 2edde613d..b554e1b9f 100644 --- a/phlex/core/detail/make_algorithm_name.hpp +++ b/phlex/core/detail/make_algorithm_name.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DETAIL_MAKE_ALGORITHM_NAME_HPP #define PHLEX_CORE_DETAIL_MAKE_ALGORITHM_NAME_HPP +#include "phlex/phlex_core_export.hpp" + // This simple utility is placed in an implementation file to avoid including the // phlex/configuration.hpp in framework code. @@ -14,7 +16,8 @@ namespace phlex::experimental { class algorithm_name; namespace detail { - algorithm_name make_algorithm_name(configuration const* config, std::string_view name); + phlex_core_EXPORT algorithm_name make_algorithm_name(configuration const* config, + std::string_view name); } } diff --git a/phlex/core/detail/maybe_predicates.hpp b/phlex/core/detail/maybe_predicates.hpp index 196915d7f..f48c33a87 100644 --- a/phlex/core/detail/maybe_predicates.hpp +++ b/phlex/core/detail/maybe_predicates.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DETAIL_MAYBE_PREDICATES_HPP #define PHLEX_CORE_DETAIL_MAYBE_PREDICATES_HPP +#include "phlex/phlex_core_export.hpp" + // This simple utility is placed in an implementation file to avoid including the // phlex/configuration.hpp in framework code. @@ -13,7 +15,8 @@ namespace phlex { } namespace phlex::experimental::detail { - std::optional> maybe_predicates(configuration const* config); + phlex_core_EXPORT std::optional> maybe_predicates( + configuration const* config); } #endif // PHLEX_CORE_DETAIL_MAYBE_PREDICATES_HPP diff --git a/phlex/core/detail/repeater_node.hpp b/phlex/core/detail/repeater_node.hpp index eb9ba978f..1b48fec9c 100644 --- a/phlex/core/detail/repeater_node.hpp +++ b/phlex/core/detail/repeater_node.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_DETAIL_REPEATER_NODE_HPP #define PHLEX_CORE_DETAIL_REPEATER_NODE_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/message.hpp" #include "oneapi/tbb/concurrent_hash_map.h" @@ -15,7 +17,8 @@ namespace phlex::experimental::detail { using repeater_node_input = std::tuple; - class repeater_node : public tbb::flow::composite_node> { + class phlex_core_EXPORT repeater_node : + public tbb::flow::composite_node> { public: repeater_node(tbb::flow::graph& g, std::string node_name, identifier layer_name); diff --git a/phlex/core/edge_creation_policy.hpp b/phlex/core/edge_creation_policy.hpp index b6f0783e7..caede8b78 100644 --- a/phlex/core/edge_creation_policy.hpp +++ b/phlex/core/edge_creation_policy.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_EDGE_CREATION_POLICY_HPP #define PHLEX_CORE_EDGE_CREATION_POLICY_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/message.hpp" #include "phlex/model/identifier.hpp" #include "phlex/model/product_specification.hpp" @@ -15,7 +17,7 @@ namespace phlex::experimental { using product_name_t = identifier; - class edge_creation_policy { + class phlex_core_EXPORT edge_creation_policy { public: template edge_creation_policy(Args&... producers); diff --git a/phlex/core/edge_maker.hpp b/phlex/core/edge_maker.hpp index fb4bf3289..a40a46028 100644 --- a/phlex/core/edge_maker.hpp +++ b/phlex/core/edge_maker.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_EDGE_MAKER_HPP #define PHLEX_CORE_EDGE_MAKER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_output.hpp" #include "phlex/core/declared_provider.hpp" @@ -28,7 +30,7 @@ namespace phlex::experimental { index_router::provider_input_ports_t make_provider_edges(index_router::head_ports_t head_ports, declared_providers& providers); - class edge_maker { + class phlex_core_EXPORT edge_maker { public: template edge_maker(Args&... args); diff --git a/phlex/core/filter.hpp b/phlex/core/filter.hpp index 36ccac003..b96b116a3 100644 --- a/phlex/core/filter.hpp +++ b/phlex/core/filter.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_FILTER_HPP #define PHLEX_CORE_FILTER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/detail/filter_impl.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/message.hpp" @@ -12,7 +14,7 @@ namespace phlex::experimental { oneapi::tbb::flow::composite_node, std::tuple>; - class filter : public filter_base { + class phlex_core_EXPORT filter : public filter_base { using indexer_t = oneapi::tbb::flow::indexer_node; using tag_t = indexer_t::output_type; diff --git a/phlex/core/framework_graph.hpp b/phlex/core/framework_graph.hpp index 49a1a6c04..c45f426ff 100644 --- a/phlex/core/framework_graph.hpp +++ b/phlex/core/framework_graph.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_FRAMEWORK_GRAPH_HPP #define PHLEX_CORE_FRAMEWORK_GRAPH_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_unfold.hpp" #include "phlex/core/filter.hpp" @@ -31,7 +33,7 @@ namespace phlex { } namespace phlex::experimental { - class framework_graph { + class phlex_core_EXPORT framework_graph { public: explicit framework_graph(data_cell_index_ptr index, int max_parallelism = oneapi::tbb::info::default_concurrency()); diff --git a/phlex/core/glue.hpp b/phlex/core/glue.hpp index 86d47e12d..1b8c008b2 100644 --- a/phlex/core/glue.hpp +++ b/phlex/core/glue.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_GLUE_HPP #define PHLEX_CORE_GLUE_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/registrar.hpp" @@ -23,7 +25,7 @@ namespace phlex::experimental { struct node_catalog; namespace detail { - void verify_name(std::string const& name, configuration const* config); + phlex_core_EXPORT void verify_name(std::string const& name, configuration const* config); } // ============================================================================== @@ -39,7 +41,7 @@ namespace phlex::experimental { * This object is stored as a shared pointer and its methods are bound to the created nodes. */ template - class glue { + class phlex_core_EXPORT glue { public: glue(tbb::flow::graph& g, node_catalog& nodes, diff --git a/phlex/core/index_router.hpp b/phlex/core/index_router.hpp index b15065eb4..0fbfdfd2b 100644 --- a/phlex/core/index_router.hpp +++ b/phlex/core/index_router.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_INDEX_ROUTER_HPP #define PHLEX_CORE_INDEX_ROUTER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/fwd.hpp" #include "phlex/core/message.hpp" #include "phlex/model/data_cell_counter.hpp" @@ -30,7 +32,7 @@ namespace phlex::experimental { // join operation. It: // (a) routes index messages to either the matching layer or its data-layer parent, and // (b) emits flush tokens to the repeater to evict a cached data product from memory. - class multilayer_slot { + class phlex_core_EXPORT multilayer_slot { public: multilayer_slot(tbb::flow::graph& g, identifier layer, @@ -55,7 +57,7 @@ namespace phlex::experimental { // A layer_scope object is an RAII object that manages layer-scoped operations during // data-cell-index routing. It updates flush counters on construction and ensures cleanup // (flushing end tokens and releasing fold results) on destruction. - class layer_scope { + class phlex_core_EXPORT layer_scope { public: layer_scope(flush_counters& counters, flusher_t& flusher, @@ -74,7 +76,7 @@ namespace phlex::experimental { }; } - class index_router { + class phlex_core_EXPORT index_router { public: struct named_input_port { product_query product_label; diff --git a/phlex/core/input_arguments.hpp b/phlex/core/input_arguments.hpp index c22867878..6ed74aedf 100644 --- a/phlex/core/input_arguments.hpp +++ b/phlex/core/input_arguments.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_INPUT_ARGUMENTS_HPP #define PHLEX_CORE_INPUT_ARGUMENTS_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/message.hpp" #include "phlex/core/product_query.hpp" #include "phlex/model/handle.hpp" @@ -56,8 +58,8 @@ namespace phlex::experimental { } namespace detail { - void verify_no_duplicate_input_products(std::string const& algorithm_name, - product_queries to_sort); + phlex_core_EXPORT void verify_no_duplicate_input_products(std::string const& algorithm_name, + product_queries to_sort); } template diff --git a/phlex/core/message.hpp b/phlex/core/message.hpp index bea2af04a..62f423220 100644 --- a/phlex/core/message.hpp +++ b/phlex/core/message.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_MESSAGE_HPP #define PHLEX_CORE_MESSAGE_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/fwd.hpp" #include "phlex/core/product_query.hpp" #include "phlex/model/fwd.hpp" @@ -44,7 +46,7 @@ namespace phlex::experimental { std::size_t id; }; - struct message_matcher { + struct phlex_core_EXPORT message_matcher { std::size_t operator()(message const& msg) const noexcept; }; @@ -62,13 +64,13 @@ namespace phlex::experimental { using named_index_ports = std::vector; // Overload for use with most_derived - message const& more_derived(message const& a, message const& b); + phlex_core_EXPORT message const& more_derived(message const& a, message const& b); // Non-template overload for single message case inline message const& most_derived(message const& msg) { return msg; } - std::size_t port_index_for(product_queries const& product_labels, - product_query const& product_label); + phlex_core_EXPORT std::size_t port_index_for(product_queries const& product_labels, + product_query const& product_label); } #endif // PHLEX_CORE_MESSAGE_HPP diff --git a/phlex/core/node_catalog.hpp b/phlex/core/node_catalog.hpp index 447f11d40..68051aaa5 100644 --- a/phlex/core/node_catalog.hpp +++ b/phlex/core/node_catalog.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_NODE_CATALOG_HPP #define PHLEX_CORE_NODE_CATALOG_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_observer.hpp" #include "phlex/core/declared_output.hpp" @@ -17,7 +19,7 @@ #include namespace phlex::experimental { - struct node_catalog { + struct phlex_core_EXPORT node_catalog { template auto registrar_for(std::vector& errors) { diff --git a/phlex/core/product_query.hpp b/phlex/core/product_query.hpp index dfd73bb6f..dd0f4859f 100644 --- a/phlex/core/product_query.hpp +++ b/phlex/core/product_query.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_PRODUCT_QUERY_HPP #define PHLEX_CORE_PRODUCT_QUERY_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/model/identifier.hpp" #include "phlex/model/product_specification.hpp" #include "phlex/model/type_id.hpp" @@ -63,7 +65,7 @@ namespace phlex { }; } - struct product_query { + struct phlex_core_EXPORT product_query { detail::required_creator_name creator; detail::required_layer_name layer; std::optional suffix; diff --git a/phlex/core/products_consumer.hpp b/phlex/core/products_consumer.hpp index c6ae79c04..180b6b7db 100644 --- a/phlex/core/products_consumer.hpp +++ b/phlex/core/products_consumer.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_PRODUCTS_CONSUMER_HPP #define PHLEX_CORE_PRODUCTS_CONSUMER_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/consumer.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/input_arguments.hpp" @@ -15,7 +17,7 @@ #include namespace phlex::experimental { - class products_consumer : public consumer { + class phlex_core_EXPORT products_consumer : public consumer { public: products_consumer(algorithm_name name, std::vector predicates, diff --git a/phlex/core/registrar.hpp b/phlex/core/registrar.hpp index d51fa32e6..82ae79d55 100644 --- a/phlex/core/registrar.hpp +++ b/phlex/core/registrar.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_REGISTRAR_HPP #define PHLEX_CORE_REGISTRAR_HPP +#include "phlex/phlex_core_export.hpp" + // ======================================================================================= // // The registrar class completes the registration of a node at the end of a registration @@ -58,7 +60,8 @@ namespace phlex::experimental { namespace detail { - void add_to_error_messages(std::vector& errors, std::string const& name); + phlex_core_EXPORT void add_to_error_messages(std::vector& errors, + std::string const& name); } template diff --git a/phlex/core/registration_api.hpp b/phlex/core/registration_api.hpp index ce4d8e5b4..93a7532aa 100644 --- a/phlex/core/registration_api.hpp +++ b/phlex/core/registration_api.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_REGISTRATION_API_HPP #define PHLEX_CORE_REGISTRATION_API_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/declared_fold.hpp" @@ -304,7 +306,7 @@ namespace phlex::experimental { // ==================================================================================== // Output API - class output_api { + class phlex_core_EXPORT output_api { public: output_api(registrar reg, configuration const* config, diff --git a/phlex/core/store_counters.hpp b/phlex/core/store_counters.hpp index 8363a93d8..0e97b9f56 100644 --- a/phlex/core/store_counters.hpp +++ b/phlex/core/store_counters.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CORE_STORE_COUNTERS_HPP #define PHLEX_CORE_STORE_COUNTERS_HPP +#include "phlex/phlex_core_export.hpp" + #include "phlex/core/fwd.hpp" #include "phlex/model/data_cell_counter.hpp" #include "phlex/model/data_cell_index.hpp" @@ -14,7 +16,7 @@ #include namespace phlex::experimental { - class store_counter { + class phlex_core_EXPORT store_counter { public: void set_flush_value(flush_counts_ptr counts, std::size_t original_message_id); void increment(data_cell_index::hash_type layer_hash); @@ -35,7 +37,7 @@ namespace phlex::experimental { std::atomic ready_to_flush_{true}; }; - class count_stores { + class phlex_core_EXPORT count_stores { protected: store_counter& counter_for(data_cell_index::hash_type hash); std::unique_ptr done_with(data_cell_index::hash_type hash); diff --git a/phlex/model/CMakeLists.txt b/phlex/model/CMakeLists.txt index 6b5eabf27..f75e21f7f 100644 --- a/phlex/model/CMakeLists.txt +++ b/phlex/model/CMakeLists.txt @@ -40,6 +40,16 @@ install( ) target_include_directories(phlex_model PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_model) +phlex_apply_optimizations(phlex_model) + +phlex_make_internal_library( + phlex_model + LIBRARIES + PUBLIC Boost::boost spdlog::spdlog fmt::fmt + PRIVATE phlex_utilities_internal TBB::tbb +) +add_library(phlex::model_internal ALIAS phlex_model_internal) # Interface library cet_make_library( diff --git a/phlex/model/algorithm_name.hpp b/phlex/model/algorithm_name.hpp index 139704408..778f10803 100644 --- a/phlex/model/algorithm_name.hpp +++ b/phlex/model/algorithm_name.hpp @@ -1,10 +1,12 @@ #ifndef PHLEX_MODEL_ALGORITHM_NAME_HPP #define PHLEX_MODEL_ALGORITHM_NAME_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/identifier.hpp" namespace phlex::experimental { - class algorithm_name { + class phlex_model_EXPORT algorithm_name { enum class specified_fields { neither, either, both }; public: diff --git a/phlex/model/data_cell_counter.hpp b/phlex/model/data_cell_counter.hpp index 6cbd615c1..888a7da22 100644 --- a/phlex/model/data_cell_counter.hpp +++ b/phlex/model/data_cell_counter.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_DATA_CELL_COUNTER_HPP #define PHLEX_MODEL_DATA_CELL_COUNTER_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/data_cell_index.hpp" #include "phlex/model/fwd.hpp" #include "phlex/model/identifier.hpp" @@ -12,7 +14,7 @@ #include namespace phlex::experimental { - class flush_counts { + class phlex_model_EXPORT flush_counts { public: flush_counts(); explicit flush_counts(std::map child_counts); @@ -34,7 +36,7 @@ namespace phlex::experimental { std::map child_counts_{}; }; - class data_cell_counter { + class phlex_model_EXPORT data_cell_counter { public: data_cell_counter(); data_cell_counter(data_cell_counter* parent, identifier const& layer_name); @@ -57,7 +59,7 @@ namespace phlex::experimental { std::map child_counts_{}; }; - class flush_counters { + class phlex_model_EXPORT flush_counters { public: void update(data_cell_index_ptr const id); flush_counts extract(data_cell_index_ptr const id); diff --git a/phlex/model/data_cell_index.hpp b/phlex/model/data_cell_index.hpp index d4bdc83ff..18c64325f 100644 --- a/phlex/model/data_cell_index.hpp +++ b/phlex/model/data_cell_index.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_DATA_CELL_INDEX_HPP #define PHLEX_MODEL_DATA_CELL_INDEX_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/fwd.hpp" #include "phlex/model/identifier.hpp" @@ -14,7 +16,7 @@ #include namespace phlex { - class data_cell_index : public std::enable_shared_from_this { + class phlex_model_EXPORT data_cell_index : public std::enable_shared_from_this { public: static data_cell_index const& base(); static data_cell_index_ptr base_ptr(); @@ -51,7 +53,7 @@ namespace phlex { hash_type hash_{0}; }; - std::ostream& operator<<(std::ostream& os, data_cell_index const& id); + phlex_model_EXPORT std::ostream& operator<<(std::ostream& os, data_cell_index const& id); } namespace std { diff --git a/phlex/model/data_layer_hierarchy.hpp b/phlex/model/data_layer_hierarchy.hpp index 8e03819ae..426aefd37 100644 --- a/phlex/model/data_layer_hierarchy.hpp +++ b/phlex/model/data_layer_hierarchy.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_DATA_LAYER_HIERARCHY_HPP #define PHLEX_MODEL_DATA_LAYER_HIERARCHY_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/data_cell_index.hpp" #include "phlex/model/fwd.hpp" @@ -13,7 +15,7 @@ namespace phlex::experimental { - class data_layer_hierarchy { + class phlex_model_EXPORT data_layer_hierarchy { public: ~data_layer_hierarchy(); void increment_count(data_cell_index_ptr const& id); diff --git a/phlex/model/identifier.hpp b/phlex/model/identifier.hpp index 89769117f..cc002bcb0 100644 --- a/phlex/model/identifier.hpp +++ b/phlex/model/identifier.hpp @@ -1,10 +1,14 @@ #ifndef PHLEX_MODEL_IDENTIFIER_HPP #define PHLEX_MODEL_IDENTIFIER_HPP +#include "phlex/phlex_model_export.hpp" + #include #include +#include +#include #include #include #include @@ -18,7 +22,7 @@ namespace phlex::experimental { /// Carries around the string itself (as a shared_ptr to string to make copies lighter) /// along with a precomputed hash used for all comparisons - class identifier { + class phlex_model_EXPORT identifier { public: static std::uint64_t hash_string(std::string_view str); // The default constructor is necessary so other classes containing identifiers @@ -56,8 +60,9 @@ namespace phlex::experimental { std::string const& trans_get_string() const noexcept { return content_; } // Comparison operators with _id queries - friend bool operator==(identifier const& lhs, identifier_query rhs); - friend std::strong_ordering operator<=>(identifier const& lhs, identifier_query rhs); + friend phlex_model_EXPORT bool operator==(identifier const& lhs, identifier_query rhs); + friend phlex_model_EXPORT std::strong_ordering operator<=>(identifier const& lhs, + identifier_query rhs); friend std::hash; private: @@ -67,8 +72,8 @@ namespace phlex::experimental { // Identifier UDL namespace literals { - identifier operator""_id(char const* lit, std::size_t len); - identifier_query operator""_idq(char const* lit, std::size_t len); + phlex_model_EXPORT identifier operator""_id(char const* lit, std::size_t len); + phlex_model_EXPORT identifier_query operator""_idq(char const* lit, std::size_t len); } // Really trying to avoid the extra function call here diff --git a/phlex/model/product_matcher.hpp b/phlex/model/product_matcher.hpp index 632273f06..e6f13bdef 100644 --- a/phlex/model/product_matcher.hpp +++ b/phlex/model/product_matcher.hpp @@ -9,13 +9,15 @@ // // ======================================================================================= +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/fwd.hpp" #include #include namespace phlex::experimental { - class product_matcher { + class phlex_model_EXPORT product_matcher { public: explicit product_matcher(std::string matcher_spec); bool matches(product_store_const_ptr const& store) const; diff --git a/phlex/model/product_specification.hpp b/phlex/model/product_specification.hpp index 5167f4741..35de9f0d6 100644 --- a/phlex/model/product_specification.hpp +++ b/phlex/model/product_specification.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_PRODUCT_SPECIFICATION_HPP #define PHLEX_MODEL_PRODUCT_SPECIFICATION_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/algorithm_name.hpp" #include "phlex/model/identifier.hpp" #include "phlex/model/type_id.hpp" @@ -12,7 +14,7 @@ #include namespace phlex::experimental { - class product_specification { + class phlex_model_EXPORT product_specification { public: product_specification(); product_specification(char const* name); @@ -44,9 +46,10 @@ namespace phlex::experimental { using product_specifications = std::vector; - product_specifications to_product_specifications(std::string_view name, - std::vector output_labels, - std::vector output_types); + phlex_model_EXPORT product_specifications + to_product_specifications(std::string_view name, + std::vector output_labels, + std::vector output_types); } template <> diff --git a/phlex/model/product_store.hpp b/phlex/model/product_store.hpp index 23199001e..bbe29bc85 100644 --- a/phlex/model/product_store.hpp +++ b/phlex/model/product_store.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_PRODUCT_STORE_HPP #define PHLEX_MODEL_PRODUCT_STORE_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/algorithm_name.hpp" #include "phlex/model/data_cell_index.hpp" #include "phlex/model/fwd.hpp" @@ -15,7 +17,7 @@ #include namespace phlex::experimental { - class product_store { + class phlex_model_EXPORT product_store { public: explicit product_store(data_cell_index_ptr id, algorithm_name source = default_source(), @@ -58,7 +60,8 @@ namespace phlex::experimental { source_; // FIXME: Should not have to copy (the source should outlive the product store) }; - product_store_ptr const& more_derived(product_store_ptr const& a, product_store_ptr const& b); + phlex_model_EXPORT product_store_ptr const& more_derived(product_store_ptr const& a, + product_store_ptr const& b); // Non-template overload for single product_store_ptr case inline product_store_ptr const& most_derived(product_store_ptr const& store) { return store; } diff --git a/phlex/model/products.hpp b/phlex/model/products.hpp index d4ca44d93..60601423c 100644 --- a/phlex/model/products.hpp +++ b/phlex/model/products.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_MODEL_PRODUCTS_HPP #define PHLEX_MODEL_PRODUCTS_HPP +#include "phlex/phlex_model_export.hpp" + #include "phlex/model/product_specification.hpp" #include @@ -12,7 +14,7 @@ namespace phlex::experimental { - struct product_base { + struct phlex_model_EXPORT product_base { virtual ~product_base() = default; virtual void const* address() const = 0; virtual std::type_info const& type() const = 0; @@ -32,7 +34,7 @@ namespace phlex::experimental { std::remove_cvref_t obj; }; - class products { + class phlex_model_EXPORT products { using collection_t = std::unordered_map>; public: diff --git a/phlex/utilities/CMakeLists.txt b/phlex/utilities/CMakeLists.txt index cc6c0228d..5edf24c7b 100644 --- a/phlex/utilities/CMakeLists.txt +++ b/phlex/utilities/CMakeLists.txt @@ -27,6 +27,16 @@ install( ) target_include_directories(phlex_utilities PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_utilities) +phlex_apply_optimizations(phlex_utilities) + +phlex_make_internal_library( + phlex_utilities + LIBRARIES + PRIVATE Boost::boost + PUBLIC spdlog::spdlog +) +add_library(phlex::utilities_internal ALIAS phlex_utilities_internal) # Interface library cet_make_library( diff --git a/phlex/utilities/hashing.hpp b/phlex/utilities/hashing.hpp index 04b6c0455..f521654ae 100644 --- a/phlex/utilities/hashing.hpp +++ b/phlex/utilities/hashing.hpp @@ -1,14 +1,17 @@ #ifndef PHLEX_UTILITIES_HASHING_HPP #define PHLEX_UTILITIES_HASHING_HPP +#include "phlex/phlex_utilities_export.hpp" + +#include #include #include namespace phlex::experimental { - std::size_t hash(std::string const& str); - std::size_t hash(std::size_t i) noexcept; - std::size_t hash(std::size_t i, std::size_t j); - std::size_t hash(std::size_t i, std::string const& str); + phlex_utilities_EXPORT std::size_t hash(std::string const& str); + phlex_utilities_EXPORT std::size_t hash(std::size_t i) noexcept; + phlex_utilities_EXPORT std::size_t hash(std::size_t i, std::size_t j); + phlex_utilities_EXPORT std::size_t hash(std::size_t i, std::string const& str); template std::size_t hash(std::size_t i, std::size_t j, Ts... ks) { diff --git a/phlex/utilities/resource_usage.hpp b/phlex/utilities/resource_usage.hpp index f79f4b4c6..d7b4e5b71 100644 --- a/phlex/utilities/resource_usage.hpp +++ b/phlex/utilities/resource_usage.hpp @@ -6,10 +6,12 @@ // resource_usage object. The destructor will also report the maximum RSS of the process. // ======================================================================================= +#include "phlex/phlex_utilities_export.hpp" + #include namespace phlex::experimental { - class resource_usage { + class phlex_utilities_EXPORT resource_usage { public: resource_usage() noexcept; ~resource_usage(); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 63a32a9e5..8f14921e9 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -8,6 +8,20 @@ target_link_libraries(layer_generator PRIVATE phlex::core) install(TARGETS layer_generator LIBRARY) +# Companion library for tests. +# PHLEX_HIDE_SYMBOLS=ON: separate compile against phlex_core_internal so that +# tests linking it do not mix the visibility-hidden and all-visible variants +# of phlex_core in the same process. +# PHLEX_HIDE_SYMBOLS=OFF: thin INTERFACE alias — layer_generator already +# exports all symbols, so no separate .so is needed. +if(PHLEX_HIDE_SYMBOLS) + add_library(layer_generator_internal layer_generator.cpp) + target_link_libraries(layer_generator_internal PRIVATE phlex_core_internal) +else() + add_library(layer_generator_internal INTERFACE) + target_link_libraries(layer_generator_internal INTERFACE layer_generator) +endif() + add_library(generate_layers MODULE generate_layers.cpp) target_link_libraries(generate_layers PRIVATE phlex::module layer_generator) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b1a29f020..10e308867 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,24 +5,24 @@ include(CetTest) cet_test_env(SPDLOG_LEVEL=debug) -cet_test(concepts SOURCE concepts.cpp LIBRARIES phlex::core) +cet_test(concepts SOURCE concepts.cpp LIBRARIES phlex::core_internal) cet_test( adjust_config USE_CATCH2_MAIN SOURCE adjust_config.cpp LIBRARIES - run_phlex + run_phlex_internal Boost::json ) cet_test(config_test USE_CATCH2_MAIN SOURCE configuration.cpp LIBRARIES phlex::configuration ) -cet_test(string_literal SOURCE string_literal.cpp LIBRARIES phlex::utilities) +cet_test(string_literal SOURCE string_literal.cpp LIBRARIES phlex::utilities_internal) cet_test(type_deduction SOURCE type_deduction.cpp LIBRARIES phlex::metaprogramming ) -cet_test(type_id USE_CATCH2_MAIN SOURCE type_id.cpp LIBRARIES phlex::model fmt::fmt) +cet_test(type_id USE_CATCH2_MAIN SOURCE type_id.cpp LIBRARIES phlex::model_internal fmt::fmt) cet_test(identifier USE_CATCH2_MAIN SOURCE identifier.cpp LIBRARIES phlex::model phlex::configuration Boost::json) cet_test( yielding_driver @@ -30,7 +30,7 @@ cet_test( SOURCE yielding_driver.cpp LIBRARIES - phlex::core + phlex::core_internal TBB::tbb ) @@ -40,9 +40,9 @@ cet_test( SOURCE allowed_families.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json - layer_generator + layer_generator_internal ) cet_test( vector_of_abstract_types @@ -50,8 +50,8 @@ cet_test( SOURCE vector_of_abstract_types.cpp LIBRARIES - phlex::core - layer_generator + phlex::core_internal + layer_generator_internal ) cet_test( cached_execution @@ -59,9 +59,9 @@ cet_test( SOURCE cached_execution.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json - layer_generator + layer_generator_internal ) cet_test( class_registration @@ -69,7 +69,7 @@ cet_test( SOURCE class_registration.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json ) cet_test( @@ -78,12 +78,12 @@ cet_test( SOURCE different_hierarchies.cpp LIBRARIES - phlex::core + phlex::core_internal spdlog::spdlog - layer_generator + layer_generator_internal ) cet_test(filter_impl USE_CATCH2_MAIN SOURCE filter_impl.cpp LIBRARIES - phlex::core + phlex::core_internal ) cet_test( filter @@ -91,7 +91,7 @@ cet_test( SOURCE filter.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json ) cet_test( @@ -100,9 +100,9 @@ cet_test( SOURCE framework_graph.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json - layer_generator + layer_generator_internal ) cet_test( function_registration @@ -110,7 +110,7 @@ cet_test( SOURCE function_registration.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json ) cet_test( @@ -121,9 +121,9 @@ cet_test( LIBRARIES Boost::json TBB::tbb - phlex::core + phlex::core_internal spdlog::spdlog - layer_generator + layer_generator_internal ) cet_test( layer_generator_test @@ -131,8 +131,8 @@ cet_test( SOURCE layer_generator.cpp LIBRARIES - phlex::core - layer_generator + phlex::core_internal + layer_generator_internal ) cet_test( multiple_function_registration @@ -141,13 +141,13 @@ cet_test( multiple_function_registration.cpp LIBRARIES Boost::json - phlex::core + phlex::core_internal ) cet_test( output_products USE_CATCH2_MAIN SOURCE output_products.cpp - LIBRARIES layer_generator phlex::core spdlog::spdlog + LIBRARIES layer_generator_internal phlex::core_internal spdlog::spdlog ) cet_test( data_cell_counting @@ -155,20 +155,20 @@ cet_test( SOURCE data_cell_counting.cpp LIBRARIES - phlex::model - phlex::utilities + phlex::model_internal + phlex::utilities_internal ) cet_test(data_cell_index USE_CATCH2_MAIN SOURCE data_cell_index.cpp LIBRARIES - phlex::model + phlex::model_internal ) cet_test(product_handle USE_CATCH2_MAIN SOURCE product_handle.cpp LIBRARIES - phlex::core + phlex::core_internal ) cet_test(product_matcher USE_CATCH2_MAIN SOURCE product_matcher.cpp LIBRARIES - phlex::model + phlex::model_internal ) cet_test(product_store USE_CATCH2_MAIN SOURCE product_store.cpp LIBRARIES - phlex::core + phlex::core_internal ) cet_test( fold @@ -176,9 +176,9 @@ cet_test( SOURCE fold.cpp LIBRARIES - phlex::core + phlex::core_internal spdlog::spdlog - layer_generator + layer_generator_internal ) cet_test( repeater_node @@ -186,7 +186,7 @@ cet_test( SOURCE repeater_node_test.cpp LIBRARIES - phlex::core + phlex::core_internal ) cet_test( replicated @@ -195,15 +195,15 @@ cet_test( replicated.cpp LIBRARIES TBB::tbb - phlex::utilities + phlex::utilities_internal spdlog::spdlog ) cet_test(product_query USE_CATCH2_MAIN SOURCE product_query.cpp LIBRARIES - phlex::core + phlex::core_internal ) cet_test(core_misc_test USE_CATCH2_MAIN SOURCE core_misc_test.cpp LIBRARIES - phlex::core + phlex::core_internal Boost::json ) cet_test( @@ -212,8 +212,8 @@ cet_test( SOURCE provider_test.cpp LIBRARIES - phlex::core - layer_generator + phlex::core_internal + layer_generator_internal ) cet_test( type_distinction @@ -222,7 +222,7 @@ cet_test( type_distinction.cpp LIBRARIES spdlog::spdlog - phlex::core + phlex::core_internal ) cet_test( unfold @@ -231,10 +231,10 @@ cet_test( unfold.cpp LIBRARIES Boost::json - phlex::core + phlex::core_internal TBB::tbb spdlog::spdlog - layer_generator + layer_generator_internal ) add_subdirectory(benchmarks) diff --git a/test/python/all_config.py b/test/python/all_config.py index aeee3b373..0a4c16310 100644 --- a/test/python/all_config.py +++ b/test/python/all_config.py @@ -49,9 +49,9 @@ def __init__(self, config): assert len(config["some_objects"]) == 3 expected = [ - {'a': 'b', 'c': 'd', 'e': 'f'}, - {'g': 'h', 'i': 'j', 'k': 'l'}, - {'m': 'n', 'o': 'p', 'q': 'r'}, + {"a": "b", "c": "d", "e": "f"}, + {"g": "h", "i": "j", "k": "l"}, + {"m": "n", "o": "p", "q": "r"}, ] for i in range(3): assert config["some_objects"][i] == expected[i] @@ -60,10 +60,10 @@ def __init__(self, config): assert config["empty"] == () try: - config[42] # should raise + config[42] # should raise assert not "did not raise TypeError" except TypeError: - pass # all good as exception was raised + pass # all good as exception was raised def __call__(self, i: int, j: int) -> None: """Dummy routine to do something. diff --git a/test/python/reducer.py b/test/python/reducer.py index b32fe0395..75b283e6d 100644 --- a/test/python/reducer.py +++ b/test/python/reducer.py @@ -74,17 +74,13 @@ def PHLEX_REGISTER_ALGORITHMS(m, config): {"creator": "reduce0", "layer": "event", "suffix": "sum0"}, {"creator": "reduce1", "layer": "event", "suffix": "sum1"}, ] - m.transform( - add_sum01, name="reduce01", input_family=input_family01, output_products=["sum01"] - ) + m.transform(add_sum01, name="reduce01", input_family=input_family01, output_products=["sum01"]) input_family01 = [ {"creator": "reduce2", "layer": "event", "suffix": "sum2"}, {"creator": "reduce3", "layer": "event", "suffix": "sum3"}, ] - m.transform( - add_sum23, name="reduce23", input_family=input_family01, output_products=["sum23"] - ) + m.transform(add_sum23, name="reduce23", input_family=input_family01, output_products=["sum23"]) # once more (and the configuration will add a verifier) input_family_final = [ diff --git a/test/python/sumit.py b/test/python/sumit.py index 17eaef93c..ae43e5ffc 100644 --- a/test/python/sumit.py +++ b/test/python/sumit.py @@ -63,8 +63,8 @@ def PHLEX_REGISTER_ALGORITHMS(m, config): None """ m.transform(collectify, input_family=config["input"], output_products=["my_pyarray"]) - m.transform(sum_array, - input_family=[ - {"creator" : "collectify", "layer" : "event", "suffix" : "my_pyarray"} - ], - output_products=config["output"]) + m.transform( + sum_array, + input_family=[{"creator": "collectify", "layer": "event", "suffix": "my_pyarray"}], + output_products=config["output"], + ) diff --git a/test/python/test_coverage.py b/test/python/test_coverage.py index 33f82d33b..52c844d89 100644 --- a/test/python/test_coverage.py +++ b/test/python/test_coverage.py @@ -42,13 +42,14 @@ def PHLEX_REGISTER_ALGORITHMS(m, config): """Register algorithms.""" # We need to transform scalar inputs to lists first # i, f1, d1 come from cppsource4py - tfs = ((collect_int, "input", "i", "l_int"), - (collect_float, "input", "f1", "l_float"), - (collect_double, "input", "d1", "l_double"), - (list_int_func, collect_int.__name__, "l_int", "sum_int"), - (list_float_func, collect_float.__name__, "l_float", "sum_float"), - (list_double_func, collect_double.__name__, "l_double", "sum_double") - ) + tfs = ( + (collect_int, "input", "i", "l_int"), + (collect_float, "input", "f1", "l_float"), + (collect_double, "input", "d1", "l_double"), + (list_int_func, collect_int.__name__, "l_int", "sum_int"), + (list_float_func, collect_float.__name__, "l_float", "sum_float"), + (list_double_func, collect_double.__name__, "l_double", "sum_double"), + ) for func, creator, suffix, output in tfs: input_family = [{"creator": creator, "layer": "event", "suffix": suffix}] diff --git a/test/python/test_mismatch.py b/test/python/test_mismatch.py index 2d188496c..55eca0e7c 100644 --- a/test/python/test_mismatch.py +++ b/test/python/test_mismatch.py @@ -10,6 +10,8 @@ def PHLEX_REGISTER_ALGORITHMS(m, config): """Register algorithms.""" # input_family has 1 element, but function takes 2 arguments # This should trigger the error in modulewrap.cpp - m.transform(mismatch_func, - input_family=[{"creator": "input", "layer": "event", "suffix": "a"}], - output_products=["sum"]) + m.transform( + mismatch_func, + input_family=[{"creator": "input", "layer": "event", "suffix": "a"}], + output_products=["sum"], + ) diff --git a/test/python/vectypes.py b/test/python/vectypes.py index de182aabb..5cd464920 100644 --- a/test/python/vectypes.py +++ b/test/python/vectypes.py @@ -259,11 +259,13 @@ def PHLEX_REGISTER_ALGORITHMS(m, config): ) sum_kwargs = { - "input_family": [{ - "creator": list_collect.__name__ if use_lists else arr_collect.__name__, - "layer": "event", - "suffix": arr_name - }], + "input_family": [ + { + "creator": list_collect.__name__ if use_lists else arr_collect.__name__, + "layer": "event", + "suffix": arr_name, + } + ], "output_products": config[out_key], } if sum_name: diff --git a/test/utilities/CMakeLists.txt b/test/utilities/CMakeLists.txt index 9cfd780a0..9ace0e04e 100644 --- a/test/utilities/CMakeLists.txt +++ b/test/utilities/CMakeLists.txt @@ -1,7 +1,7 @@ -cet_test(sized_tuple SOURCE sized_tuple.cpp LIBRARIES phlex::utilities) +cet_test(sized_tuple SOURCE sized_tuple.cpp LIBRARIES phlex::utilities_internal) cet_test(sleep_for USE_CATCH2_MAIN SOURCE sleep_for.cpp LIBRARIES - phlex::utilities + phlex::utilities_internal ) cet_test( thread_counter @@ -9,6 +9,6 @@ cet_test( SOURCE thread_counter.cpp LIBRARIES - phlex::utilities + phlex::utilities_internal TBB::tbb )