Repository navigation
[rootcling] Classify LinkDefs by basename in callbacks - #23730
agourakis82 wants to merge 3 commits into
Conversation
Directory names containing LinkDef must not turn ordinary included headers into selection files. Otherwise the callback can collect an internal relative include or lose a required public include. Use basenames only for classification and keep emitted paths intact. Cover both directory cases and the existing nested clear/lock behavior. Related to root-project#23640. The reporter's actual prefix remains unknown. Assisted-by: codex:GPT 6.1 Sol
Test Results 24 files 24 suites 4d 0h 27m 35s ⏱️ For more details on these failures, see this check. Results for commit b126049. |
|
I am a bit confused. The PR title and example do not seem to match the tests added. In particular on the surface I do not see how only looking at the basename of |
|
You're right — taking the basename of execution_defs.h alone doesn't explain it. I should have made the example clearer. The important part is the file doing the include. For example, LinkDefDirectory/Wrapper.h is an ordinary header, but the callback can treat it as a LinkDef because it checks the whole path. It then records that header's internal includes as though they came from a selection file. That's what the smaller tests exercise. The patch checks the basenames of both files, while keeping the original spelling for emitted includes. The nested-LinkDef test makes sure the existing clear/lock behavior still works. I also want to be careful about the connection to the original issue: the LinkDefCache setup demonstrates this bug, but it isn't the reporter's environment. I haven't established that this was the cause of their failure. |
Integrate upstream c4011b2 while preserving the reviewed rootcling correction and its regressions. The merge tree is b36dc99, identical to the combined tree validated by native Slurm job 16772 and strict audit 16775: two required baseline failures, the nested control passing, and 12 selected CTest entries passing with the correction. The historical PyROOT and DistRDF CI failures also occur without this patch. Fresh hosted CI on this combined tree remains a separate gate. No test or workflow is weakened. Assisted-by: codex:GPT-6
| @@ -0,0 +1,3 @@ | |||
| #ifndef __ROOTCLING__ | |||
| #error "Headers collected after a nested LinkDef must not be emitted directly." | |||
There was a problem hiding this comment.
This files seems explicitly included in the file passed to rootcling, why is it an error that it is parsed by rootcling?
| # Directory names must not make ordinary headers look like LinkDef files. | ||
| ROOTTEST_GENERATE_DICTIONARY(includeDirectoryDict | ||
| includeDirectory.h | ||
| LINKDEF includeDirectoryLinkDef.h) | ||
|
|
||
| ROOTTEST_GENERATE_DICTIONARY(includeDirectoryFromSelectionDict | ||
| LINKDEF includeDirectoryFromSelectionLinkDef.h) | ||
|
|
||
| ROOTTEST_GENERATE_DICTIONARY(includeNestedDict | ||
| includeNested.h | ||
| LINKDEF NestedSelection/OuterLinkDef.h) | ||
|
|
There was a problem hiding this comment.
The test is not yet verifying if the intended dictionary where actually generated.
There was a problem hiding this comment.
I've added an explicit check in 9694854, using assertIncludeDictionary.C. Each case starts a fresh ROOT process and loads the requested dictionary library. It then looks up the compiled class registration with TClassTable::GetDictNorm and checks HasDictionary() and the class name.
Starting a fresh process also prevents a dictionary loaded by another test from hiding a missing registration. This should check that the intended dictionary is present, rather than just that generation completed successfully.
Load each generated library in a fresh ROOT process and require the expected compiled dictionary registration. Connect runtime checks to their dictionary generation fixtures and clarify the selection-header guards. Assisted-by: Codex:GPT-6.1-Sol
|
You're right — rootcling is supposed to parse After.h. My explanation mixed up the two stages. The guard checks the later compilation of the generated dictionary C++, where this selection-only header should not appear as a direct include. I've clarified that distinction in the comments in 9694854. |
This Pull request:
Related to #23640. It fixes a demonstrated include-provenance failure; the
reporter's actual installation prefix and full environment remain unknown.
Changes or fixes:
The inclusion callback currently applies the LinkDef filename heuristic to
whole paths. An ordinary header under a directory containing
LinkDefcantherefore be mistaken for a selection file, causing internal relative includes
to leak into the generated dictionary or a required include to be lost.
Classify the current and included files by basename in this callback, retaining
the original path for emitted includes. The global helper and other callers
are unchanged. Add two failing-before/passing-after dictionary compilation
tests and an explicit nested-LinkDef control for the existing clear/lock logic.
Native Linux C++23 validation:
c4011b297ee1(2026-10-24), after theCppInterOp update: GCC 15.3, LLVM 22.1.8, C++23. Both directory regressions
fail with the original callback and pass with the correction; the nested
control passes in both. All 12 selected CTest entries pass after the fix.
bf65bcfe0162, GCC 15.3, LLVM 22.1.8: 12 selected CTest entriespass. Separate disposable clear/lock mutations make the nested test fail;
restoring the source makes the selected tests pass again.
fix; all 12 selected entries pass after it. Each selection contains three
added tests, eight existing compatibility tests and one build fixture.
Thing.hpp/LinkDef.hexample compiles before and after underordinary paths. With copied GCC headers explicitly prioritized using
-Iunder
LinkDefCache, the original generator emitsexecution_defs.handcompilation fails; the corrected generator's output compiles.
These are minimal source builds with runtime C++ modules and PyROOT disabled,
not the reporter's complete NixOS installation or a conda-forge recipe rebuild.
The marker case is a controlled diagnostic with additional
-Iarguments,not an exact reproduction of the reporter's command or prefix. Earlier setup
attempts stopped for missing
crypt.hand an ineffective marker-path control;the final 6.40.04 gate reused the preserved baseline build after correcting
those setup issues and checking source and binary identities. The full suite,
other platforms and runtime modules have not been validated.
A fresh upstream CI execution and maintainer review remain pending.
Follow-up regression checks (
9694854e): each generated library is explicitlyloaded in a fresh ROOT process and must register the intended compiled class.
The selection-only header guards now explain rootcling parsing versus the
later compilation of generated dictionary C++.
Supplemental validation on ROOT 6.40.04 / LLVM 20.1.8 / GCC 15.3 (C++23): all
three generation, shared-library compilation and runtime checks pass. Missing
class controls fail. Changing the selected class while keeping the library
name permits generation and compilation but fails the runtime assertion;
restoring the selection passes again. This follow-up has not been rebuilt at
the exact current ROOT head or run through the official CMake/CTest fixtures.
Official CI for this follow-up remains pending.
Checklist:
AI assistance: OpenAI Codex assisted with diagnosis, implementation, tests and
validation; model label supplied by the author: GPT-6.1-Sol. No independent
provider approval is claimed.
Assisted-by: Codex:GPT-6.1-Sol