[cmake] modernize and simplify RConfigure generation - #23261
ferdymercury wants to merge 5 commits into
Conversation
|
A slightly related issue ROOT-8061 |
|
Unfortunately, for this to go forward, we need CMake 3.27 I will continue later on with RConfig.hxx that it has a lot of definitions that can be solved at config time and thus is movable to RConfigure.h. |
8aed3d4 to
d6304cb
Compare
Test Results 16 files 16 suites 2d 7h 55m 48s ⏱️ Results for commit d2647f1. ♻️ This comment has been updated with latest results. |
84076bf to
a80d016
Compare
1b18b0b to
5e862a1
Compare
inbuilt configure file and mention also current cplusplus not just ROOT in error message
d467a3c to
26c9477
Compare
via header guards
26c9477 to
99482fc
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The new generation logic currently emits invalid/incorrect preprocessor content (unquoted path macros, a wrong feature-variable reference, and an MSVC compiler flag treated as a macro), which can break builds.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR modernizes how RConfigure.h is generated by replacing the configure_file()-driven config/RConfigure.in template with a CMake target/property-driven approach (via an INTERFACE library and file(GENERATE)), as a first step toward depending on a config-time target instead of a global header.
Changes:
- Remove the
config/RConfigure.intemplate-based generation path. - Generate
ginclude/RConfigure.hfromRConfigureDefsINTERFACE_COMPILE_DEFINITIONSusingfile(GENERATE). - Introduce a new
ROOTdefsinterface target intended to carry the configuration definitions to dependents.
File summaries
| File | Description |
|---|---|
| config/RConfigure.in | Removes the legacy configure_file() template used to produce RConfigure.h. |
| cmake/modules/RootConfiguration.cmake | Adds RConfigureDefs/ROOTdefs and switches to file(GENERATE) for RConfigure.h creation. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| $<$<CXX_COMPILER_ID:MSVC>:-Zc:__cplusplus> | ||
| ) | ||
|
|
||
| file(GENERATE |
There was a problem hiding this comment.
I am not quite seeing (yet?) the simplification. (The boiler plate could technically be completely removed from the original with a macro and a list of things to test/set).
There is a significant difference between configure_file and file(GENERATE which may or may not have drastic practical consequence. The timing of the file generation is different (Configure Phase vs Generation Phase) and I am concerned that the file will be touched/regenerated at each re-invocation of cmake (leading to a full rebuild each time !?).
I am also confused by configure_file is not the 'right' tool to generate a file containing configuration information. Is there a updated recommendation from KitWare?
There was a problem hiding this comment.
I am concerned that the file will be touched/regenerated at each re-invocation of cmake (leading to a full rebuild each time !?).
Nope, see https://cmake.org/cmake/help/latest/command/file.html.
Generated files are modified and their timestamp updated on subsequent cmake runs only if their content is changed.
I am also confused by
configure_fileis not the 'right' tool to generate a file containing configuration information. Is there a updated recommendation from KitWare?
Relying on global headers just for expressing "defines" is in general a bad idea: it's hard to express the dependency. The 'modern CMake' way is target compile definitions. This allows you to express dependencies. With global headers, it's harder
See
https://cmake.org/cmake/help/latest/guide/tutorial/In-Depth%20CMake%20Target%20Commands.html
The target_compile_definitions() command describes compile definitions as target properties. It is the most common mechanism for communicating build configuration information to the source code itself. As with all properties, the scope keywords apply as we have discussed.
I am not quite seeing (yet?) the simplification.
The main advantage is that now you depend on a target rather than on a global header. This allows you to better track dependencies, as well as to do better intertwining of ROOT from other libraries if you just need some compile time definitions, so you do not need to link against Core, or otherwise do global target_include_directory but then that misses dependency tracking (if global header is changed, CMake does not know that it should rebuild)
See eg #23270
There was a problem hiding this comment.
which may or may not have drastic practical consequence
a potential advantage of targets vs headers is that, rather than having to preprocess/parse a 400 lines long header file (RConfigure.h) for every compilation in ROOT, with a lot of ifdefs else branches, the compiler already gets the resolved defines via the -D flag, so the ifdef conditions are only checked once at configure time and never again. The difference will though probably be neglibible in building time.
This Pull request:
Changes or fixes:
This is a first step towards later using the defined target to remove dependencies with a global header file in some external / builtins targets, it's better to just depend on a config time target if one just needs the ROOT global defs.
Besides, 150 lines of boilerplate code are removed.
Checklist: