/CxxModules-in-ROOT-Doc

C++ Modules document from the perspective of ROOT

Primary LanguageCMIT LicenseMIT

This is a repository to collect all knowledge about C++ modules while I was doing an internship at CERN.

  • CMSSW.md is a detailed introduction for building CMSSW software.
  • future_todo.md is to give remaining works that can be done in the future.
  • rootcling_impl.md is a detailed explaination of module related part of rootcling.
  • rootcling_impl.md is a detailed explaination of module related part of TCling interface.

Please read TCling.md first if you're new to ROOT and C++ Modules.

Table of contents

Overview

ROOT has a C++ interpreter, Cling, used in its backend. C++ Modules is a mechanism to accelarate compilation time of C++ code in general, but the benefit of compilation time improvement can be turned into runtime performance improvement as we have C++ interpreter. Cling uses LLVM/Clang as its backend, and C++ Module implementation in ROOT heavily relies on Clang APIs.

In ROOT, we generate ROOT pcms at compilation time of ROOT. PCMs are generated by rootcling, which is a ROOT dictionary generator. The modulemap file serves as a definition file of modules, so that rootcling can reuse pcms when generating another pcm. We generate one pcm for one library, that is for example, Core.pcm corresponds to libCore.so and so on.

"Runtime C++ Module" and "Compile time C++ Module"

Often, people are confused with the word "runtime modules" and "compile time modules (or even normal modules)". It is necessary to understand the difference between the two, otherwise reading any C++ module related documentation will not make sense.

"Runtime modules" is our main focus and the main feature, which uses PCMs at ROOT runtime (or CMSSW runtime, which uses ROOT as its backend). It requires rootcling to generate PCMs at ROOT compilation time, and load them at runtime so that we can avoid runtime header parsing. This feature can be turned on by adding "-Druntime_cxxmodules" to cmake flags.

"Compile time modules" is a normal C++ modules which is happening at the compilation time of ROOT. The compiler needs to be Clang, and you need "-Dcxxmodules" in cmake flags to turn on this feature. It is a normal C++ modules, so it improves the compilation time of ROOT quite a lot, but doesn't give any runtime benefits.

Useful vocabraries

  • Modules - C++ Modules, implented in Clang, it's the same word when we say "cxxmodules". When we just say "modules", it often means "runtime C++ modules"
  • PCM - "Pre Compiled Modules". AST file of C++ Modules
  • PCH - "Pre Compiled Headers". Header optimization before C++ Modules.
  • rdict pcm - Another runtime optimization, which has nothing to do with C++ Modules. It is an I/O optimization.
  • preloading - It refers to preloading of all PCMs at ROOT startup time. See TCling.md for more details.
  • dictionary generation - Often refers to rootcling or genreflex (genreflex is a wrapper of rootcling), which generates "dictionary" (eg. G__Core.cxx), rootmap, and PCM.
  • rootmap files - This is a file generated by rootcling, using a information from Linkdef files. Linkdef files need to be manuary maintained. rootmap files are used to enable features like "Implicit #include" described in the section above, when C++ was not implemented.

rootcling invocation

You will come back to this once per month.

/home/yuka/module-release/core/rootcling_stage1/src/rootcling_stage1 -v2 -f G__Core.cxx -cxxmodule -s /home/yuka/module-release/lib/libCore.so -excludePath /home/yuka/root -excludePath /home/yuka/module-release -rml libCore.so -rmf /home/yuka/module-release/lib/libCore.rootmap -I/home/yuka/root -I/home/yuka/module-release/etc/cling/ -I/home/yuka/module-release/include -I/home/yuka/root/core/base/res -I/home/yuka/root/core/base/../foundation/res -I/usr/include -DSYSTEM_TYPE_unix Buttons.h Bytes.h Byteswap.h Gtypes.h GuiTypes.h KeySymbols.h MessageTypes.h ROOT/TExecutor.hxx ROOT/TSequentialExecutor.hxx Riostream.h Rtypes.h TApplication.h TApplicationImp.h TAtt3D.h TAttAxis.h TAttBBox.h TAttBBox2D.h TAttFill.h TAttLine.h TAttMarker.h TAttPad.h TAttText.h TBase64.h TBenchmark.h TBrowser.h TBrowserImp.h TBuffer.h TBuffer3D.h TBuffer3DTypes.h TCanvasImp.h TColor.h TColorGradient.h TContextMenu.h TContextMenuImp.h TControlBarImp.h TDatime.h TDirectory.h TEnv.h TError.h TException.h TExec.h TFileCollection.h TFileInfo.h TFolder.h TGuiFactory.h TInetAddress.h TInspectorImp.h TMD5.h TMacro.h TMathBase.h TMemberInspector.h TMessageHandler.h TNamed.h TNotifyLink.h TObjString.h TObject.h TObjectSpy.h TPRegexp.h TParameter.h TPluginManager.h TPoint.h TProcessID.h TProcessUUID.h TQClass.h TQCommand.h TQConnection.h TQObject.h TROOT.h TRedirectOutputGuard.h TRef.h TRefCnt.h TRegexp.h TRemoteObject.h TRootIOCtor.h TStopwatch.h TStorage.h TString.h TStringLong.h TStyle.h TSysEvtHandler.h TSystem.h TSystemDirectory.h TSystemFile.h TTask.h TThreadSlots.h TTime.h TTimeStamp.h TTimer.h TUUID.h TUri.h TUrl.h TVersionCheck.h TVirtualAuth.h TVirtualFFT.h TVirtualGL.h TVirtualMonitoring.h TVirtualMutex.h TVirtualPS.h TVirtualPad.h TVirtualPadEditor.h TVirtualPadPainter.h TVirtualPerfStats.h TVirtualQConnection.h TVirtualRWMutex.h TVirtualTableInterface.h TVirtualViewer3D.h TVirtualX.h strlcpy.h snprintf.h ROOT/TSeq.hxx TArray.h TArrayC.h TArrayD.h TArrayF.h TArrayI.h TArrayL.h TArrayL64.h TArrayS.h TBits.h TBtree.h TClassTable.h TClonesArray.h TCollection.h TCollectionProxyInfo.h TExMap.h THashList.h THashTable.h TIterator.h TList.h TMap.h TObjArray.h TObjectTable.h TOrdCollection.h TRefArray.h TRefTable.h TSeqCollection.h TSortedList.h TVirtualCollectionProxy.h ESTLType.h RStringView.h TClassEdit.h ROOT/RIntegerSequence.hxx ROOT/RMakeUnique.hxx ROOT/RNotFn.hxx ROOT/RSpan.hxx ROOT/RStringView.hxx ROOT/TypeTraits.hxx ROOT/span.hxx TUnixSystem.h TClingRuntime.h root_std_complex.h TBaseClass.h TClass.h TClassGenerator.h TClassMenuItem.h TClassRef.h TClassStreamer.h TDataMember.h TDataType.h TDictAttributeMap.h TDictionary.h TEnum.h TEnumConstant.h TFileMergeInfo.h TFunction.h TFunctionTemplate.h TGenericClassInfo.h TGlobal.h TInterpreter.h TInterpreterValue.h TIsAProxy.h TListOfDataMembers.h TListOfEnums.h TListOfEnumsWithLock.h TListOfFunctionTemplates.h TListOfFunctions.h TMemberStreamer.h TMethod.h TMethodArg.h TMethodCall.h TProtoClass.h TRealData.h TSchemaHelper.h TSchemaRule.h TSchemaRuleSet.h TStatusBitsChecker.h TStreamer.h TStreamerElement.h TToggle.h TToggleGroup.h TVirtualIsAProxy.h TVirtualRefProxy.h TVirtualStreamerInfo.h Getline.h /home/yuka/root/core/base/inc/LinkDef.h

Features that Interpreter needs to support

These features are sort of "C++ superset support in ROOT". Cling supports them in order to make users' life easier.

  • Implicit #include
root[] vector<int> v = {1, 2, 3} // works

You don't need to include header in ROOT

  • Auto auto
root[] i = 12 // Interpreted as "auto i = 12"
  • using namespace std
root[] string s; // Instead of std::string
  • Eval print
root[] 40+2 // without semicolon at the end
(int) 42
  • AUto loading TFile objects
root[] TFile::Open("tutorials/hsimple.root");
root[] hpx->Draw();
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
  • Auto loading
root[] TTree t;
Info in <TUnixSystem::Load>: loaded library /home/yuka/module-release/lib/libTree.so, status 0
  • Auto parsing
root[] gSystem->Load("libGeom")
root[] TGeoManager g; // Triggers auto-parsing!
Info in <TInterpreter::AutoParse>: Parsing full payload for TGeoManager
  • Ptr check
root[] int *p = (int*)(0x120 + 0x3);
root[] *p
ROOT_prompt_1:1:2: warning: invalid memory pointer passed to a callee: *p

Available online documents

Publications of ROOT C++ Modules

Resources for C++ Modules in general

Resources for ROOT