Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1782778
feat: Add C++20 module support infrastructure (prototype)
wdconinc Dec 20, 2025
eeeca16
feat: Implement C++20 module template generation (80% complete)
wdconinc Dec 20, 2025
9219cdd
fix: Implement namespace-aware module export generation (Strategy 2)
wdconinc Dec 20, 2025
8aec23b
fix: Correct CollectionIterator naming pattern
wdconinc Dec 20, 2025
528d5c4
refactor: Move Pythonizations implementation to separate compilation …
wdconinc Dec 20, 2025
a9141d4
fix: Add global namespace prefix for non-namespaced types in modules
wdconinc Dec 20, 2025
59a0e30
feat: Move podio.core module to src/ and enable proper installation
wdconinc Dec 20, 2025
e5cf1a9
ci: Enable C++ modules in workflow for gcc15 builds
wdconinc Dec 20, 2025
2aab78a
docs: Add comprehensive C++20 modules user documentation
wdconinc Dec 20, 2025
e69da7c
Remove duplicate podio_core_module.ixx from tests directory
wdconinc Dec 20, 2025
c5ab024
Clean up license header in podio_core_module.ixx
wdconinc Dec 20, 2025
5a049b7
Add comprehensive test suite for C++ modules functionality
wdconinc Dec 20, 2025
dd06c41
Add C++ modules test infrastructure
wdconinc Dec 20, 2025
60f19ea
Add experimental test for direct module imports in .cpp files
wdconinc Dec 20, 2025
6a68383
test: remove redundant C++ module tests, keep only import test
wdconinc Dec 20, 2025
3d37bb6
Disable module import test due to compiler stdlib issues
wdconinc Dec 20, 2025
8db7160
fix: hide Obj, Data, CollectionData in modules
wdconinc Dec 26, 2025
88c80f1
docs: podio.core: generalize from ROOT- to I/O-independent functionality
wdconinc Dec 26, 2025
fcbc75c
fix: cpp_generator._build_type_info -> generator_utils.qualified_for_…
wdconinc Dec 27, 2025
14e46d3
feat: add tests/test_module_import
wdconinc Dec 27, 2025
5dc9a50
fix: pre-commit
wdconinc Dec 27, 2025
048ec04
fix: add Threads dependency to podioConfig
wdconinc Dec 27, 2025
621116a
fix: pre-commit with -DPODIO_ENABLE_CXX_MODULES=ON
wdconinc Dec 27, 2025
61d424f
fix: clang-format
wdconinc Dec 27, 2025
d5d9138
fix: pylint and flake8 style
wdconinc Dec 27, 2025
739b12e
fix: style
wdconinc Dec 27, 2025
2e991ad
fix: remove generation, integration, unit tests
wdconinc Dec 27, 2025
6c6dafb
fix: disable modules in pre-commit again
wdconinc Dec 27, 2025
dfde5d6
fix: consistently use PODIO_ENABLE_CXX_MODULES (incl. in CI)
wdconinc Dec 27, 2025
0fac8aa
fix: update docs to avoid podio_MODULES_AVAILABLE
wdconinc Dec 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
-DCMAKE_CXX_FLAGS=" -fdiagnostics-color=always -Werror "\
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DPODIO_ENABLE_SCHEMA_EVOLUTION_TESTS=ON \
-DPODIO_ENABLE_CXX_MODULES=OFF \
-DUSE_EXTERNAL_CATCH2=OFF
ln -s $(pwd)/compile_commands.json ../
cd ..
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
-DPODIO_RUN_STRACE_TEST=$([[ ${{ matrix.LCG }} == LCG_104/* ]] && echo "OFF" || echo "ON") \
-DCMAKE_INSTALL_PREFIX=../install \
-DCMAKE_CXX_STANDARD=$([[ ${{ matrix.LCG }} == *-gcc15-* ]] && echo "23" || echo "20") \
-DPODIO_ENABLE_CXX_MODULES=$([[ ${{ matrix.LCG }} == *-gcc15-* ]] && echo "ON" || echo "OFF") \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_FLAGS=" -fdiagnostics-color=always -Werror -Wno-error=deprecated-declarations " \
-DUSE_EXTERNAL_CATCH2=AUTO \
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ podio_python_setup()
#--- enable podio macros--------------------------------------------------------
include(cmake/podioMacros.cmake)

#--- enable C++20 module support (if requested) --------------------------------
include(cmake/podioModules.cmake)

# optionally build with SIO -------------------------------------------------
if(ENABLE_SIO)
find_package( SIO REQUIRED)
Expand Down
1 change: 1 addition & 0 deletions cmake/podioConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ set(PODIO_IO_HANDLERS "@PODIO_IO_HANDLERS@")

include(CMakeFindDependencyMacro)
find_dependency(ROOT @ROOT_VERSION@)
find_dependency(Threads REQUIRED)
if(NOT "@REQUIRE_PYTHON_VERSION@" STREQUAL "")
find_dependency(Python @REQUIRE_PYTHON_VERSION@ COMPONENTS Interpreter Development)
else()
Expand Down
23 changes: 22 additions & 1 deletion cmake/podioMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ function(PODIO_GENERATE_DATAMODEL datamodel YAML_FILE RETURN_HEADERS RETURN_SOUR
set(VERSION_ARG "--datamodel-version=${ARG_VERSION}")
endif()

# Check if C++20 modules should be generated
set(MODULES_ARG "")
if(PODIO_ENABLE_CXX_MODULES)
set(MODULES_ARG "--enable-modules")
endif()
Comment on lines +138 to +142
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering whether this should be an explicit argument to the datamodel generation. For my understanding: This requires podio.core to be available as a module? Or would it still be possible to have podio built without modules and have the datamodel compiled into a module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now the data model module definition (from python/templates/datamodel_module.ixx.jinja2) uses just regular includes, not another module import. That means that it is not necessary to have a podio.core module in order to use the edm4hep.datamodel module.

The only thing from podio that is re-exported is:

export namespace podio {
  using podio::CollectionBase;
  using podio::ICollectionProvider;
  using podio::SchemaEvolution;
  using podio::SchemaVersionT;
}

That is significantly less than what's in src/podio_core_module.ixx which turns into the podio.core module.

As long as we don't re-export a different entity under the same name this is fine. They are ultimately just using statements.


# Make sure that we re run the generation process every time either the
# templates or the yaml file changes.
include(${podio_PYTHON_DIR}/templates/CMakeLists.txt)
Expand All @@ -155,7 +161,7 @@ function(PODIO_GENERATE_DATAMODEL datamodel YAML_FILE RETURN_HEADERS RETURN_SOUR
message(STATUS "Creating '${datamodel}' datamodel")
# we need to bootstrap the data model, so this has to be executed in the cmake run
execute_process(
COMMAND ${Python_EXECUTABLE} ${podio_PYTHON_DIR}/podio_class_generator.py ${CLANG_FORMAT_ARG} ${SCHEMA_EVOLUTION_ARG} ${UPSTREAM_EDM_ARG} ${YAML_FILE} ${ARG_OUTPUT_FOLDER} ${datamodel} ${ARG_IO_BACKEND_HANDLERS} ${LANGUAGE_ARG} ${VERSION_ARG} ${OLD_DESCRIPTION_ARG}
COMMAND ${Python_EXECUTABLE} ${podio_PYTHON_DIR}/podio_class_generator.py ${CLANG_FORMAT_ARG} ${SCHEMA_EVOLUTION_ARG} ${UPSTREAM_EDM_ARG} ${YAML_FILE} ${ARG_OUTPUT_FOLDER} ${datamodel} ${ARG_IO_BACKEND_HANDLERS} ${LANGUAGE_ARG} ${VERSION_ARG} ${MODULES_ARG} ${OLD_DESCRIPTION_ARG}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE podio_generate_command_retval
)
Expand Down Expand Up @@ -210,6 +216,21 @@ function(PODIO_ADD_DATAMODEL_CORE_LIB lib_name HEADERS SOURCES)
CXX_CLANG_TIDY "" # Do not run clang-tidy on generated sources
# TODO: Update generation to generate compliant code already
)

# Add C++20 module interface if it was generated
if(PODIO_ENABLE_CXX_MODULES)
# Check if module files were generated
include(${ARG_OUTPUT_FOLDER}/podio_generated_files.cmake)
if(DEFINED module_files AND module_files)
message(STATUS "Adding C++20 module interface to ${lib_name}")
target_sources(${lib_name}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${ARG_OUTPUT_FOLDER}
FILES ${module_files}
)
endif()
endif()
endfunction()


Expand Down
99 changes: 99 additions & 0 deletions cmake/podioModules.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#---------------------------------------------------------------------------------------------------
# CMake support for C++20 modules in podio
#
# This file provides macros and options for generating and using C++20 module interfaces
# for podio-generated datamodels.
#---------------------------------------------------------------------------------------------------

# Option to enable C++20 module generation
option(PODIO_ENABLE_CXX_MODULES "Generate C++20 module interface files (.ixx) for datamodels" OFF)

# Check if modules are actually supported
if(PODIO_ENABLE_CXX_MODULES)
# Check CMake version
if(CMAKE_VERSION VERSION_LESS 3.29)
message(WARNING "C++20 modules require CMake 3.29 or later (found ${CMAKE_VERSION}). Disabling module support.")
set(PODIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to CMake version" FORCE)
endif()

# Check generator
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
message(WARNING "C++20 modules are not supported with the Unix Makefiles generator. Please use Ninja. Disabling module support.")
set(PODIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to generator" FORCE)
endif()

# Check compiler support
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
message(WARNING "C++20 modules require GCC 14 or later (found ${CMAKE_CXX_COMPILER_VERSION}). Disabling module support.")
set(PODIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to compiler version" FORCE)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
message(WARNING "C++20 modules require Clang 18 or later (found ${CMAKE_CXX_COMPILER_VERSION}). Disabling module support.")
set(PODIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to compiler version" FORCE)
endif()
else()
message(WARNING "C++20 modules have only been tested with GCC 14+ and Clang 18+. Found ${CMAKE_CXX_COMPILER_ID}. Proceed at your own risk.")
endif()
endif()

if(PODIO_ENABLE_CXX_MODULES)
message(STATUS "C++20 module support is ENABLED for podio datamodels")
message(STATUS " - CMake version: ${CMAKE_VERSION}")
message(STATUS " - Generator: ${CMAKE_GENERATOR}")
message(STATUS " - Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
else()
message(STATUS "C++20 module support is DISABLED for podio datamodels")
endif()

#---------------------------------------------------------------------------------------------------
# PODIO_ADD_MODULE_INTERFACE( target module_name module_file )
#
# Add a C++20 module interface to a target
#
# Arguments:
# target - The target to which the module should be added
# module_name - The name of the module (e.g., "podio.core")
# module_file - The .ixx file implementing the module interface
#---------------------------------------------------------------------------------------------------
function(PODIO_ADD_MODULE_INTERFACE target module_name module_file)
if(NOT PODIO_ENABLE_CXX_MODULES)
return()
endif()

message(STATUS "Adding C++20 module '${module_name}' to target '${target}'")

# Add the module file to the target as a CXX_MODULES file set
# Use PUBLIC so the module gets installed and can be used by downstream projects
target_sources(${target}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${module_file}
)
endfunction()

#---------------------------------------------------------------------------------------------------
# PODIO_GENERATE_MODULE_INTERFACE( datamodel OUTPUT_FILE )
#
# Generate a C++20 module interface for a podio datamodel
# This is currently a placeholder - actual generation will be added later
#
# Arguments:
# datamodel - Name of the datamodel (e.g., "TestDataModel")
# OUTPUT_FILE - Variable name to store the generated .ixx file path
#---------------------------------------------------------------------------------------------------
function(PODIO_GENERATE_MODULE_INTERFACE datamodel OUTPUT_FILE)
if(NOT PODIO_ENABLE_CXX_MODULES)
set(${OUTPUT_FILE} "" PARENT_SCOPE)
return()
endif()

# For now, just set the expected output location
# Actual generation will be implemented in the template
set(module_file "${CMAKE_CURRENT_BINARY_DIR}/${datamodel}_module.ixx")
set(${OUTPUT_FILE} ${module_file} PARENT_SCOPE)

message(STATUS "Will generate module interface: ${module_file}")
endfunction()
Loading
Loading