From b0bc4cbaa1a12a291cd8f6294ac1eaec6279b4cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:52:29 +0000 Subject: [PATCH 01/22] Add symbol visibility armoring to all shared libraries (de novo on main) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create PhlexSymbolVisibility.cmake with phlex_apply_symbol_visibility() that generates export headers into centralized ${PROJECT_BINARY_DIR}/include, sets CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON, and installs the headers for downstream consumers. Apply phlex_apply_symbol_visibility() to all 5 shared libraries: phlex_utilities, phlex_model, phlex_core, phlex_configuration_internal, run_phlex. Annotate ~45 headers across the whole phlex namespace (including phlex::experimental) with export macros — every non-template class and free function with a .cpp implementation. Also add missing includes flagged by misc-include-cleaner: - and to identifier.hpp - to hashing.hpp - to load_module.hpp Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- CMakeLists.txt | 1 + Modules/private/PhlexSymbolVisibility.cmake | 26 +++++++++++++++++++++ phlex/CMakeLists.txt | 1 + phlex/app/CMakeLists.txt | 1 + phlex/app/load_module.hpp | 16 +++++++++---- phlex/app/run.hpp | 4 +++- phlex/app/version.hpp | 4 +++- phlex/concurrency.hpp | 4 +++- phlex/configuration.hpp | 8 ++++--- phlex/core/CMakeLists.txt | 1 + phlex/core/consumer.hpp | 4 +++- phlex/core/declared_fold.hpp | 4 +++- phlex/core/declared_observer.hpp | 4 +++- phlex/core/declared_output.hpp | 4 +++- phlex/core/declared_predicate.hpp | 4 +++- phlex/core/declared_provider.hpp | 4 +++- phlex/core/declared_transform.hpp | 4 +++- phlex/core/declared_unfold.hpp | 6 +++-- phlex/core/detail/filter_impl.hpp | 6 +++-- phlex/core/detail/make_algorithm_name.hpp | 4 +++- phlex/core/detail/maybe_predicates.hpp | 4 +++- phlex/core/detail/repeater_node.hpp | 4 +++- phlex/core/edge_creation_policy.hpp | 4 +++- phlex/core/edge_maker.hpp | 4 +++- phlex/core/filter.hpp | 4 +++- phlex/core/framework_graph.hpp | 4 +++- phlex/core/glue.hpp | 4 +++- phlex/core/index_router.hpp | 8 ++++--- phlex/core/input_arguments.hpp | 4 +++- phlex/core/message.hpp | 4 +++- phlex/core/node_catalog.hpp | 4 +++- phlex/core/product_query.hpp | 4 +++- phlex/core/products_consumer.hpp | 4 +++- phlex/core/registrar.hpp | 4 +++- phlex/core/registration_api.hpp | 2 ++ phlex/core/store_counters.hpp | 6 +++-- phlex/model/CMakeLists.txt | 1 + phlex/model/algorithm_name.hpp | 4 +++- phlex/model/data_cell_counter.hpp | 8 ++++--- phlex/model/data_cell_index.hpp | 6 +++-- phlex/model/data_layer_hierarchy.hpp | 4 +++- phlex/model/identifier.hpp | 10 +++++--- phlex/model/product_matcher.hpp | 4 +++- phlex/model/product_specification.hpp | 4 +++- phlex/model/product_store.hpp | 4 +++- phlex/model/products.hpp | 6 +++-- phlex/utilities/CMakeLists.txt | 1 + phlex/utilities/hashing.hpp | 11 +++++---- phlex/utilities/resource_usage.hpp | 4 +++- 49 files changed, 185 insertions(+), 60 deletions(-) create mode 100644 Modules/private/PhlexSymbolVisibility.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index dad564236..c67482ad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ 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) option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) option(ENABLE_ASAN "Enable Address Sanitizer" OFF) diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake new file mode 100644 index 000000000..d376b9f25 --- /dev/null +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -0,0 +1,26 @@ +include(GenerateExportHeader) + +function(phlex_apply_symbol_visibility target) + set(EXPORT_HEADER "${PROJECT_BINARY_DIR}/include/${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" + ) + + set_target_properties( + ${target} + PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON + ) + + target_include_directories( + ${target} + PUBLIC $ $ + ) + + install(FILES "${EXPORT_HEADER}" DESTINATION include) +endfunction() diff --git a/phlex/CMakeLists.txt b/phlex/CMakeLists.txt index f208a812a..e81b70028 100644 --- a/phlex/CMakeLists.txt +++ b/phlex/CMakeLists.txt @@ -33,6 +33,7 @@ cet_make_library( Boost::json phlex::core ) +phlex_apply_symbol_visibility(phlex_configuration_internal) cet_make_library( LIBRARY_NAME diff --git a/phlex/app/CMakeLists.txt b/phlex/app/CMakeLists.txt index 3c0a57af0..8ab21ed04 100644 --- a/phlex/app/CMakeLists.txt +++ b/phlex/app/CMakeLists.txt @@ -18,6 +18,7 @@ cet_make_library( ) install(FILES load_module.hpp run.hpp version.hpp DESTINATION include/phlex/app) +phlex_apply_symbol_visibility(run_phlex) # We'll use C++17's filesystem instead of Boost's target_compile_definitions(run_phlex PRIVATE BOOST_DLL_USE_STD_FS) diff --git a/phlex/app/load_module.hpp b/phlex/app/load_module.hpp index 14d3ba1f4..4b7f44a8a 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 "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..c275ebcbe 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 "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..e7be449f9 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 "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..328ec2982 100644 --- a/phlex/concurrency.hpp +++ b/phlex/concurrency.hpp @@ -1,10 +1,12 @@ #ifndef PHLEX_CONCURRENCY_HPP #define PHLEX_CONCURRENCY_HPP +#include "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..ebae0f69a 100644 --- a/phlex/configuration.hpp +++ b/phlex/configuration.hpp @@ -1,6 +1,8 @@ #ifndef PHLEX_CONFIGURATION_HPP #define PHLEX_CONFIGURATION_HPP +#include "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} {} diff --git a/phlex/core/CMakeLists.txt b/phlex/core/CMakeLists.txt index 36fd293a3..a98e0589c 100644 --- a/phlex/core/CMakeLists.txt +++ b/phlex/core/CMakeLists.txt @@ -81,6 +81,7 @@ install( DESTINATION include/phlex/core/detail ) target_include_directories(phlex_core PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_core) # AppleClang 15.0 still treats std::views::join as experimental if( diff --git a/phlex/core/consumer.hpp b/phlex/core/consumer.hpp index fbd38b055..aa0c2b5a6 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_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..170ccf571 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_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..d41ff6ecb 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_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..479d99425 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_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..0d94968d2 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_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..5fed93a75 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_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..bd9e99817 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_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..e23051784 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_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..fe932f65e 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_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..2021ffef5 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_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,7 @@ 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..5248de7e1 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_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,7 @@ 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..e7ec113cc 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_core_export.hpp" + #include "phlex/core/message.hpp" #include "oneapi/tbb/concurrent_hash_map.h" @@ -15,7 +17,7 @@ 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..ff31fd104 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_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..5cbdff0e5 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_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..e1af1ad3b 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_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..3741b0dcf 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_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..e842136eb 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_core_export.hpp" + #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/registrar.hpp" @@ -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..5d8ecb643 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_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..8de94af4e 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_core_export.hpp" + #include "phlex/core/message.hpp" #include "phlex/core/product_query.hpp" #include "phlex/model/handle.hpp" @@ -56,7 +58,7 @@ namespace phlex::experimental { } namespace detail { - void verify_no_duplicate_input_products(std::string const& algorithm_name, + phlex_core_EXPORT void verify_no_duplicate_input_products(std::string const& algorithm_name, product_queries to_sort); } diff --git a/phlex/core/message.hpp b/phlex/core/message.hpp index bea2af04a..7bd5028ad 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_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; }; diff --git a/phlex/core/node_catalog.hpp b/phlex/core/node_catalog.hpp index 447f11d40..dc306db93 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_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..1274391c9 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_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..e8172fa2d 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_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..46bf5f5b7 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_core_export.hpp" + // ======================================================================================= // // The registrar class completes the registration of a node at the end of a registration @@ -58,7 +60,7 @@ 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..d52773488 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_core_export.hpp" + #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/declared_fold.hpp" diff --git a/phlex/core/store_counters.hpp b/phlex/core/store_counters.hpp index 8363a93d8..6750e92f5 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_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..5c0a6dcc9 100644 --- a/phlex/model/CMakeLists.txt +++ b/phlex/model/CMakeLists.txt @@ -40,6 +40,7 @@ install( ) target_include_directories(phlex_model PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_model) # Interface library cet_make_library( diff --git a/phlex/model/algorithm_name.hpp b/phlex/model/algorithm_name.hpp index 139704408..570896f88 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_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..0495bb46e 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_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..2bd0906be 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_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..7e19cce99 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_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..e8cd0c3af 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_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 @@ -67,8 +71,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..2ca5a55e0 100644 --- a/phlex/model/product_matcher.hpp +++ b/phlex/model/product_matcher.hpp @@ -9,13 +9,15 @@ // // ======================================================================================= +#include "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..40af34a7b 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_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); diff --git a/phlex/model/product_store.hpp b/phlex/model/product_store.hpp index 23199001e..aaeca101e 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_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(), diff --git a/phlex/model/products.hpp b/phlex/model/products.hpp index d4ca44d93..1b0129978 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_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..91438d2d4 100644 --- a/phlex/utilities/CMakeLists.txt +++ b/phlex/utilities/CMakeLists.txt @@ -27,6 +27,7 @@ install( ) target_include_directories(phlex_utilities PRIVATE ${PROJECT_SOURCE_DIR}) +phlex_apply_symbol_visibility(phlex_utilities) # Interface library cet_make_library( diff --git a/phlex/utilities/hashing.hpp b/phlex/utilities/hashing.hpp index 04b6c0455..e8857038c 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_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..4a5cfab48 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_utilities_export.hpp" + #include namespace phlex::experimental { - class resource_usage { + class phlex_utilities_EXPORT resource_usage { public: resource_usage() noexcept; ~resource_usage(); From 826d5af9498ef69aa952b447b80832ae6fdca153 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:07:25 +0000 Subject: [PATCH 02/22] Apply ruff fixes --- test/python/all_config.py | 10 +++++----- test/python/reducer.py | 8 ++------ test/python/sumit.py | 10 +++++----- test/python/test_coverage.py | 15 ++++++++------- test/python/test_mismatch.py | 8 +++++--- test/python/vectypes.py | 12 +++++++----- 6 files changed, 32 insertions(+), 31 deletions(-) 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: From 8a09630b6ff04b17244bd10cc580234a76dfaaeb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:07:31 +0000 Subject: [PATCH 03/22] Apply clang-format fixes --- phlex/configuration.hpp | 4 ++-- phlex/core/detail/make_algorithm_name.hpp | 3 ++- phlex/core/detail/maybe_predicates.hpp | 3 ++- phlex/core/detail/repeater_node.hpp | 3 ++- phlex/core/input_arguments.hpp | 2 +- phlex/core/registrar.hpp | 3 ++- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/phlex/configuration.hpp b/phlex/configuration.hpp index ebae0f69a..f1c2df54a 100644 --- a/phlex/configuration.hpp +++ b/phlex/configuration.hpp @@ -24,8 +24,8 @@ namespace phlex { } // Used later for product_query - phlex_configuration_internal_EXPORT 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 diff --git a/phlex/core/detail/make_algorithm_name.hpp b/phlex/core/detail/make_algorithm_name.hpp index 2021ffef5..d7eb1b467 100644 --- a/phlex/core/detail/make_algorithm_name.hpp +++ b/phlex/core/detail/make_algorithm_name.hpp @@ -16,7 +16,8 @@ namespace phlex::experimental { class algorithm_name; namespace detail { - phlex_core_EXPORT 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 5248de7e1..3d74c662b 100644 --- a/phlex/core/detail/maybe_predicates.hpp +++ b/phlex/core/detail/maybe_predicates.hpp @@ -15,7 +15,8 @@ namespace phlex { } namespace phlex::experimental::detail { - phlex_core_EXPORT 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 e7ec113cc..a0983994b 100644 --- a/phlex/core/detail/repeater_node.hpp +++ b/phlex/core/detail/repeater_node.hpp @@ -17,7 +17,8 @@ namespace phlex::experimental::detail { using repeater_node_input = std::tuple; - class phlex_core_EXPORT 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/input_arguments.hpp b/phlex/core/input_arguments.hpp index 8de94af4e..666613261 100644 --- a/phlex/core/input_arguments.hpp +++ b/phlex/core/input_arguments.hpp @@ -59,7 +59,7 @@ namespace phlex::experimental { namespace detail { phlex_core_EXPORT void verify_no_duplicate_input_products(std::string const& algorithm_name, - product_queries to_sort); + product_queries to_sort); } template diff --git a/phlex/core/registrar.hpp b/phlex/core/registrar.hpp index 46bf5f5b7..9e41a8cc1 100644 --- a/phlex/core/registrar.hpp +++ b/phlex/core/registrar.hpp @@ -60,7 +60,8 @@ namespace phlex::experimental { namespace detail { - phlex_core_EXPORT 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 From dff7b8a7eda7944355cace27baa6365af95cab74 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:07:27 +0000 Subject: [PATCH 04/22] Apply YAML formatter fixes --- .github/workflows/clang-format-fix.yaml | 15 ++++++++------- .github/workflows/clang-tidy-fix.yaml | 4 +++- .github/workflows/cmake-format-fix.yaml | 15 ++++++++------- .github/workflows/codeql-analysis.yaml | 8 +------- .github/workflows/header-guards-fix.yaml | 15 ++++++++------- .github/workflows/jsonnet-format-fix.yaml | 15 ++++++++------- .github/workflows/markdown-fix.yaml | 15 ++++++++------- .github/workflows/python-fix.yaml | 15 ++++++++------- .github/workflows/yaml-fix.yaml | 15 ++++++++------- 9 files changed, 60 insertions(+), 57 deletions(-) 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 From ac59b9668d27349e207ad98aea359fcb306470e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:27:18 +0000 Subject: [PATCH 05/22] Export tag_invoke customization points in configuration.hpp The Boost.JSON customization point overloads for configuration, product_query, and experimental::identifier were hidden by the visibility policy, causing config_test link failure: undefined reference to phlex::tag_invoke(boost::json::value_to_tag...) phlex::tag_invoke(boost::json::value_to_tag...) These are public API symbols (they back value_to() for JSON deserialization) that were missed in the initial visibility sweep. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- phlex/configuration.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/phlex/configuration.hpp b/phlex/configuration.hpp index f1c2df54a..7346a5983 100644 --- a/phlex/configuration.hpp +++ b/phlex/configuration.hpp @@ -91,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 From df6cf3ea05cf367b5063241821ebf0f1c7540eab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:46:46 +0000 Subject: [PATCH 06/22] Export missing symbols causing undefined-reference link failures Three non-template free functions had .cpp implementations but were missing export macros, causing linker failures in test executables: - phlex_model_EXPORT on friend operator== / operator<=> for identifier_query in identifier.hpp (called from identifier test) - phlex_core_EXPORT on detail::verify_name in glue.hpp (called from template instantiations of glue::provide/observe/transform/...) - phlex_core_EXPORT on port_index_for and more_derived in message.hpp (called from template instantiations in observer_node et al.) Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- phlex/core/glue.hpp | 2 +- phlex/core/message.hpp | 6 +++--- phlex/model/identifier.hpp | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/phlex/core/glue.hpp b/phlex/core/glue.hpp index e842136eb..c03298c4e 100644 --- a/phlex/core/glue.hpp +++ b/phlex/core/glue.hpp @@ -25,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); } // ============================================================================== diff --git a/phlex/core/message.hpp b/phlex/core/message.hpp index 7bd5028ad..506850603 100644 --- a/phlex/core/message.hpp +++ b/phlex/core/message.hpp @@ -64,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/model/identifier.hpp b/phlex/model/identifier.hpp index e8cd0c3af..7f9e3267b 100644 --- a/phlex/model/identifier.hpp +++ b/phlex/model/identifier.hpp @@ -60,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: From 356a737d694a4341034026b48058923eb2292619 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:13:54 +0000 Subject: [PATCH 07/22] Export to_product_specifications, output_api, and product_store::more_derived Three more non-template symbols with .cpp implementations were missing export macros, causing linker failures across most test executables: - phlex_model_EXPORT on to_product_specifications() in product_specification.hpp (called from declared_transform.hpp and declared_fold.hpp template instantiations in every test binary) - phlex_core_EXPORT on output_api class in registration_api.hpp (constructor called from glue::output template instantiations) - phlex_model_EXPORT on more_derived(product_store_ptr, product_store_ptr) in product_store.hpp (distinct from the message::more_derived fixed earlier; called directly from product_store test and from template get_most_derived) Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- phlex/core/registration_api.hpp | 2 +- phlex/model/product_specification.hpp | 6 +++--- phlex/model/product_store.hpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/phlex/core/registration_api.hpp b/phlex/core/registration_api.hpp index d52773488..893b04a24 100644 --- a/phlex/core/registration_api.hpp +++ b/phlex/core/registration_api.hpp @@ -306,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/model/product_specification.hpp b/phlex/model/product_specification.hpp index 40af34a7b..25481f54c 100644 --- a/phlex/model/product_specification.hpp +++ b/phlex/model/product_specification.hpp @@ -46,9 +46,9 @@ 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 aaeca101e..19f5f24b6 100644 --- a/phlex/model/product_store.hpp +++ b/phlex/model/product_store.hpp @@ -60,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; } From 1f413c1b6e1c73183741da8b70f3654e88be54a5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:27:38 +0000 Subject: [PATCH 08/22] Apply clang-format fixes --- phlex/model/product_specification.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/phlex/model/product_specification.hpp b/phlex/model/product_specification.hpp index 25481f54c..a2b82897f 100644 --- a/phlex/model/product_specification.hpp +++ b/phlex/model/product_specification.hpp @@ -46,9 +46,10 @@ namespace phlex::experimental { using product_specifications = std::vector; - phlex_model_EXPORT 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 <> From 3598df27f750d5c7dec47479236c0246e56a7570 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:13:28 +0000 Subject: [PATCH 09/22] Add _internal companion libraries for test access and size/timing comparison Introduce phlex_make_internal_library(target LIBRARIES ...) in PhlexSymbolVisibility.cmake. The function: - reads SOURCES from the already-defined public target (no duplication) - handles generated sources (configure_file output) via src/bin dir fallback - creates ${target}_internal SHARED using add_library (not cet_make_library) so cetmodules never registers it for installation or package export - propagates $ PUBLIC so consumers such as layer_generator_internal can resolve phlex/* headers - propagates COMPILE_DEFINITIONS and COMPILE_OPTIONS from the public target - omits CXX_VISIBILITY_PRESET hidden so all symbols are visible by default Applied to all four non-trivial shared libraries: phlex_utilities, phlex_model, phlex_core, run_phlex The _internal chain is phlex_core_internal -> phlex_model_internal -> phlex_utilities_internal so tests linking only to phlex::core_internal get all internal symbols transitively without loading the public .so files. layer_generator_internal added in plugins/CMakeLists.txt (same sources, links PRIVATE phlex_core_internal) to avoid loading both the visibility-hidden and all-visible phlex_core variants in the same test process (ODR). All tests in test/CMakeLists.txt and test/utilities/CMakeLists.txt switched to the _internal variants, except: - config_test and identifier which need phlex::configuration and thus transitively pull in the public phlex_core/model/utilities libs; since the relevant symbols are already exported these tests are fine on the public libraries - type_deduction which only requires the header-only phlex::metaprogramming Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- Modules/private/PhlexSymbolVisibility.cmake | 72 ++++++++++++++++++ phlex/app/CMakeLists.txt | 8 ++ phlex/core/CMakeLists.txt | 8 ++ phlex/model/CMakeLists.txt | 8 ++ phlex/utilities/CMakeLists.txt | 8 ++ plugins/CMakeLists.txt | 6 ++ test/CMakeLists.txt | 84 ++++++++++----------- test/utilities/CMakeLists.txt | 6 +- 8 files changed, 155 insertions(+), 45 deletions(-) diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake index d376b9f25..8bcab5a51 100644 --- a/Modules/private/PhlexSymbolVisibility.cmake +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -24,3 +24,75 @@ function(phlex_apply_symbol_visibility target) install(FILES "${EXPORT_HEADER}" DESTINATION include) endfunction() + +# Create a non-installed companion library _internal with default (visible) symbol +# visibility for all symbols. 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. +# +# 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. +function(phlex_make_internal_library target) + cmake_parse_arguments(ARG "" "" "LIBRARIES" ${ARGN}) + + set(internal "${target}_internal") + + # 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. + # 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/app/CMakeLists.txt b/phlex/app/CMakeLists.txt index 8ab21ed04..42ccc9cad 100644 --- a/phlex/app/CMakeLists.txt +++ b/phlex/app/CMakeLists.txt @@ -23,6 +23,14 @@ phlex_apply_symbol_visibility(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/core/CMakeLists.txt b/phlex/core/CMakeLists.txt index a98e0589c..6e31ad98a 100644 --- a/phlex/core/CMakeLists.txt +++ b/phlex/core/CMakeLists.txt @@ -91,6 +91,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/model/CMakeLists.txt b/phlex/model/CMakeLists.txt index 5c0a6dcc9..3209bf43a 100644 --- a/phlex/model/CMakeLists.txt +++ b/phlex/model/CMakeLists.txt @@ -42,6 +42,14 @@ install( target_include_directories(phlex_model PRIVATE ${PROJECT_SOURCE_DIR}) phlex_apply_symbol_visibility(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( LIBRARY_NAME diff --git a/phlex/utilities/CMakeLists.txt b/phlex/utilities/CMakeLists.txt index 91438d2d4..def3a7698 100644 --- a/phlex/utilities/CMakeLists.txt +++ b/phlex/utilities/CMakeLists.txt @@ -29,6 +29,14 @@ install( target_include_directories(phlex_utilities PRIVATE ${PROJECT_SOURCE_DIR}) phlex_apply_symbol_visibility(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( LIBRARY_NAME diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 63a32a9e5..07a0ec3df 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -8,6 +8,12 @@ target_link_libraries(layer_generator PRIVATE phlex::core) install(TARGETS layer_generator LIBRARY) +# Companion library that links against phlex_core_internal so that tests +# using layer_generator do not mix the visibility-hidden and all-visible +# variants of phlex_core in the same process. +add_library(layer_generator_internal layer_generator.cpp) +target_link_libraries(layer_generator_internal PRIVATE phlex_core_internal) + 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/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 ) From 12984fb20e2d61a57f358cc235669c25cd1b91c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:21:58 +0000 Subject: [PATCH 10/22] Move export headers from include/ to include/phlex/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generate and install phlex_X_export.hpp files under include/phlex/ instead of flat in include/, matching the layout of all other Phlex installed headers. Update every #include "X_export.hpp" directive in the 42 affected public headers to #include "phlex/X_export.hpp". The target_include_directories entries are unchanged — the base paths (PROJECT_BINARY_DIR/include for build, include for install) already resolve correctly once the phlex/ subdirectory is part of the filename. Co-authored-by: pcanal <5175087+pcanal@users.noreply.github.com> --- Modules/private/PhlexSymbolVisibility.cmake | 6 +++--- phlex/app/load_module.hpp | 2 +- phlex/app/run.hpp | 2 +- phlex/app/version.hpp | 2 +- phlex/concurrency.hpp | 2 +- phlex/configuration.hpp | 2 +- phlex/core/consumer.hpp | 2 +- phlex/core/declared_fold.hpp | 2 +- phlex/core/declared_observer.hpp | 2 +- phlex/core/declared_output.hpp | 2 +- phlex/core/declared_predicate.hpp | 2 +- phlex/core/declared_provider.hpp | 2 +- phlex/core/declared_transform.hpp | 2 +- phlex/core/declared_unfold.hpp | 2 +- phlex/core/detail/filter_impl.hpp | 2 +- phlex/core/detail/make_algorithm_name.hpp | 2 +- phlex/core/detail/maybe_predicates.hpp | 2 +- phlex/core/detail/repeater_node.hpp | 2 +- phlex/core/edge_creation_policy.hpp | 2 +- phlex/core/edge_maker.hpp | 2 +- phlex/core/filter.hpp | 2 +- phlex/core/framework_graph.hpp | 2 +- phlex/core/glue.hpp | 2 +- phlex/core/index_router.hpp | 2 +- phlex/core/input_arguments.hpp | 2 +- phlex/core/message.hpp | 2 +- phlex/core/node_catalog.hpp | 2 +- phlex/core/product_query.hpp | 2 +- phlex/core/products_consumer.hpp | 2 +- phlex/core/registrar.hpp | 2 +- phlex/core/registration_api.hpp | 2 +- phlex/core/store_counters.hpp | 2 +- phlex/model/algorithm_name.hpp | 2 +- phlex/model/data_cell_counter.hpp | 2 +- phlex/model/data_cell_index.hpp | 2 +- phlex/model/data_layer_hierarchy.hpp | 2 +- phlex/model/identifier.hpp | 2 +- phlex/model/product_matcher.hpp | 2 +- phlex/model/product_specification.hpp | 2 +- phlex/model/product_store.hpp | 2 +- phlex/model/products.hpp | 2 +- phlex/utilities/hashing.hpp | 2 +- phlex/utilities/resource_usage.hpp | 2 +- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake index 8bcab5a51..8344c37c6 100644 --- a/Modules/private/PhlexSymbolVisibility.cmake +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -1,7 +1,7 @@ include(GenerateExportHeader) function(phlex_apply_symbol_visibility target) - set(EXPORT_HEADER "${PROJECT_BINARY_DIR}/include/${target}_export.hpp") + set(EXPORT_HEADER "${PROJECT_BINARY_DIR}/include/phlex/${target}_export.hpp") set(EXPORT_MACRO_NAME "${target}_EXPORT") generate_export_header( @@ -22,7 +22,7 @@ function(phlex_apply_symbol_visibility target) PUBLIC $ $ ) - install(FILES "${EXPORT_HEADER}" DESTINATION include) + install(FILES "${EXPORT_HEADER}" DESTINATION include/phlex) endfunction() # Create a non-installed companion library _internal with default (visible) symbol @@ -74,7 +74,7 @@ function(phlex_make_internal_library target) # 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. + # 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( diff --git a/phlex/app/load_module.hpp b/phlex/app/load_module.hpp index 4b7f44a8a..20fbcc3b8 100644 --- a/phlex/app/load_module.hpp +++ b/phlex/app/load_module.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_APP_LOAD_MODULE_HPP #define PHLEX_APP_LOAD_MODULE_HPP -#include "run_phlex_export.hpp" +#include "phlex/run_phlex_export.hpp" #include "phlex/core/fwd.hpp" #include "phlex/driver.hpp" diff --git a/phlex/app/run.hpp b/phlex/app/run.hpp index c275ebcbe..af4ab113f 100644 --- a/phlex/app/run.hpp +++ b/phlex/app/run.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_APP_RUN_HPP #define PHLEX_APP_RUN_HPP -#include "run_phlex_export.hpp" +#include "phlex/run_phlex_export.hpp" #include "boost/json.hpp" diff --git a/phlex/app/version.hpp b/phlex/app/version.hpp index e7be449f9..dfb9b93cc 100644 --- a/phlex/app/version.hpp +++ b/phlex/app/version.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_APP_VERSION_HPP #define PHLEX_APP_VERSION_HPP -#include "run_phlex_export.hpp" +#include "phlex/run_phlex_export.hpp" namespace phlex::experimental { run_phlex_EXPORT char const* version(); diff --git a/phlex/concurrency.hpp b/phlex/concurrency.hpp index 328ec2982..cb98595fb 100644 --- a/phlex/concurrency.hpp +++ b/phlex/concurrency.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CONCURRENCY_HPP #define PHLEX_CONCURRENCY_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include diff --git a/phlex/configuration.hpp b/phlex/configuration.hpp index 7346a5983..1a5ec1ef0 100644 --- a/phlex/configuration.hpp +++ b/phlex/configuration.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CONFIGURATION_HPP #define PHLEX_CONFIGURATION_HPP -#include "phlex_configuration_internal_export.hpp" +#include "phlex/phlex_configuration_internal_export.hpp" #include "boost/json.hpp" #include "phlex/core/product_query.hpp" diff --git a/phlex/core/consumer.hpp b/phlex/core/consumer.hpp index aa0c2b5a6..bc4c70a00 100644 --- a/phlex/core/consumer.hpp +++ b/phlex/core/consumer.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_CONSUMER_HPP #define PHLEX_CORE_CONSUMER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/model/algorithm_name.hpp" diff --git a/phlex/core/declared_fold.hpp b/phlex/core/declared_fold.hpp index 170ccf571..429a252d3 100644 --- a/phlex/core/declared_fold.hpp +++ b/phlex/core/declared_fold.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_FOLD_HPP #define PHLEX_CORE_DECLARED_FOLD_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" diff --git a/phlex/core/declared_observer.hpp b/phlex/core/declared_observer.hpp index d41ff6ecb..fc3e6d0eb 100644 --- a/phlex/core/declared_observer.hpp +++ b/phlex/core/declared_observer.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_OBSERVER_HPP #define PHLEX_CORE_DECLARED_OBSERVER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/declared_output.hpp b/phlex/core/declared_output.hpp index 479d99425..4e2643583 100644 --- a/phlex/core/declared_output.hpp +++ b/phlex/core/declared_output.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_OUTPUT_HPP #define PHLEX_CORE_DECLARED_OUTPUT_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/consumer.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/declared_predicate.hpp b/phlex/core/declared_predicate.hpp index 0d94968d2..755d8b295 100644 --- a/phlex/core/declared_predicate.hpp +++ b/phlex/core/declared_predicate.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_PREDICATE_HPP #define PHLEX_CORE_DECLARED_PREDICATE_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/detail/filter_impl.hpp" diff --git a/phlex/core/declared_provider.hpp b/phlex/core/declared_provider.hpp index 5fed93a75..9ade62ef1 100644 --- a/phlex/core/declared_provider.hpp +++ b/phlex/core/declared_provider.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_PROVIDER_HPP #define PHLEX_CORE_DECLARED_PROVIDER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/declared_transform.hpp b/phlex/core/declared_transform.hpp index bd9e99817..8e9586c2b 100644 --- a/phlex/core/declared_transform.hpp +++ b/phlex/core/declared_transform.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_TRANSFORM_HPP #define PHLEX_CORE_DECLARED_TRANSFORM_HPP -#include "phlex_core_export.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. diff --git a/phlex/core/declared_unfold.hpp b/phlex/core/declared_unfold.hpp index e23051784..8952f6f36 100644 --- a/phlex/core/declared_unfold.hpp +++ b/phlex/core/declared_unfold.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DECLARED_UNFOLD_HPP #define PHLEX_CORE_DECLARED_UNFOLD_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/concepts.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/detail/filter_impl.hpp b/phlex/core/detail/filter_impl.hpp index fe932f65e..0277ee876 100644 --- a/phlex/core/detail/filter_impl.hpp +++ b/phlex/core/detail/filter_impl.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DETAIL_FILTER_IMPL_HPP #define PHLEX_CORE_DETAIL_FILTER_IMPL_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/product_query.hpp" diff --git a/phlex/core/detail/make_algorithm_name.hpp b/phlex/core/detail/make_algorithm_name.hpp index d7eb1b467..b554e1b9f 100644 --- a/phlex/core/detail/make_algorithm_name.hpp +++ b/phlex/core/detail/make_algorithm_name.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DETAIL_MAKE_ALGORITHM_NAME_HPP #define PHLEX_CORE_DETAIL_MAKE_ALGORITHM_NAME_HPP -#include "phlex_core_export.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. diff --git a/phlex/core/detail/maybe_predicates.hpp b/phlex/core/detail/maybe_predicates.hpp index 3d74c662b..f48c33a87 100644 --- a/phlex/core/detail/maybe_predicates.hpp +++ b/phlex/core/detail/maybe_predicates.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DETAIL_MAYBE_PREDICATES_HPP #define PHLEX_CORE_DETAIL_MAYBE_PREDICATES_HPP -#include "phlex_core_export.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. diff --git a/phlex/core/detail/repeater_node.hpp b/phlex/core/detail/repeater_node.hpp index a0983994b..1b48fec9c 100644 --- a/phlex/core/detail/repeater_node.hpp +++ b/phlex/core/detail/repeater_node.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_DETAIL_REPEATER_NODE_HPP #define PHLEX_CORE_DETAIL_REPEATER_NODE_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/message.hpp" diff --git a/phlex/core/edge_creation_policy.hpp b/phlex/core/edge_creation_policy.hpp index ff31fd104..caede8b78 100644 --- a/phlex/core/edge_creation_policy.hpp +++ b/phlex/core/edge_creation_policy.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_EDGE_CREATION_POLICY_HPP #define PHLEX_CORE_EDGE_CREATION_POLICY_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/message.hpp" #include "phlex/model/identifier.hpp" diff --git a/phlex/core/edge_maker.hpp b/phlex/core/edge_maker.hpp index 5cbdff0e5..a40a46028 100644 --- a/phlex/core/edge_maker.hpp +++ b/phlex/core/edge_maker.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_EDGE_MAKER_HPP #define PHLEX_CORE_EDGE_MAKER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_output.hpp" diff --git a/phlex/core/filter.hpp b/phlex/core/filter.hpp index e1af1ad3b..b96b116a3 100644 --- a/phlex/core/filter.hpp +++ b/phlex/core/filter.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_FILTER_HPP #define PHLEX_CORE_FILTER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/detail/filter_impl.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/framework_graph.hpp b/phlex/core/framework_graph.hpp index 3741b0dcf..c45f426ff 100644 --- a/phlex/core/framework_graph.hpp +++ b/phlex/core/framework_graph.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_FRAMEWORK_GRAPH_HPP #define PHLEX_CORE_FRAMEWORK_GRAPH_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_unfold.hpp" diff --git a/phlex/core/glue.hpp b/phlex/core/glue.hpp index c03298c4e..1b8c008b2 100644 --- a/phlex/core/glue.hpp +++ b/phlex/core/glue.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_GLUE_HPP #define PHLEX_CORE_GLUE_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" diff --git a/phlex/core/index_router.hpp b/phlex/core/index_router.hpp index 5d8ecb643..0fbfdfd2b 100644 --- a/phlex/core/index_router.hpp +++ b/phlex/core/index_router.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_INDEX_ROUTER_HPP #define PHLEX_CORE_INDEX_ROUTER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/message.hpp" diff --git a/phlex/core/input_arguments.hpp b/phlex/core/input_arguments.hpp index 666613261..6ed74aedf 100644 --- a/phlex/core/input_arguments.hpp +++ b/phlex/core/input_arguments.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_INPUT_ARGUMENTS_HPP #define PHLEX_CORE_INPUT_ARGUMENTS_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/message.hpp" #include "phlex/core/product_query.hpp" diff --git a/phlex/core/message.hpp b/phlex/core/message.hpp index 506850603..62f423220 100644 --- a/phlex/core/message.hpp +++ b/phlex/core/message.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_MESSAGE_HPP #define PHLEX_CORE_MESSAGE_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/fwd.hpp" #include "phlex/core/product_query.hpp" diff --git a/phlex/core/node_catalog.hpp b/phlex/core/node_catalog.hpp index dc306db93..68051aaa5 100644 --- a/phlex/core/node_catalog.hpp +++ b/phlex/core/node_catalog.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_NODE_CATALOG_HPP #define PHLEX_CORE_NODE_CATALOG_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/declared_fold.hpp" #include "phlex/core/declared_observer.hpp" diff --git a/phlex/core/product_query.hpp b/phlex/core/product_query.hpp index 1274391c9..dd0f4859f 100644 --- a/phlex/core/product_query.hpp +++ b/phlex/core/product_query.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_PRODUCT_QUERY_HPP #define PHLEX_CORE_PRODUCT_QUERY_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/model/identifier.hpp" #include "phlex/model/product_specification.hpp" diff --git a/phlex/core/products_consumer.hpp b/phlex/core/products_consumer.hpp index e8172fa2d..180b6b7db 100644 --- a/phlex/core/products_consumer.hpp +++ b/phlex/core/products_consumer.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_PRODUCTS_CONSUMER_HPP #define PHLEX_CORE_PRODUCTS_CONSUMER_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/consumer.hpp" #include "phlex/core/fwd.hpp" diff --git a/phlex/core/registrar.hpp b/phlex/core/registrar.hpp index 9e41a8cc1..82ae79d55 100644 --- a/phlex/core/registrar.hpp +++ b/phlex/core/registrar.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_REGISTRAR_HPP #define PHLEX_CORE_REGISTRAR_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" // ======================================================================================= // diff --git a/phlex/core/registration_api.hpp b/phlex/core/registration_api.hpp index 893b04a24..93a7532aa 100644 --- a/phlex/core/registration_api.hpp +++ b/phlex/core/registration_api.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_REGISTRATION_API_HPP #define PHLEX_CORE_REGISTRATION_API_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/concurrency.hpp" #include "phlex/core/concepts.hpp" diff --git a/phlex/core/store_counters.hpp b/phlex/core/store_counters.hpp index 6750e92f5..0e97b9f56 100644 --- a/phlex/core/store_counters.hpp +++ b/phlex/core/store_counters.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_CORE_STORE_COUNTERS_HPP #define PHLEX_CORE_STORE_COUNTERS_HPP -#include "phlex_core_export.hpp" +#include "phlex/phlex_core_export.hpp" #include "phlex/core/fwd.hpp" #include "phlex/model/data_cell_counter.hpp" diff --git a/phlex/model/algorithm_name.hpp b/phlex/model/algorithm_name.hpp index 570896f88..778f10803 100644 --- a/phlex/model/algorithm_name.hpp +++ b/phlex/model/algorithm_name.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_ALGORITHM_NAME_HPP #define PHLEX_MODEL_ALGORITHM_NAME_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/identifier.hpp" diff --git a/phlex/model/data_cell_counter.hpp b/phlex/model/data_cell_counter.hpp index 0495bb46e..888a7da22 100644 --- a/phlex/model/data_cell_counter.hpp +++ b/phlex/model/data_cell_counter.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_DATA_CELL_COUNTER_HPP #define PHLEX_MODEL_DATA_CELL_COUNTER_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/data_cell_index.hpp" #include "phlex/model/fwd.hpp" diff --git a/phlex/model/data_cell_index.hpp b/phlex/model/data_cell_index.hpp index 2bd0906be..18c64325f 100644 --- a/phlex/model/data_cell_index.hpp +++ b/phlex/model/data_cell_index.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_DATA_CELL_INDEX_HPP #define PHLEX_MODEL_DATA_CELL_INDEX_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/fwd.hpp" #include "phlex/model/identifier.hpp" diff --git a/phlex/model/data_layer_hierarchy.hpp b/phlex/model/data_layer_hierarchy.hpp index 7e19cce99..426aefd37 100644 --- a/phlex/model/data_layer_hierarchy.hpp +++ b/phlex/model/data_layer_hierarchy.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_DATA_LAYER_HIERARCHY_HPP #define PHLEX_MODEL_DATA_LAYER_HIERARCHY_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/data_cell_index.hpp" #include "phlex/model/fwd.hpp" diff --git a/phlex/model/identifier.hpp b/phlex/model/identifier.hpp index 7f9e3267b..cc002bcb0 100644 --- a/phlex/model/identifier.hpp +++ b/phlex/model/identifier.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_IDENTIFIER_HPP #define PHLEX_MODEL_IDENTIFIER_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include diff --git a/phlex/model/product_matcher.hpp b/phlex/model/product_matcher.hpp index 2ca5a55e0..e6f13bdef 100644 --- a/phlex/model/product_matcher.hpp +++ b/phlex/model/product_matcher.hpp @@ -9,7 +9,7 @@ // // ======================================================================================= -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/fwd.hpp" diff --git a/phlex/model/product_specification.hpp b/phlex/model/product_specification.hpp index a2b82897f..35de9f0d6 100644 --- a/phlex/model/product_specification.hpp +++ b/phlex/model/product_specification.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_PRODUCT_SPECIFICATION_HPP #define PHLEX_MODEL_PRODUCT_SPECIFICATION_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/algorithm_name.hpp" #include "phlex/model/identifier.hpp" diff --git a/phlex/model/product_store.hpp b/phlex/model/product_store.hpp index 19f5f24b6..bbe29bc85 100644 --- a/phlex/model/product_store.hpp +++ b/phlex/model/product_store.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_PRODUCT_STORE_HPP #define PHLEX_MODEL_PRODUCT_STORE_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/algorithm_name.hpp" #include "phlex/model/data_cell_index.hpp" diff --git a/phlex/model/products.hpp b/phlex/model/products.hpp index 1b0129978..60601423c 100644 --- a/phlex/model/products.hpp +++ b/phlex/model/products.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_MODEL_PRODUCTS_HPP #define PHLEX_MODEL_PRODUCTS_HPP -#include "phlex_model_export.hpp" +#include "phlex/phlex_model_export.hpp" #include "phlex/model/product_specification.hpp" diff --git a/phlex/utilities/hashing.hpp b/phlex/utilities/hashing.hpp index e8857038c..f521654ae 100644 --- a/phlex/utilities/hashing.hpp +++ b/phlex/utilities/hashing.hpp @@ -1,7 +1,7 @@ #ifndef PHLEX_UTILITIES_HASHING_HPP #define PHLEX_UTILITIES_HASHING_HPP -#include "phlex_utilities_export.hpp" +#include "phlex/phlex_utilities_export.hpp" #include #include diff --git a/phlex/utilities/resource_usage.hpp b/phlex/utilities/resource_usage.hpp index 4a5cfab48..d7b4e5b71 100644 --- a/phlex/utilities/resource_usage.hpp +++ b/phlex/utilities/resource_usage.hpp @@ -6,7 +6,7 @@ // resource_usage object. The destructor will also report the maximum RSS of the process. // ======================================================================================= -#include "phlex_utilities_export.hpp" +#include "phlex/phlex_utilities_export.hpp" #include From fb2153b7ec4b2029fb1d9045475afcad8a0d15f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:26:53 +0000 Subject: [PATCH 11/22] Remove redundant INSTALL_INTERFACE from phlex_apply_symbol_visibility cetmodules adds INSTALL_INTERFACE:include to every target it creates via cet_make_library, so the explicit INSTALL_INTERFACE:include entry in phlex_apply_symbol_visibility was a no-op duplicate. The only unique contribution of the target_include_directories call is the BUILD_INTERFACE to ${PROJECT_BINARY_DIR}/include, which is where generate_export_header writes the generated phlex/X_export.hpp headers. Co-authored-by: pcanal <5175087+pcanal@users.noreply.github.com> --- Modules/private/PhlexSymbolVisibility.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake index 8344c37c6..338a560b0 100644 --- a/Modules/private/PhlexSymbolVisibility.cmake +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -18,8 +18,7 @@ function(phlex_apply_symbol_visibility target) ) target_include_directories( - ${target} - PUBLIC $ $ + ${target} PUBLIC $ ) install(FILES "${EXPORT_HEADER}" DESTINATION include/phlex) From bcffb4a7774be46ad091f2f94345caf41466075c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 21:04:10 +0000 Subject: [PATCH 12/22] Apply cmake-format fixes --- Modules/private/PhlexSymbolVisibility.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake index 338a560b0..d2dd906e6 100644 --- a/Modules/private/PhlexSymbolVisibility.cmake +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -17,9 +17,7 @@ function(phlex_apply_symbol_visibility target) PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON ) - target_include_directories( - ${target} PUBLIC $ - ) + target_include_directories(${target} PUBLIC $) install(FILES "${EXPORT_HEADER}" DESTINATION include/phlex) endfunction() From 5fc99e6409f3156c16dc5d5732b8bd8fe313ccfc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:21:22 +0000 Subject: [PATCH 13/22] Add PHLEX_HIDE_SYMBOLS option to toggle symbol visibility mode Introduce option(PHLEX_HIDE_SYMBOLS ... ON) in CMakeLists.txt and wire it through both functions in PhlexSymbolVisibility.cmake: phlex_apply_symbol_visibility(target) ON (default): generate export header + CXX_VISIBILITY_PRESET hidden OFF: generate export header only; all symbols visible by default phlex_make_internal_library(target LIBRARIES ...) ON (default): compile separate SHARED lib with full symbol visibility OFF: create a thin INTERFACE target wrapping the public lib; no extra compilation or .so needed since the public lib already exports everything In OFF mode _internal aliases and layer_generator_internal still exist and link correctly via the INTERFACE wrappers, so no other files change. Benchmark tests (test/benchmarks/, test/max-parallelism/) already link exclusively to curated public targets in both modes. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- CMakeLists.txt | 5 +++ Modules/private/PhlexSymbolVisibility.cmake | 37 +++++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c67482ad6..4d3cd7611 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,11 @@ option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) option(ENABLE_ASAN "Enable Address Sanitizer" OFF) option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF) option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF) +option( + PHLEX_HIDE_SYMBOLS + "Hide non-exported symbols in shared libraries (ON = curated API; OFF = all symbols visible)" + ON +) add_compile_options( -Wall diff --git a/Modules/private/PhlexSymbolVisibility.cmake b/Modules/private/PhlexSymbolVisibility.cmake index d2dd906e6..69590f457 100644 --- a/Modules/private/PhlexSymbolVisibility.cmake +++ b/Modules/private/PhlexSymbolVisibility.cmake @@ -12,32 +12,49 @@ function(phlex_apply_symbol_visibility target) STATIC_DEFINE "${target}_STATIC_DEFINE" ) - set_target_properties( - ${target} - PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON - ) + 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 non-installed companion library _internal with default (visible) symbol -# visibility for all symbols. This allows tests to access non-exported implementation -# details without requiring every internal symbol to carry an EXPORT macro, and enables +# 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. +# 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) From a37cb2e3b82a1abd40c1361f54219e209fbdef64 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:09:50 +0000 Subject: [PATCH 14/22] Make layer_generator_internal conditional on PHLEX_HIDE_SYMBOLS When PHLEX_HIDE_SYMBOLS=OFF, layer_generator already exports all symbols, so compiling a separate .so for layer_generator_internal is unnecessary. Use a thin INTERFACE alias instead, matching the behaviour of phlex_make_internal_library() for the core libraries. All plugins used by the benchmark tests (test/benchmarks/, test/max-parallelism/) already link exclusively against curated public targets (phlex::module, phlex::core, layer_generator), not the _internal variants. This is unaffected by PHLEX_HIDE_SYMBOLS. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- plugins/CMakeLists.txt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 07a0ec3df..8f14921e9 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -8,11 +8,19 @@ target_link_libraries(layer_generator PRIVATE phlex::core) install(TARGETS layer_generator LIBRARY) -# Companion library that links against phlex_core_internal so that tests -# using layer_generator do not mix the visibility-hidden and all-visible -# variants of phlex_core in the same process. -add_library(layer_generator_internal layer_generator.cpp) -target_link_libraries(layer_generator_internal PRIVATE phlex_core_internal) +# 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) From 4d4accdd07b7503a144c31f8ed04de86309e9ef5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:40:30 +0000 Subject: [PATCH 15/22] Add PhlexOptimization.cmake: -fno-semantic-interposition, -fno-plt, PHLEX_ENABLE_IPO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three optimizations are chosen specifically for the symbol-hiding + external-plugin architecture: 1. -fno-semantic-interposition (GCC >= 9, Clang >= 8; when PHLEX_HIDE_SYMBOLS=ON) Allows the compiler to inline, devirtualise, and generate direct (non-PLT) calls for same-DSO accesses to exported functions. Safe only once the exported-symbol surface is explicitly bounded by export macros — exactly what PHLEX_HIDE_SYMBOLS=ON provides. 2. -fno-plt (GCC >= 7.3, Clang >= 4, ELF/Linux only) Replaces PLT stubs with GOT-based dispatch for calls FROM a Phlex library TO external DSOs (TBB, Boost, spdlog, ...). Removes one level of indirection from every cross-DSO call after load-time resolution. 3. PHLEX_ENABLE_IPO (default OFF) Sets CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE and _RELWITHDEBINFO after confirming compiler support. LTO is safe with symbol hiding because export attributes preserve the complete exported-symbol set; the linker cannot eliminate or rename any default-visibility symbol. External plugins compiled without LTO are unaffected. Intentionally excluded: -ffast-math/-funsafe-math-optimizations, which can silently break floating-point correctness in physics/numerical code. PhlexOptimization.cmake is included from the root CMakeLists.txt. phlex_apply_optimizations() is called after phlex_apply_symbol_visibility() in each of the five shared library CMakeLists.txt files. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- CMakeLists.txt | 1 + Modules/private/PhlexOptimization.cmake | 112 ++++++++++++++++++++++++ phlex/CMakeLists.txt | 1 + phlex/app/CMakeLists.txt | 1 + phlex/core/CMakeLists.txt | 1 + phlex/model/CMakeLists.txt | 1 + phlex/utilities/CMakeLists.txt | 1 + 7 files changed, 118 insertions(+) create mode 100644 Modules/private/PhlexOptimization.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d3cd7611..1b965d7a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ 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..4f8fc2f79 --- /dev/null +++ b/Modules/private/PhlexOptimization.cmake @@ -0,0 +1,112 @@ +# Provides phlex_apply_optimizations(target), which applies safe, +# performance-oriented compiler flags to a Phlex shared library target. +# +# 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. +# +# PHLEX_ENABLE_IPO (default OFF) +# When ON, enables interprocedural optimization (link-time optimization) for +# Release and RelWithDebInfo configurations via the +# CMAKE_INTERPROCEDURAL_OPTIMIZATION_* variables. +# +# LTO is safe with symbol hiding: export attributes preserve the complete +# exported-symbol set; the linker cannot eliminate or rename any symbol that +# carries a default-visibility attribute. External plugins compiled without +# LTO link against the normal exported-symbol table and are unaffected. + +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) +# --------------------------------------------------------------------------- +cmake_policy(SET CMP0069 NEW) +include(CheckIPOSupported) + +option( + PHLEX_ENABLE_IPO + [=[Enable interprocedural optimization (LTO) for Release and RelWithDebInfo +builds. Safe with symbol hiding because export macros preserve the complete +exported-symbol set. External plugins compiled without LTO are unaffected.]=] + OFF +) + +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/phlex/CMakeLists.txt b/phlex/CMakeLists.txt index e81b70028..76e54ae2e 100644 --- a/phlex/CMakeLists.txt +++ b/phlex/CMakeLists.txt @@ -34,6 +34,7 @@ cet_make_library( 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 42ccc9cad..66c537496 100644 --- a/phlex/app/CMakeLists.txt +++ b/phlex/app/CMakeLists.txt @@ -19,6 +19,7 @@ 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) diff --git a/phlex/core/CMakeLists.txt b/phlex/core/CMakeLists.txt index 6e31ad98a..fce6340f3 100644 --- a/phlex/core/CMakeLists.txt +++ b/phlex/core/CMakeLists.txt @@ -82,6 +82,7 @@ install( ) 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( diff --git a/phlex/model/CMakeLists.txt b/phlex/model/CMakeLists.txt index 3209bf43a..f75e21f7f 100644 --- a/phlex/model/CMakeLists.txt +++ b/phlex/model/CMakeLists.txt @@ -41,6 +41,7 @@ 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 diff --git a/phlex/utilities/CMakeLists.txt b/phlex/utilities/CMakeLists.txt index def3a7698..5edf24c7b 100644 --- a/phlex/utilities/CMakeLists.txt +++ b/phlex/utilities/CMakeLists.txt @@ -28,6 +28,7 @@ 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 From 9821b54f469594b981524d235cbae1c75647fc83 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:44:53 +0000 Subject: [PATCH 16/22] Auto-enable PHLEX_ENABLE_IPO for Release/RelWithDebInfo build types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmake -DCMAKE_BUILD_TYPE=Release now automatically opts into LTO without requiring a separate -DPHLEX_ENABLE_IPO=ON. The default is derived from CMAKE_BUILD_TYPE at first configure time: Release / RelWithDebInfo → PHLEX_ENABLE_IPO defaults to ON Debug / Coverage / sanitizer builds → PHLEX_ENABLE_IPO defaults to OFF Multi-config generators (no CMAKE_BUILD_TYPE) → defaults to OFF The option can always be overridden explicitly with -DPHLEX_ENABLE_IPO=ON|OFF. The compile-level flags (-fno-semantic-interposition, -fno-plt) are unchanged: they are applied unconditionally (subject to compiler/platform support) regardless of build type, complementing CMake's per-config CMAKE_CXX_FLAGS_RELEASE (-O3 -DNDEBUG) without duplicating it. Documentation in the module header is updated to describe the full build-type interaction. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- Modules/private/PhlexOptimization.cmake | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake index 4f8fc2f79..145cd724c 100644 --- a/Modules/private/PhlexOptimization.cmake +++ b/Modules/private/PhlexOptimization.cmake @@ -36,11 +36,24 @@ # These flags may silently produce incorrect numerical results and are # therefore not enabled. # -# PHLEX_ENABLE_IPO (default OFF) +# Interaction with CMAKE_BUILD_TYPE +# -fno-semantic-interposition and -fno-plt are compile-level flags that are +# applied unconditionally (subject to compiler / platform support) regardless +# of build type; they complement but do not duplicate CMake's per-config +# CMAKE_CXX_FLAGS_RELEASE (-O3 -DNDEBUG) and CMAKE_CXX_FLAGS_DEBUG (-g). +# +# PHLEX_ENABLE_IPO (default ON for Release/RelWithDebInfo, OFF otherwise) # When ON, enables interprocedural optimization (link-time optimization) for # Release and RelWithDebInfo configurations via the # CMAKE_INTERPROCEDURAL_OPTIMIZATION_* variables. # +# The default is determined from CMAKE_BUILD_TYPE at first configure time: +# Release / RelWithDebInfo → ON (maximise optimisation) +# Debug / Coverage / sanitizers → OFF (preserve debuggability) +# not set (multi-config generators) → OFF (conservative fallback) +# +# The option can always be overridden explicitly with -DPHLEX_ENABLE_IPO=ON|OFF. +# # LTO is safe with symbol hiding: export attributes preserve the complete # exported-symbol set; the linker cannot eliminate or rename any symbol that # carries a default-visibility attribute. External plugins compiled without @@ -67,12 +80,23 @@ endif() cmake_policy(SET CMP0069 NEW) include(CheckIPOSupported) +# Derive a sensible default: enable LTO automatically for Release-class builds +# so that cmake -DCMAKE_BUILD_TYPE=Release "does the right thing" without +# requiring a separate -DPHLEX_ENABLE_IPO=ON. Debug/sanitizer/coverage builds +# keep the default OFF to preserve debuggability. +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. Safe with symbol hiding because export macros preserve the complete -exported-symbol set. External plugins compiled without LTO are unaffected.]=] - OFF +exported-symbol set. External plugins compiled without LTO are unaffected. +Defaults to ON when CMAKE_BUILD_TYPE is Release or RelWithDebInfo.]=] + "${_phlex_ipo_default}" ) if(PHLEX_ENABLE_IPO) From cb78d90219d0acc4088e00d8295ef378f71010d4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:48:38 +0000 Subject: [PATCH 17/22] Default PHLEX_HIDE_SYMBOLS based on CMAKE_BUILD_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror the PHLEX_ENABLE_IPO pattern: for Release/RelWithDebInfo builds, default PHLEX_HIDE_SYMBOLS=ON (curated API + -fno-semantic-interposition safe); for Debug, Coverage, and sanitizer builds, default OFF so all symbols are visible to debuggers, profilers, and sanitizer stack traces. cmake -DCMAKE_BUILD_TYPE=Release → PHLEX_HIDE_SYMBOLS=ON, PHLEX_ENABLE_IPO=ON cmake -DCMAKE_BUILD_TYPE=Debug → PHLEX_HIDE_SYMBOLS=OFF, PHLEX_ENABLE_IPO=OFF cmake (no CMAKE_BUILD_TYPE) → both OFF (conservative fallback) Both options can still be overridden explicitly at any time. Update PhlexOptimization.cmake header to document the combined interaction of both options with CMAKE_BUILD_TYPE. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- CMakeLists.txt | 13 ++++++++++++- Modules/private/PhlexOptimization.cmake | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b965d7a6..0006ff53b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,10 +65,21 @@ option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) option(ENABLE_ASAN "Enable Address Sanitizer" OFF) option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF) option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF) + +# Default PHLEX_HIDE_SYMBOLS to ON for Release-class builds (symbol hiding +# improves performance and reduces library size) and OFF for Debug builds +# (all symbols visible aids debuggers, profilers, and sanitizer stack traces). +# Mirrors the PHLEX_ENABLE_IPO default logic. +if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") + set(_phlex_hide_symbols_default ON) +else() + set(_phlex_hide_symbols_default OFF) +endif() + option( PHLEX_HIDE_SYMBOLS "Hide non-exported symbols in shared libraries (ON = curated API; OFF = all symbols visible)" - ON + "${_phlex_hide_symbols_default}" ) add_compile_options( diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake index 145cd724c..6d65e77ed 100644 --- a/Modules/private/PhlexOptimization.cmake +++ b/Modules/private/PhlexOptimization.cmake @@ -37,28 +37,30 @@ # therefore not enabled. # # Interaction with CMAKE_BUILD_TYPE +# Both PHLEX_HIDE_SYMBOLS and PHLEX_ENABLE_IPO default based on +# CMAKE_BUILD_TYPE (set in CMakeLists.txt before this module is included): +# +# Release / RelWithDebInfo → PHLEX_HIDE_SYMBOLS=ON, PHLEX_ENABLE_IPO=ON +# Debug / Coverage / sanitizers → both default to OFF +# not set (multi-config generators) → both default to OFF (conservative) +# # -fno-semantic-interposition and -fno-plt are compile-level flags that are -# applied unconditionally (subject to compiler / platform support) regardless -# of build type; they complement but do not duplicate CMake's per-config -# CMAKE_CXX_FLAGS_RELEASE (-O3 -DNDEBUG) and CMAKE_CXX_FLAGS_DEBUG (-g). +# applied unconditionally (subject to compiler / platform support and +# PHLEX_HIDE_SYMBOLS) regardless of build type; they complement but do not +# duplicate CMake's per-config CMAKE_CXX_FLAGS_RELEASE (-O3 -DNDEBUG) and +# CMAKE_CXX_FLAGS_DEBUG (-g). # # PHLEX_ENABLE_IPO (default ON for Release/RelWithDebInfo, OFF otherwise) # When ON, enables interprocedural optimization (link-time optimization) for # Release and RelWithDebInfo configurations via the # CMAKE_INTERPROCEDURAL_OPTIMIZATION_* variables. # -# The default is determined from CMAKE_BUILD_TYPE at first configure time: -# Release / RelWithDebInfo → ON (maximise optimisation) -# Debug / Coverage / sanitizers → OFF (preserve debuggability) -# not set (multi-config generators) → OFF (conservative fallback) -# -# The option can always be overridden explicitly with -DPHLEX_ENABLE_IPO=ON|OFF. -# # LTO is safe with symbol hiding: export attributes preserve the complete # exported-symbol set; the linker cannot eliminate or rename any symbol that # carries a default-visibility attribute. External plugins compiled without # LTO link against the normal exported-symbol table and are unaffected. + include_guard() include(CheckCXXCompilerFlag) From 6512cc730ec659faa4c602e2923e2d4fb5232734 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:00:21 +0000 Subject: [PATCH 18/22] Auto-adjust PHLEX_HIDE_SYMBOLS default when PHLEX_ENABLE_IPO=ON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move PHLEX_HIDE_SYMBOLS from CMakeLists.txt into PhlexOptimization.cmake so both options are co-located and their defaults are derived together. PHLEX_ENABLE_IPO is now defined first; PHLEX_HIDE_SYMBOLS defaults to ON whenever PHLEX_ENABLE_IPO=ON (in addition to Release/RelWithDebInfo): cmake -DPHLEX_ENABLE_IPO=ON → PHLEX_HIDE_SYMBOLS defaults ON cmake -DCMAKE_BUILD_TYPE=Release → both default ON (unchanged) cmake (Debug / no type) → both default OFF (unchanged) LTO achieves its full potential only with hidden symbols: without -fvisibility=hidden the LTO optimizer must treat every exported symbol as interposable and cannot apply -fno-semantic-interposition. Making IPO automatically pull in symbol hiding as its default ensures the optimal combination is selected whenever LTO is requested. The per-target compile flags in phlex_apply_optimizations() are unchanged: they already self-adjust at build time based on the final option values. The note emitted when a user explicitly overrides PHLEX_HIDE_SYMBOLS=OFF after requesting IPO is retained (now factual rather than advisory). Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- CMakeLists.txt | 16 ---- Modules/private/PhlexOptimization.cmake | 99 ++++++++++++++++++------- 2 files changed, 73 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0006ff53b..6ca459c00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,22 +66,6 @@ option(ENABLE_ASAN "Enable Address Sanitizer" OFF) option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF) option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF) -# Default PHLEX_HIDE_SYMBOLS to ON for Release-class builds (symbol hiding -# improves performance and reduces library size) and OFF for Debug builds -# (all symbols visible aids debuggers, profilers, and sanitizer stack traces). -# Mirrors the PHLEX_ENABLE_IPO default logic. -if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") - set(_phlex_hide_symbols_default ON) -else() - set(_phlex_hide_symbols_default OFF) -endif() - -option( - PHLEX_HIDE_SYMBOLS - "Hide non-exported symbols in shared libraries (ON = curated API; OFF = all symbols visible)" - "${_phlex_hide_symbols_default}" -) - add_compile_options( -Wall -Werror diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake index 6d65e77ed..e88919171 100644 --- a/Modules/private/PhlexOptimization.cmake +++ b/Modules/private/PhlexOptimization.cmake @@ -1,5 +1,7 @@ # 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 +# ensures their defaults are mutually consistent. # # Two flags are applied (subject to compiler support and platform): # @@ -36,29 +38,41 @@ # These flags may silently produce incorrect numerical results and are # therefore not enabled. # -# Interaction with CMAKE_BUILD_TYPE -# Both PHLEX_HIDE_SYMBOLS and PHLEX_ENABLE_IPO default based on -# CMAKE_BUILD_TYPE (set in CMakeLists.txt before this module is included): +# Options and their interaction with CMAKE_BUILD_TYPE # -# Release / RelWithDebInfo → PHLEX_HIDE_SYMBOLS=ON, PHLEX_ENABLE_IPO=ON -# Debug / Coverage / sanitizers → both default to OFF -# not set (multi-config generators) → both default to OFF (conservative) +# Both PHLEX_HIDE_SYMBOLS and PHLEX_ENABLE_IPO are defined here so that their +# defaults can be derived together. The effective defaults are: # -# -fno-semantic-interposition and -fno-plt are compile-level flags that are -# applied unconditionally (subject to compiler / platform support and -# PHLEX_HIDE_SYMBOLS) regardless of build type; they complement but do not -# duplicate CMake's per-config CMAKE_CXX_FLAGS_RELEASE (-O3 -DNDEBUG) and -# CMAKE_CXX_FLAGS_DEBUG (-g). +# CMAKE_BUILD_TYPE PHLEX_ENABLE_IPO PHLEX_HIDE_SYMBOLS +# ───────────────── ─────────────── ───────────────── +# Release ON ON +# RelWithDebInfo ON ON +# Debug / sanitizer OFF OFF +# not set OFF OFF +# +# Automatic co-adjustment: PHLEX_HIDE_SYMBOLS defaults to ON whenever +# PHLEX_ENABLE_IPO is ON, even outside Release builds. LTO achieves its +# full potential only in combination with hidden symbols — without +# -fvisibility=hidden, -fno-semantic-interposition cannot be applied and the +# LTO optimizer must treat every exported symbol as potentially interposable. +# Setting IPO=ON therefore implies symbol hiding unless the user explicitly +# overrides PHLEX_HIDE_SYMBOLS=OFF after configure. +# +# -fno-semantic-interposition and -fno-plt are compile-level flags applied +# per-target at build time (not at configure time), so they automatically +# reflect the final option values regardless of how they were set. # # PHLEX_ENABLE_IPO (default ON for Release/RelWithDebInfo, OFF otherwise) -# When ON, enables interprocedural optimization (link-time optimization) for -# Release and RelWithDebInfo configurations via the -# CMAKE_INTERPROCEDURAL_OPTIMIZATION_* variables. +# When ON, enables interprocedural optimization (LTO) for Release and +# RelWithDebInfo configurations. LTO is safe with 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. # -# LTO is safe with symbol hiding: export attributes preserve the complete -# exported-symbol set; the linker cannot eliminate or rename any symbol that -# carries a default-visibility attribute. External plugins compiled without -# LTO link against the normal exported-symbol table and are unaffected. +# PHLEX_HIDE_SYMBOLS (default ON when PHLEX_ENABLE_IPO=ON or Release/RelWithDebInfo) +# 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() @@ -77,15 +91,12 @@ if(NOT APPLE) endif() # --------------------------------------------------------------------------- -# Interprocedural optimization (LTO) +# Interprocedural optimization (LTO) — defined first so its value can inform +# the PHLEX_HIDE_SYMBOLS default below. # --------------------------------------------------------------------------- cmake_policy(SET CMP0069 NEW) include(CheckIPOSupported) -# Derive a sensible default: enable LTO automatically for Release-class builds -# so that cmake -DCMAKE_BUILD_TYPE=Release "does the right thing" without -# requiring a separate -DPHLEX_ENABLE_IPO=ON. Debug/sanitizer/coverage builds -# keep the default OFF to preserve debuggability. if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") set(_phlex_ipo_default ON) else() @@ -95,12 +106,35 @@ endif() option( PHLEX_ENABLE_IPO [=[Enable interprocedural optimization (LTO) for Release and RelWithDebInfo -builds. Safe with symbol hiding because export macros preserve the complete -exported-symbol set. External plugins compiled without LTO are unaffected. -Defaults to ON when CMAKE_BUILD_TYPE is Release or RelWithDebInfo.]=] +builds. Defaults to ON when CMAKE_BUILD_TYPE is Release or RelWithDebInfo. +When enabled, PHLEX_HIDE_SYMBOLS defaults to ON as well, since LTO achieves +its full potential only with a bounded exported-symbol set.]=] "${_phlex_ipo_default}" ) +# --------------------------------------------------------------------------- +# Symbol hiding — derived after PHLEX_ENABLE_IPO so that requesting IPO +# automatically enables hiding by default (they work together for maximum +# effect). +# --------------------------------------------------------------------------- +if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$" OR PHLEX_ENABLE_IPO) + 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 and whenever PHLEX_ENABLE_IPO=ON, since LTO +achieves its full potential only with a bounded exported-symbol set.]=] + "${_phlex_hide_default}" +) + +# --------------------------------------------------------------------------- +# Activate LTO (if enabled and supported) +# --------------------------------------------------------------------------- if(PHLEX_ENABLE_IPO) check_ipo_supported( RESULT _phlex_ipo_supported @@ -114,6 +148,19 @@ if(PHLEX_ENABLE_IPO) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON) message(STATUS "Phlex: LTO enabled for Release and RelWithDebInfo builds") + if(NOT PHLEX_HIDE_SYMBOLS) + # The user explicitly set PHLEX_HIDE_SYMBOLS=OFF after the default was + # derived. The flags in phlex_apply_optimizations() self-adjust: LTO + # will be active but -fno-semantic-interposition will not be applied + # (it requires a bounded exported-symbol set). All other flags continue + # to apply normally. + message( + STATUS + "Phlex: PHLEX_ENABLE_IPO=ON with PHLEX_HIDE_SYMBOLS=OFF — " + "-fno-semantic-interposition will not be applied (requires a bounded " + "exported-symbol set). All other optimizations remain active." + ) + endif() else() message( WARNING From d3a57d97a6b43868a933086e42916355fc79a1ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:08:39 +0000 Subject: [PATCH 19/22] Force PHLEX_HIDE_SYMBOLS=ON when PHLEX_ENABLE_IPO=ON (not just default) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit option() only sets the cache default when the variable is not yet present, so an explicit -DPHLEX_HIDE_SYMBOLS=OFF on the command line bypassed the defaulting logic and produced the invalid combination in CMakeCache.txt. Fix: after both options are resolved from the cache, check for the PHLEX_ENABLE_IPO=ON + PHLEX_HIDE_SYMBOLS=OFF combination and use set(... FORCE) to correct PHLEX_HIDE_SYMBOLS to ON. A STATUS message explains the forced correction. CMakeCache.txt will now always show PHLEX_HIDE_SYMBOLS=ON when PHLEX_ENABLE_IPO=ON. Before: cmake ... -DPHLEX_HIDE_SYMBOLS=OFF -DCMAKE_BUILD_TYPE=Release → CMakeCache.txt: PHLEX_ENABLE_IPO=ON, PHLEX_HIDE_SYMBOLS=OFF ✗ After: cmake ... -DPHLEX_HIDE_SYMBOLS=OFF -DCMAKE_BUILD_TYPE=Release → STATUS "PHLEX_HIDE_SYMBOLS forced ON because PHLEX_ENABLE_IPO=ON" → CMakeCache.txt: PHLEX_ENABLE_IPO=ON, PHLEX_HIDE_SYMBOLS=ON ✓ Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- Modules/private/PhlexOptimization.cmake | 58 +++++++++++++++---------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake index e88919171..8e332ff25 100644 --- a/Modules/private/PhlexOptimization.cmake +++ b/Modules/private/PhlexOptimization.cmake @@ -50,13 +50,14 @@ # Debug / sanitizer OFF OFF # not set OFF OFF # -# Automatic co-adjustment: PHLEX_HIDE_SYMBOLS defaults to ON whenever -# PHLEX_ENABLE_IPO is ON, even outside Release builds. LTO achieves its -# full potential only in combination with hidden symbols — without -# -fvisibility=hidden, -fno-semantic-interposition cannot be applied and the -# LTO optimizer must treat every exported symbol as potentially interposable. -# Setting IPO=ON therefore implies symbol hiding unless the user explicitly -# overrides PHLEX_HIDE_SYMBOLS=OFF after configure. +# Automatic co-adjustment: PHLEX_HIDE_SYMBOLS is forced ON whenever +# PHLEX_ENABLE_IPO is ON, even if the user passes -DPHLEX_HIDE_SYMBOLS=OFF +# on the command line. LTO achieves its full potential only in combination +# with hidden symbols — without -fvisibility=hidden, +# -fno-semantic-interposition cannot be applied and the LTO optimizer must +# treat every exported symbol as potentially interposable. +# The enforcement uses set(... FORCE) after both options are resolved from +# the cache, so the corrected value is always reflected in CMakeCache.txt. # # -fno-semantic-interposition and -fno-plt are compile-level flags applied # per-target at build time (not at configure time), so they automatically @@ -127,11 +128,37 @@ 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 and whenever PHLEX_ENABLE_IPO=ON, since LTO -achieves its full potential only with a bounded exported-symbol set.]=] +Release/RelWithDebInfo builds and whenever PHLEX_ENABLE_IPO=ON. When +PHLEX_ENABLE_IPO=ON this option is forced ON regardless of the value passed on +the command line, since LTO achieves its full potential only with a bounded +exported-symbol set.]=] "${_phlex_hide_default}" ) +# --------------------------------------------------------------------------- +# Enforce option consistency: PHLEX_ENABLE_IPO=ON requires PHLEX_HIDE_SYMBOLS=ON. +# option() only sets the default when the cache variable is not yet present, so +# an explicit -DPHLEX_HIDE_SYMBOLS=OFF on the command line bypasses the default +# logic above. After both options are resolved from the cache we therefore +# check for the invalid/suboptimal combination and force-correct it. +# --------------------------------------------------------------------------- +if(PHLEX_ENABLE_IPO AND NOT PHLEX_HIDE_SYMBOLS) + message( + STATUS + "Phlex: PHLEX_HIDE_SYMBOLS forced ON because PHLEX_ENABLE_IPO=ON " + "(LTO achieves full potential only with a bounded exported-symbol set; " + "-fno-semantic-interposition requires hidden-by-default visibility)." + ) + set(PHLEX_HIDE_SYMBOLS + ON + CACHE BOOL + [=[Hide non-exported symbols in shared libraries (ON = curated API with +hidden-by-default visibility; OFF = all symbols visible). Forced ON because +PHLEX_ENABLE_IPO=ON.]=] + FORCE + ) +endif() + # --------------------------------------------------------------------------- # Activate LTO (if enabled and supported) # --------------------------------------------------------------------------- @@ -148,19 +175,6 @@ if(PHLEX_ENABLE_IPO) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON) message(STATUS "Phlex: LTO enabled for Release and RelWithDebInfo builds") - if(NOT PHLEX_HIDE_SYMBOLS) - # The user explicitly set PHLEX_HIDE_SYMBOLS=OFF after the default was - # derived. The flags in phlex_apply_optimizations() self-adjust: LTO - # will be active but -fno-semantic-interposition will not be applied - # (it requires a bounded exported-symbol set). All other flags continue - # to apply normally. - message( - STATUS - "Phlex: PHLEX_ENABLE_IPO=ON with PHLEX_HIDE_SYMBOLS=OFF — " - "-fno-semantic-interposition will not be applied (requires a bounded " - "exported-symbol set). All other optimizations remain active." - ) - endif() else() message( WARNING From ad2c0abc2ec9b5fe8dbc1db5d6490a7193d8ad16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:13:09 +0000 Subject: [PATCH 20/22] Revert forced PHLEX_HIDE_SYMBOLS correction; make options fully independent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert the set(FORCE) that prevented PHLEX_ENABLE_IPO=ON + PHLEX_HIDE_SYMBOLS=OFF: this combination is valid and essential for benchmarking the LTO benefit with and without symbol hiding. All four combinations are now fully supported: PHLEX_HIDE_SYMBOLS=ON PHLEX_ENABLE_IPO=ON → LTO + -fno-semantic-interposition (maximum) PHLEX_HIDE_SYMBOLS=OFF PHLEX_ENABLE_IPO=ON → LTO only (benchmark comparison case) PHLEX_HIDE_SYMBOLS=ON PHLEX_ENABLE_IPO=OFF → -fno-semantic-interposition only PHLEX_HIDE_SYMBOLS=OFF PHLEX_ENABLE_IPO=OFF → no special flags (debug/default) Both options now default independently from CMAKE_BUILD_TYPE (ON for Release/RelWithDebInfo, OFF otherwise) with no cross-dependency in the defaulting logic. The per-target flags in phlex_apply_optimizations() already self-adjust correctly to whichever combination is in effect. Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- Modules/private/PhlexOptimization.cmake | 78 +++++++++---------------- 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/Modules/private/PhlexOptimization.cmake b/Modules/private/PhlexOptimization.cmake index 8e332ff25..a0528d7d2 100644 --- a/Modules/private/PhlexOptimization.cmake +++ b/Modules/private/PhlexOptimization.cmake @@ -1,7 +1,7 @@ # 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 -# ensures their defaults are mutually consistent. +# documents how they interact. # # Two flags are applied (subject to compiler support and platform): # @@ -50,27 +50,27 @@ # Debug / sanitizer OFF OFF # not set OFF OFF # -# Automatic co-adjustment: PHLEX_HIDE_SYMBOLS is forced ON whenever -# PHLEX_ENABLE_IPO is ON, even if the user passes -DPHLEX_HIDE_SYMBOLS=OFF -# on the command line. LTO achieves its full potential only in combination -# with hidden symbols — without -fvisibility=hidden, -# -fno-semantic-interposition cannot be applied and the LTO optimizer must -# treat every exported symbol as potentially interposable. -# The enforcement uses set(... FORCE) after both options are resolved from -# the cache, so the corrected value is always reflected in CMakeCache.txt. +# Both options can be overridden independently on the command line: # -# -fno-semantic-interposition and -fno-plt are compile-level flags applied -# per-target at build time (not at configure time), so they automatically -# reflect the final option values regardless of how they were set. +# -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 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. +# 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 when PHLEX_ENABLE_IPO=ON or Release/RelWithDebInfo) +# 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. @@ -108,17 +108,17 @@ option( PHLEX_ENABLE_IPO [=[Enable interprocedural optimization (LTO) for Release and RelWithDebInfo builds. Defaults to ON when CMAKE_BUILD_TYPE is Release or RelWithDebInfo. -When enabled, PHLEX_HIDE_SYMBOLS defaults to ON as well, since LTO achieves -its full potential only with a bounded exported-symbol set.]=] +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 — derived after PHLEX_ENABLE_IPO so that requesting IPO -# automatically enables hiding by default (they work together for maximum -# effect). +# 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)$" OR PHLEX_ENABLE_IPO) +if(CMAKE_BUILD_TYPE MATCHES "^(Release|RelWithDebInfo)$") set(_phlex_hide_default ON) else() set(_phlex_hide_default OFF) @@ -128,37 +128,13 @@ 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 and whenever PHLEX_ENABLE_IPO=ON. When -PHLEX_ENABLE_IPO=ON this option is forced ON regardless of the value passed on -the command line, since LTO achieves its full potential only with a bounded -exported-symbol set.]=] +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}" ) -# --------------------------------------------------------------------------- -# Enforce option consistency: PHLEX_ENABLE_IPO=ON requires PHLEX_HIDE_SYMBOLS=ON. -# option() only sets the default when the cache variable is not yet present, so -# an explicit -DPHLEX_HIDE_SYMBOLS=OFF on the command line bypasses the default -# logic above. After both options are resolved from the cache we therefore -# check for the invalid/suboptimal combination and force-correct it. -# --------------------------------------------------------------------------- -if(PHLEX_ENABLE_IPO AND NOT PHLEX_HIDE_SYMBOLS) - message( - STATUS - "Phlex: PHLEX_HIDE_SYMBOLS forced ON because PHLEX_ENABLE_IPO=ON " - "(LTO achieves full potential only with a bounded exported-symbol set; " - "-fno-semantic-interposition requires hidden-by-default visibility)." - ) - set(PHLEX_HIDE_SYMBOLS - ON - CACHE BOOL - [=[Hide non-exported symbols in shared libraries (ON = curated API with -hidden-by-default visibility; OFF = all symbols visible). Forced ON because -PHLEX_ENABLE_IPO=ON.]=] - FORCE - ) -endif() - # --------------------------------------------------------------------------- # Activate LTO (if enabled and supported) # --------------------------------------------------------------------------- From 421f4ca03d9e3a87ab3702d2f0c7cf9d55f89030 Mon Sep 17 00:00:00 2001 From: Chris Green Date: Tue, 10 Mar 2026 16:30:08 -0500 Subject: [PATCH 21/22] Specify default opt/debug options for different `CMAKE_BUILD_TYPE`s - May be overridden from CMake command line, environment, etc. --- CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ca459c00..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) From 9ec4e66e12fab3ff0a0f55eb75623a0dad47a07d Mon Sep 17 00:00:00 2001 From: Chris Green Date: Tue, 10 Mar 2026 16:32:24 -0500 Subject: [PATCH 22/22] Enable compile/link time profiling --- CMakeLists.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17454494d..b925dab9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,27 @@ option(ENABLE_TSAN "Enable Thread Sanitizer" OFF) option(ENABLE_ASAN "Enable Address Sanitizer" OFF) option(PHLEX_USE_FORM "Enable experimental integration with FORM" OFF) option(ENABLE_COVERAGE "Enable code coverage instrumentation" OFF) +option(ENABLE_BUILD_PROFILING "Enable monitoring of compile and link operations" OFF) + +# ############################################################################## +# Enable collection of compile/link statistics. +# +# If lld is available but not default for the current toolset, then use +# `-DCMAKE_LINKER_TYPE=LLD` +if (ENABLE_BUILD_PROFILING) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + add_compile_options("-ftime-trace") + endif() + if(CMAKE_CXX_COMPILER_LINKER_ID STREQUAL "LLD") + message(STATUS "LLD detected (Phlex build) - Enabling tracing") + add_link_options("-Wl,--time-trace") + add_link_options("-Wl,--Map=phlex_link.map") + add_link_options("-Wl,--print-archive-stats=-") + endif() +endif() +# ############################################################################## add_compile_options( -Wall