diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx index 9e2282f659328..8cd8e234deeec 100644 --- a/core/base/src/TSystem.cxx +++ b/core/base/src/TSystem.cxx @@ -3499,6 +3499,11 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, } mapfileStream.close(); + bool useCxxModules = false; +#ifdef R__USE_CXXMODULES + useCxxModules = true; +#endif + // ======= Generate the rootcling command line TString rcling = "rootcling"; PrependPathName(TROOT::GetBinDir(), rcling); @@ -3506,6 +3511,10 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, rcling += mapfile; rcling += "\" -f \""; rcling.Append(dict).Append("\" "); + + if (useCxxModules) + rcling += " -cxxmodule "; + if (produceRootmap) { rcling += " -rml " + libname + " -rmf \"" + libmapfilename + "\" "; } diff --git a/core/dictgen/res/Scanner.h b/core/dictgen/res/Scanner.h index baa87828b0b01..f53ab3db755f1 100644 --- a/core/dictgen/res/Scanner.h +++ b/core/dictgen/res/Scanner.h @@ -70,7 +70,7 @@ class RScanner: public clang::RecursiveASTVisitor typedef std::vector FunctionColl_t; typedef std::vector VariableColl_t; typedef std::vector EnumColl_t; - typedef void (*DeclCallback)(const char *type); + typedef void (*DeclCallback)(const clang::RecordDecl*); typedef std::map DeclsSelRulesMap_t; enum class EScanType : char {kNormal, kTwoPasses, kOnePCM}; diff --git a/core/dictgen/src/Scanner.cxx b/core/dictgen/src/Scanner.cxx index 8f2ccad2b0e9b..afb831be5d7d5 100644 --- a/core/dictgen/src/Scanner.cxx +++ b/core/dictgen/src/Scanner.cxx @@ -653,9 +653,7 @@ bool RScanner::TreatRecordDeclOrTypedefNameDecl(clang::TypeDecl* typeDecl) // them either directly or indirectly. Any false positive can be // resolved by removing the spurrious dependency in the (user) header // files. - std::string qual_name; - GetDeclQualName(recordDecl,qual_name); - fRecordDeclCallback(qual_name.c_str()); + fRecordDeclCallback(recordDecl); } // in case it is implicit or a forward declaration, we are not interested. diff --git a/core/dictgen/src/rootcling_impl.cxx b/core/dictgen/src/rootcling_impl.cxx index ba69c28bed2f5..f9334c2d9731b 100644 --- a/core/dictgen/src/rootcling_impl.cxx +++ b/core/dictgen/src/rootcling_impl.cxx @@ -772,9 +772,17 @@ string gLibsNeeded; //////////////////////////////////////////////////////////////////////////////// -void RecordDeclCallback(const char *c) +void RecordDeclCallback(const clang::RecordDecl* recordDecl) { - string need(gAutoloads[c]); + std::string need; + if (recordDecl->hasOwningModule()) { + clang::Module *M = recordDecl->getOwningModule()->getTopLevelModule(); + need = "lib" + M->Name + ".so"; + } else { + auto N = clang::dyn_cast (recordDecl); + need = gAutoloads[N->getName()]; + } + if (need.length() && gLibsNeeded.find(need) == string::npos) { gLibsNeeded += " " + need; } @@ -4159,6 +4167,7 @@ int RootClingMain(int argc, bool selSyntaxOnly = false; bool noIncludePaths = false; bool cxxmodule = getenv("ROOT_MODULES") != nullptr; + bool isAclic = false; // Collect the diagnostic pragmas linked to the usage of -W // Workaround for ROOT-5656 @@ -4298,6 +4307,8 @@ int RootClingMain(int argc, } ic++; } + if (liblistPrefix.length()) + isAclic = true; // Check if we have a multi dict request but no target library if (multiDict && sharedLibraryPathName.empty()) { @@ -5054,7 +5065,7 @@ int RootClingMain(int argc, // Write the module/PCH depending on what mode we are on if (modGen.IsPCH()) { if (!GenerateAllDict(modGen, CI, currentDirectory)) return 1; - } else if (cxxmodule) { + } else if (cxxmodule && !isAclic) { if (!CheckModuleValid(modGen, resourceDir, interp, linkdefFilename, moduleName.str())) return 1; } @@ -5096,7 +5107,7 @@ int RootClingMain(int argc, else return a + " " + b; }); - bool rootMapNeeded = !rootmapFileName.empty() || !rootmapLibName.empty(); + bool rootMapNeeded = (!rootmapFileName.empty() || !rootmapLibName.empty()) && !(cxxmodule && !isAclic); std::list classesNames; std::list classesNamesForRootmap; @@ -5169,6 +5180,7 @@ int RootClingMain(int argc, // Manually call end of translation unit because we never call the // appropriate deconstructors in the interpreter. This writes out the C++ // module file that we currently generate. + if (!isAclic) { cling::Interpreter::PushTransactionRAII RAII(&interp); CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext()); diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index 8825c3d9e5ccb..d4206a5cd267a 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -1311,10 +1311,6 @@ TCling::TCling(const char *name, const char *title, const char* const argv[]) // This should be vector in order to be able to pass it to LoadModules std::vector CoreModules = {"ROOT_Foundation_C","ROOT_Config", "ROOT_Foundation_Stage1_NoRTTI", "Core", "RIO"}; - // These modules contain global variables which conflict with users' code such as "PI". - // FIXME: Reducing those will let us be less dependent on rootmap files - static constexpr std::array ExcludeModules = - { { "Rtools", "RSQLite", "RInterface", "RMVA"} }; LoadModules(CoreModules, *fInterpreter); @@ -1332,8 +1328,7 @@ TCling::TCling(const char *name, const char *title, const char* const argv[]) std::string ModuleName = GetModuleNameAsString(M, PP); if (!ModuleName.empty() && - std::find(CoreModules.begin(), CoreModules.end(), ModuleName) == CoreModules.end() - && std::find(ExcludeModules.begin(), ExcludeModules.end(), ModuleName) == ExcludeModules.end()) { + std::find(CoreModules.begin(), CoreModules.end(), ModuleName) == CoreModules.end()) { if (M->IsSystem && !M->IsMissingRequirement) LoadModule(ModuleName, *fInterpreter); else if (!M->IsSystem && !M->IsMissingRequirement)