From 2f53e6928f680aa7c726b8b4866555f41afd7acb Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Tue, 29 Sep 2026 12:04:20 +0000 Subject: [PATCH] [core] ACLiC: skip dependency scan for explicitly linked libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When loading an ACLiC library with C++ modules enabled and no rootmap file, `LoadLibrary` first resolves the library's dependencies by scanning its undefined symbols (`GetSharedLibDeps` with `tryDyld`) and loading each library that provides them. This is not needed if the library was explicitly linked against its dependencies (`ACLiC.LinkLibs & 1`, the default on Linux and macOS): they are then recorded in the library itself and loaded by the dynamic linker. The scan is expensive though. For a macro that uses RDataFrame, RooFit, Tree, Hist and Gpad, it takes about 2.9 s, making `.L macro.C+` with an up-to-date library take 4.9 s instead of 2.35 s (loading the library directly takes 2.2 s). Only do the scan if the library is not explicitly linked. This is the core part of https://github.com/root-project/root/pull/8017. 🤖 Done with the help of AI --- core/base/src/TSystem.cxx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx index ba5d50f0dacf9..dffb266d9461d 100644 --- a/core/base/src/TSystem.cxx +++ b/core/base/src/TSystem.cxx @@ -3418,16 +3418,18 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, if (!f(I->c_str())) break; }; - auto LoadLibrary = [useCxxModules, produceRootmap, ForeachSharedLibDep](const TString &lib) { - // We have no rootmap files or modules to construct `-l` flags enabling - // explicit linking. We have to resolve the dependencies by ourselves - // taking the job of the dyld. + auto LoadLibrary = [linkDepLibraries, useCxxModules, produceRootmap, ForeachSharedLibDep](const TString &lib) { + // If the library was explicitly linked against its dependencies, they + // are recorded in the library itself and the dynamic linker loads them. + // Otherwise, we have no rootmap files or modules to construct `-l` flags + // enabling explicit linking. We have to resolve the dependencies by + // ourselves taking the job of the dyld. // FIXME: This is a rare case where we have rootcling running with // modules disabled. Remove this code once we fully switch to modules, // or implement a special flag in rootcling which selective enables // modules for dependent libraries and does not produce a module for // the ACLiC library. - if (useCxxModules && !produceRootmap) { + if (!linkDepLibraries && useCxxModules && !produceRootmap) { std::function LoadLibF = [](const char *dep) { return gInterpreter->Load(dep, /*skipReload*/ true) >= 0; };