Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ff9d9e2
feat: Add C++20 module support infrastructure (prototype)
wdconinc Dec 20, 2025
1490753
feat: Implement C++20 module template generation (80% complete)
wdconinc Dec 20, 2025
2917291
fix: Implement namespace-aware module export generation (Strategy 2)
wdconinc Dec 20, 2025
ab84c1a
fix: Correct CollectionIterator naming pattern
wdconinc Dec 20, 2025
bd7ae87
refactor: Move Pythonizations implementation to separate compilation …
wdconinc Dec 20, 2025
9a10f3e
fix: Add global namespace prefix for non-namespaced types in modules
wdconinc Dec 20, 2025
18c1c7d
feat: Move podio.core module to src/ and enable proper installation
wdconinc Dec 20, 2025
be8253f
ci: Enable C++ modules in workflow for gcc15 builds
wdconinc Dec 20, 2025
a30d6ba
docs: Add comprehensive C++20 modules user documentation
wdconinc Dec 20, 2025
f335bd2
Remove duplicate podio_core_module.ixx from tests directory
wdconinc Dec 20, 2025
1e273cb
Clean up license header in podio_core_module.ixx
wdconinc Dec 20, 2025
d749f20
Add comprehensive test suite for C++ modules functionality
wdconinc Dec 20, 2025
7c3ff2b
Add C++ modules test infrastructure
wdconinc Dec 20, 2025
411fe7f
Add experimental test for direct module imports in .cpp files
wdconinc Dec 20, 2025
4207fd1
test: remove redundant C++ module tests, keep only import test
wdconinc Dec 20, 2025
f9c244b
Disable module import test due to compiler stdlib issues
wdconinc Dec 20, 2025
4d4173c
fix: hide Obj, Data, CollectionData in modules
wdconinc Dec 26, 2025
36aaced
docs: podio.core: generalize from ROOT- to I/O-independent functionality
wdconinc Dec 26, 2025
ad8256a
fix: cpp_generator._build_type_info -> generator_utils.qualified_for_…
wdconinc Dec 27, 2025
84d80d8
feat: add tests/test_module_import
wdconinc Dec 27, 2025
b013c2f
fix: pre-commit
wdconinc Dec 27, 2025
67fa013
fix: add Threads dependency to podioConfig
wdconinc Dec 27, 2025
c73b79d
fix: pre-commit with -DPODIO_ENABLE_CXX_MODULES=ON
wdconinc Dec 27, 2025
adcbf63
fix: clang-format
wdconinc Dec 27, 2025
a8bce2e
fix: pylint and flake8 style
wdconinc Dec 27, 2025
49f661d
fix: style
wdconinc Dec 27, 2025
c8f0108
fix: remove generation, integration, unit tests
wdconinc Dec 27, 2025
328fffb
fix: consistently use PODIO_ENABLE_CXX_MODULES (incl. in CI)
wdconinc Dec 27, 2025
ed5ce17
fix: update docs to avoid podio_MODULES_AVAILABLE
wdconinc Dec 27, 2025
a3ed905
Remove cmake arguments that are covered by presets
tmadlener Mar 17, 2026
d21f2f6
fix: suppress cppcheck errors for .ixx module files and pre-existing …
jmcarcell Jul 19, 2026
46e13eb
fix: exclude .ixx files and module import tests from clang-tidy
jmcarcell Jul 19, 2026
1c33f6e
fix: undef PODIO_JSON_OUTPUT in module interfaces to avoid TU-local n…
jmcarcell Jul 19, 2026
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 .cppcheck-suppressions.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
noExplicitConstructor:*
*:*.ixx
unusedFunction:*
missingInclude:*
missingIncludeSystem:*
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
--preset ci-build \
-DENABLE_JULIA=ON \
-DENABLE_ARROW=ON \
-DPODIO_ENABLE_CXX_MODULES=ON \
-DUSE_EXTERNAL_CATCH2=OFF
ln -s build/compile_commands.json compile_commands.json
echo "::endgroup::"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:
-DENABLE_RNTUPLE=$([[ ${{ matrix.LCG }} == LCG_104/* ]] && echo "OFF" || echo "ON") \
-DPODIO_RUN_STRACE_TEST=$([[ ${{ matrix.LCG }} == LCG_104/* ]] && echo "OFF" || echo "ON") \
-DCMAKE_INSTALL_PREFIX=$(pwd)/install \
-DCMAKE_CXX_STANDARD=$([[ ${{ matrix.LCG }} == *-gcc15-* ]] && echo "23" || echo "20") \
-DPODIO_ENABLE_CXX_MODULES=$([[ ${{ matrix.LCG }} == *-gcc15-* ]] && echo "ON" || echo "OFF") \
-DUSE_EXTERNAL_CATCH2=AUTO
echo "::endgroup::"
echo "::group::Build"
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ repos:
name: clang-tidy
entry: .github/scripts/clang-tidy-hook
types: [c++]
exclude: (tests/(datamodel|src|extra_code)/.*(h|cc)|podioVersion.in.h)
exclude: (tests/(datamodel|src|extra_code)/.*(h|cc)|podioVersion.in.h|.*\.ixx|tests/test_module_import\.cpp)
language: system
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,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(Python3 @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
Copy Markdown
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
Copy Markdown
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 ${Python3_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 ${Python3_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 @@ -211,6 +217,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