[DEV][GENERAL] Why PCM files store pull path to where they were generated


ROOT Version: 6.14.02
Platform: Archlinux x86_64
Compiler: GCC (8.6.2) / CLANG (6.0.1)


Any PCM file generated by ROOT (or any ROOT based software) stores full path to place where that PCM were generated. And after installation these files usually located in other place (and actually the source / build directory usually is deleted). Why they need this information?

P.S. I’m after the so-called “reproducible” builds. Also I make Archlinux packages of some science software (ROOT, GEANT4, as examples).


WBR, Vladimir Lomov

@vp1981, it is the same situation for PCH, because it also store its build information. Historical reason is that PCH and implicit C++ modules are not intended to be relocated.

Hello,

then they shouldn’t be installed, i.e. when one runs make install (or equivalently cmake --build . --target install). But then if they are not installed they are useless. I came to this conclusion and I stuck, why someone would do this? Is this by design? If yes, then ROOT by design isn’t supposed to be installed as a distribution package. And then it is useless to distribute precompiled packages because they contain PCM files (with, of course, useless paths in them).

@vp1981 I wanted to ask how do you build root? Are we are talking here about PCM files, which are ROOT C++ modules, which can be enabled as explicit modules using -Dcxxmodules=ON or as runtime modules -Druntime_cxxmodules=ON?
Or you are talking about X_rdict.pcm, which suppose to provide data to serialize classes, without having to parsing headers?

Before PCH was not relocatable, but now PCH is, but clang is still putting some pieces of path info inside (for diagnostic reasons).

Hello,

That’s interesting question. Until now I didn’t thought about these options (I saw a little about C++ modules and assumed that these options are related to this, but as this feature is not standardized I decided not to touch OFF value of these options). In usual build these options are off (OFF) according to CMakeCache.txt:

build $ grep 'cxxmodules' CMakeCache.txt
cxxmodules:BOOL=OFF
runtime_cxxmodules:BOOL=OFF

Yes, exactly them:

$ cd $HOME/pkgs/root-extra/src/build
$ find -name '*.pcm'
./lib/libHistFactory_rdict.pcm
./lib/libMathCore_rdict.pcm
./lib/libMatrix_rdict.pcm
./lib/libHist_rdict.pcm
./lib/libGraf_rdict.pcm
./lib/libMinuit_rdict.pcm
./lib/libFoam_rdict.pcm
./lib/libNet_rdict.pcm
./lib/libTree_rdict.pcm
./lib/libRooFitCore_rdict.pcm
./lib/libRooFit_rdict.pcm
./lib/libMathMore_rdict.pcm
./lib/libGpad_rdict.pcm
./lib/libRooStats_rdict.pcm
./lib/libXMLParser_rdict.pcm
./lib/libMultiProc_rdict.pcm
./lib/libMinuit2_rdict.pcm
./lib/libFumili_rdict.pcm
./lib/libROOTDataFrame_rdict.pcm
./lib/libPhysics_rdict.pcm
./lib/libGraf3d_rdict.pcm
./lib/libSQLIO_rdict.pcm
./lib/libTreePlayer_rdict.pcm
./lib/libMLP_rdict.pcm
./lib/libQuadp_rdict.pcm
./lib/libSmatrix_G__Smatrix32_rdict.pcm
./lib/libGed_rdict.pcm
./lib/libSmatrix_rdict.pcm
./lib/libRootAuth_rdict.pcm
./lib/libSPlot_rdict.pcm
./lib/libBonjour_rdict.pcm
./lib/libGenVector_G__GenVector32_rdict.pcm
./lib/libGenVector_rdict.pcm
./lib/libXMLIO_rdict.pcm
./lib/libNetxNG_rdict.pcm
./lib/libTMVA_rdict.pcm
./lib/libGenetic_rdict.pcm
./lib/libNetx_rdict.pcm
./lib/libUnuran_rdict.pcm
./lib/libFFTW_rdict.pcm
./lib/libRDAVIX_rdict.pcm
./lib/libROOTVecOps_rdict.pcm
./lib/libROOTGraphicsPrimitives_rdict.pcm
./lib/libROOTHistDraw_rdict.pcm
./lib/libHistPainter_rdict.pcm
./lib/libTreeViewer_rdict.pcm
./lib/libSpectrum_rdict.pcm
./lib/libSpectrumPainter_rdict.pcm
./lib/libUnfold_rdict.pcm
./lib/libHbook_rdict.pcm
./lib/libGui_rdict.pcm
./lib/libRHTTP_rdict.pcm
./lib/libRHTTPSniff_rdict.pcm
./lib/libROOTGpadv7_rdict.pcm
./lib/libPostscript_rdict.pcm
./lib/libHtml_rdict.pcm
./lib/libGX11_rdict.pcm
./lib/libGeomPainter_rdict.pcm
./lib/libGX11TTF_rdict.pcm
./lib/libASImage_rdict.pcm
./lib/libGdml_rdict.pcm
./lib/libASImageGui_rdict.pcm
./lib/libFITSIO_rdict.pcm
./lib/libX3d_rdict.pcm
./lib/libRGL_rdict.pcm
./lib/libTable_rdict.pcm
./lib/libEG_rdict.pcm
./lib/libGeom_rdict.pcm
./lib/libEve_rdict.pcm
./lib/libGviz3d_rdict.pcm
./lib/libPyROOT_rdict.pcm
./lib/libFitPanel_rdict.pcm
./lib/libVMC_rdict.pcm
./lib/libGuiBld_rdict.pcm
./lib/libPgSQL_rdict.pcm
./lib/libGuiHtml_rdict.pcm
./lib/libRecorder_rdict.pcm
./lib/libProof_rdict.pcm
./lib/libRMySQL_rdict.pcm
./lib/libSessionViewer_rdict.pcm
./lib/libROOTWebDisplay_rdict.pcm
./lib/libROOTFitPanelv7_rdict.pcm
./lib/libEGPythia6_rdict.pcm
./lib/libProofPlayer_rdict.pcm
./lib/libGeomBuilder_rdict.pcm
./lib/libProofDraw_rdict.pcm
./lib/libProofBench_rdict.pcm
./lib/libEGPythia8_rdict.pcm
./lib/libProofx_rdict.pcm
./lib/libRSQLite_rdict.pcm
./lib/libTMVAGui_rdict.pcm
./lib/libPyMVA_rdict.pcm

For example, libMathCore_rdict.pcm is build by rootcling (found build target in math/mathcore/CMakeFiles/G__MathCore.dir/build.make) with options -excludePath that I don’t understand at full:

-excludePath   Specify a path to be excluded from the include paths
 specified for building this dictionary.

Does this mean that given path is excluded from generated pcm file (i.e. not embedded into it)? Although there is another option:

-noIncludePaths        Do not store the headers' directories in the dictionary.
 Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime.

that I find promising. IIUC this option might help to avoid embedding paths to BUILDDIR into pcm files. If to consider the libMathCore_rdict.pcm file

$ strings libMathCore_rdict.pcm | grep /home
TFileF/home/vladimir/pkgs/root-extra/src/build-gcc/lib/libMathCore_rdict.pcm
F/home/vladimir/pkgs/root-extra/src/build-gcc/lib/libMathCore_rdict.pcm
TFileF/home/vladimir/pkgs/root-extra/src/build-gcc/lib/libMathCore_rdict.pcm
TFileF/home/vladimir/pkgs/root-extra/src/build-gcc/lib/libMathCore_rdict.pcm

(I think that F here is random symbol) I not sure if these paths are related with TFile, but they are definitely useless because after installation they will point to nowhere.

Which one pcm: without _rdict or with it? (and we are talking about PCH or pcm?)

P.S. As part of experiment I tried to build ROOT with these both options ON. Apparently GCC 8.2.0 isn’t ready for first of these options set to ON, while CLANG 6.0.1 (and GCC with cxxmodules=OFF) stops on core/foundation/res/RConversionRuleParser.h with module stl not found. When I set ON only runtime_cxxmodules then both compiler stop on 73% with

building model 'Core' as '.../lib/Core.pcm'
#include "Rtypes.h"
          ^
Error: Had to build non-system module Core implicitly. You first need to generate
the dictionary for Core or mark the C++ module as system module if you provided
your own system modulemap file:
Core [system] {...}

WBR, Vladimir Lomov

@vp1981,about _rdict.pcm, they are just used for improvement of I/O performance.
The paths inside arent used at all, so it is not an issue for relocatability.

About cxxmodules, it is experimental feature that will be released very soon (it is under active development now). I will try to reproduce your failure, which means that you have some “race” condition somewhere - Core module is tried to be used before it is actually build.

Thank you, I didn’t know about this function of *_rdict.pcm files. As for paths, I’m concerned exactly with them. I don’t get how they sneak into them. This worries me and it is the main subject of the topic.

Gosh, this feature isn’t standardized and even finalized yet, and I think it won’t be till C++20 (and may be much later). AFAIK, there are two different opinions about modules (one from CLANG and another from Microsoft, export macros or not).

Still I’m interesting in experimental features (though I don’t know how much efforts it requires to implement and support that feature, especially in view of undefined situation with modules, I mean the details not the idea at all).


WBR, Vladimir Lomov

Hi,

Thank you, I didn’t know about this function of *_rdict.pcm files. As for paths, I’m concerned exactly with them. I don’t get how they sneak into them. This worries me and it is the main subject of the topic.

These are root files which contain the reflection information about selected classes, enums and typedefs/aliases plus some metadata. They do not contain streamerinfos since they are coupled to the build. They are loaded to fill up ROOT type system upon dynamic library loading. Why would you like to “sneak into them”?

Gosh, this feature isn’t standardized and even finalized yet, and I think it won’t be till C++20 (and may be much later). AFAIK, there are two different opinions about modules (one from CLANG and another from Microsoft, export macros or not).

Clang, and therefore ROOT’s interpreter, supports them. For ROOT it’s enough to have a stable and robust way to persistify the AST in order to get information about interfaces for interactivity at runtime as well as, potentially, reflection information.

Still I’m interesting in experimental features (though I don’t know how much efforts it requires to implement and support that feature, especially in view of undefined situation with modules, I mean the details not the idea at all).

Great! Try ROOT out with the experimental feature oksana mentions and, remembering it’s experimental, provide all the feedback you deem useful!

Cheers,
D

1 Like

Does this mean that they are needed only at build time? (Didn’t notice that they are ROOT files, although a bit earlier the presence of TFile suggested to me that they are connected with ROOT exclusively, for a while I thought that PCM means “precompiled module”.)

Then they are used in usual ROOT work: interactive sessions and compiling ROOT based library, but what about this

vladimir@node2-smoon7: ~ $ LANG=C strings /usr/lib/root/libMathCore_rdict.pcm | grep /home
TFileB/home/vladimir/pkgs/root-extra/src/build/lib/libMathCore_rdict.pcm
B/home/vladimir/pkgs/root-extra/src/build/lib/libMathCore_rdict.pcm
TFileB/home/vladimir/pkgs/root-extra/src/build/lib/libMathCore_rdict.pcm
TFileB/home/vladimir/pkgs/root-extra/src/build/lib/libMathCore_rdict.pcm
vladimir@node2-smoon7: ~ $ LANG=C ll -lA /home/vladimir/pkgs/root-extra/src/build/lib/
ls: cannot access '/home/vladimir/pkgs/root-extra/src/build/lib/': No such file or directory
vladimir@node2-smoon7: ~ $

(half in joke: Occam’s razor)

Sorry, wrong wording. The output above demonstrates what I bother about: the *_rdict.pcm files contain for unknown reason (see the topic title) the full path to some files that even not presented on target system. If these paths are not influence the ROOT work then why to store them? If they are valuable then how this suppose to work if given paths are missing?

Does this mean that “since CLANG supports them then ROOT supports them at no cost” and “no efforts need to support them and if something will change in future, CLANG will adopted this, so ROOT will have updated modules as well”?

It’s all Greek to me. I tried to follow what is Reflection in C++ (I suppose you mean exactly that) but didn’t find any close applications in my workflow.

Thank you, I will do (despite the fact how long it takes to build ROOT).


WBR, Vladimir Lomov

Hi,

to close this thread, my last comments.

Does this mean that they are needed only at build time? (Didn’t notice that they are ROOT files, although a bit earlier the presence of TFile suggested to me that they are connected with ROOT exclusively, for a while I thought that PCM means “precompiled module”.)

No, they do not. As explained, they contain reflection information which is normally needed at runtime.

Then they are used in usual ROOT work: interactive sessions and compiling ROOT based library, but what about this

Right. As said before, some metadata is saved too.

Sorry, wrong wording. The output above demonstrates what I bother about: the *_rdict.pcm files contain for unknown reason (see the topic title) the full path to some files that even not presented on target system. If these paths are not influence the ROOT work then why to store them? If they are valuable then how this suppose to work if given paths are missing?

See reply above.

Does this mean that “since CLANG supports them then ROOT supports them at no cost” and “no efforts need to support them and if something will change in future, CLANG will adopted this, so ROOT will have updated modules as well”?

Not really, no. Just saying that ROOT is relatively immune to standardisation issues since the pcms just need to be a form of persistified AST produced at build time which will be reused to gather information about interfaces and reflection information by the same compiler which generated them.

It’s all Greek to me. I tried to follow what is Reflection in C++ (I suppose you mean exactly that) but didn’t find any close applications in my workflow.

Sorry to hear that.

Thank you, I will do (despite the fact how long it takes to build ROOT).

Ok then.

Cheers,
D

Thank you all guys, now I have all necessary information to think off.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.