Skip to content
Snippets Groups Projects
Commit 47be56cc authored by Philippe Canal's avatar Philippe Canal
Browse files

Disassociate disable-autoloading from disable-loading-of-library.

Add TCling::fAllowLibLoad (false in rootcling, true otherwise).  This re-enable
TCling::AutoLoad by default and repairs ROOT-6580.

Historical notes:

There is two distinct part of the autoloading.

(a) The autoloading callback that is triggered during parsing by the interpreter
of user code or header files (This can also be triggered by lookup in the
type database, for example by ResolveTypedef).

(b) The function TInterpreter::AutoLoad which is explicitly called when the
library for a TClass is needed, for example from the I/O or from the code
implementing the callbacks for (a).

(a) was enabled only when we have a TApplication (See commit 73449447).
It was also enabled in rootcint when called by ACLiC but with a different
implementation of the autoload callback.   In rootcling, the same behavior
has been implementated using a different callback in ROOT::Scanner rather
than in the interpreter.

(b) was never disabled and the calling code was the only decider of
whether to execute it or not.

Once we connected libRIO to rootcling, we need a way to avoid the library
loading; we found it easiest to re-use the disabling of the autoloading (a) to
also cancel the side effect of (b) [For example the inadvertent loading of the
actual libRIO.so eventhough the .o are already linked in.]

However disabling (b) when (a) is disabled (or not yet enabled) changes the
behavior of executables (for example 'hadd') that do not have a TApplication.

The two functionalities are really semantically distinct:

(a) load library when the interpreter receive a request for the type
(b) load the library when the calling code 'knows' it needs the TClass.

As the rest of the code currently stand, allowing the execution of
TCling::AutoLoad does *not* lead to any visible problem during the build of
ROOT or the execution of roottest.

However there is never any good reason to have rootcling load any libraries,
so we must keep TCling::AutoLoad disabled during rootcling execution.
parent 99d84602
No related branches found
No related tags found
No related merge requests found
......@@ -915,6 +915,8 @@ TCling::TCling(const char *name, const char *title)
// fMapNamespaces = 0;
fRootmapFiles = 0;
fLockProcessLine = kTRUE;
fAllowLibLoad = !fromRootCling;
// Disable the autoloader until it is explicitly enabled.
SetClassAutoloading(false);
......@@ -1185,7 +1187,7 @@ void TCling::RegisterModule(const char* modulename,
// The value of 'triggerFunc' is used to find the shared library location.
// rootcling also uses TCling for generating the dictionary ROOT files.
bool fromRootCling = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
static bool fromRootCling = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
// We need the dictionary initialization but we don't want to inject the
// declarations into the interpreter, except for those we really need for
// I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
......@@ -2215,6 +2217,11 @@ Int_t TCling::Load(const char* filename, Bool_t system)
// if 'system' is true, the library is never unloaded.
// Return 0 on success, -1 on failure.
if (!fAllowLibLoad) {
Error("Load","Trying to load library (%s) from rootcling.",filename);
return -1;
}
// Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
R__LOCKGUARD2(gInterpreterMutex);
cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
......@@ -4502,9 +4509,18 @@ Int_t TCling::AutoLoad(const char* cls)
R__LOCKGUARD(gInterpreterMutex);
Int_t status = 0;
if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
if (gDebug > 2) {
Info("TCling::AutoLoad",
"Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
}
return status;
}
if (fClingCallbacks && !fClingCallbacks->IsAutoloadingEnabled()) {
if (!fAllowLibLoad) {
// Never load any library from rootcling/genreflex.
if (gDebug > 2) {
Info("TCling::AutoLoad",
"Explicitly disabled (the class name is %s)", cls);
}
return 0;
}
// Prevent the recursion when the library dictionary are loaded.
......
......@@ -110,6 +110,7 @@ private: // Data Members
std::unordered_set<const clang::NamespaceDecl*> fNSFromRootmaps; // Collection of namespaces fwd declared in the rootmaps
TObjArray* fRootmapFiles; // Loaded rootmap files.
Bool_t fLockProcessLine; // True if ProcessLine should lock gInterpreterMutex.
Bool_t fAllowLibLoad; // True if library load is allowed (i.e. not in rootcling)
cling::Interpreter* fInterpreter; // The interpreter.
cling::MetaProcessor* fMetaProcessor; // The metaprocessor.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment