Loading and using libraries from rootlogon.C in root 6

Dear experts,

this is my (simplified) rootlogon.C, which is perfectly working in root 5.34:

{
	gROOT->ProcessLine("#include \"RVersion.h\"");
	int root_version = ROOT_VERSION_CODE >> 16;
	printf(" === ROOT version: %d\n", root_version);

	Char_t pwd[256];
	strncpy(pwd, gSystem->pwd(), 256);
	printf(" === Current folder: %s\n", pwd);

	Char_t arch[256];
	strncpy(arch, gSystem->GetBuildArch(), 256);
	printf(" === Architecture: %s\n", arch);

	Char_t str[256];
	snprintf(str, 256, "%s/build/%s/root%d/lib", pwd, arch, root_version);
	gSystem->cd(str);

	const UShort_t nlibs = 2;
	const Char_t *lib_name[nlibs] = { "Units", "Experiments" };
	for (UShort_t ilib = 0; ilib < nlibs; ++ilib)
	{
	   snprintf(str, 256, "lib%s", lib_name[ilib]);
	   printf(" === Loading library '%s' ...", str);
	   fflush(stdout);
	   if (!gSystem->Load(str)) printf(" Loaded\n");
	   else
	   {
	      cerr <<  "\n !!! Not compiled and/or not loaded!\n";
	      return;
	   }
	}

	Experiments::DataPath = "mypath";
}

From this post, I understand that in root 6 I should use R__LOAD_LIBRARY instead of gSystem->Load, but this macro stringifies its argument, so I cannot pass a variable to it.
How can I make this rootlogon.C works in root 6?

Thanks.

Best,
Claudio

Hi Claudio,

you can certainly load libraries at runtime in ROOT6 too. What is not possible is to count on the fact that symbols in the code are resolved correctly: for the interpreter, runtime “is too late”. The preprocessor macro you quote helps indeed “in anticipating” the load of the library.
I hope that helps.

Cheers,
D

Yes, I already knew it, I can load the libraries with no problems in ROOT 6, but I would also like the symbols ready in rootlogon.C.
The problem is that R__LOAD_LIBRARY wants directly the name of the library, but I can’t hard code it, because the path depends on which environment I’m using.

Also, in ROOT 5.34, with this rootlogon.C, I could immediately use the symbols from a library in CINT (from the ROOT input console, not from a macro), without having to #include the appropriate headers.
In ROOT 6, if I load a library with gSystem->Load in rootlogon.C, then I first need to #include the headers from the ROOT input before using any symbol.
It’s not a problem when I run the full analysis code, since that’s a compiled program, but it would be useful for quick prototyping to be able to call recurrent and tedious lines of code directly from rootlogon.C also in ROOT 6.

Is there another solution?

Hi Claudio,

Let me give it a stab:

void rootlogon() {
	string root_version = std::to_string(ROOT_VERSION_CODE >> 16);
	cout << " === ROOT version: " << root_version << '\n'
	     << " === Current folder: " << gSystem->Pwd() << '\n'
	     << " === Architecture: " << gSystem->GetBuildArch() << '\n';

	string dir = "build/";
	dir += gSystem->GetBuildArch() + "/root" + root_version + "/lib";
	gSystem->cd(dir.c_str());

	std::array<const char *, 2> lib_name = { "libUnits", "libExperiments" };
	for (auto lib: lib_name)
	{
	   cout << " === Loading library '" << lib << "' ..." << std::flush;
	   if (!gSystem->Load(lib)) cout << " Loaded\n";
	   else
	   {
	      cerr <<  "\n !!! Not compiled and/or not loaded!\n";
	      return;
	   }
	}

	gInterpreter->ProcessLine("Experiments::DataPath = \"mypath\";");
}
1 Like

Thansk Axel, that worked!
I just had to add gInterpreter->ProcessLine(Form("#include \"%s/include/%s.hh\"", pwd, lib_name) in the for loop.

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