Rootcling automatically hard-coding build directory include paths


ROOT: v6-09-01-626-g492b0f6 (master)
gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12)

When building a shared library with a ROOT(Cling) dictionary generated using rootcling
rootcling automatically adds any “-I” directives to a list of include paths which are stored in e.g. G__MyClass.cxx as:

namespace {
  void TriggerDictionaryInitialization_G__MyClass_Impl() {
    static const char* headers[] = {
static const char* includePaths[] = {

In this example, the first path was given to a rootcling “-I” directive, the second is $ROOTSYS/include, and the third is the build directory where rootcling was run: this was not given to any “-I” directive, but it seems to be systematically added automatically. These paths are then added automatically to gSystem->GetIncludePath() when the library is loaded in the interpreter, and are used by ACliC for any on-the-fly compilation.

My problem is: using rootcling option “-noIncludePaths” I can remove the dependency on the source directory given to “-I”, then at runtime I set ROOT_INCLUDE_PATH to point to the installation directory with my .h. However, the spurious working directory/build directory include path always remains, option “-excludePath” does nothing to remove it, and as the build directory is a kind of network file system disk which is not necessarily mounted at runtime, any attempt to use ACliC after loading the library fails, with errors from cc1plus that the directory in question does not exist.

I need a runtime environment which only depends on the installed libraries/files/etc., not on any source files or temporary build files/directories: indeed, one would expect everything to work even if source & build directories are completely removed from the system. This is not the case.

How can I do either of:
(1) stop rootcling automatically adding the directory where it is run to the stored list of include paths in the dictionary?
(2) stop the interpreter automatically adding the include paths stored in the dictionary when the library is loaded?

Thanks a lot for any help

Hi JD,

Danilo told me he will be looking into this soon, hopefully already tomorrow.

Cheers, Axel.

Hi John,

I read attentively your report and all the information I think I need is there. I am looking into the reason why “./” is included in the list of include paths even when the noIncludePaths or the appropriate path exclusion is used.

I tend to exclude problems with all usecases but Aclic - the presence of that path is in principle harmless: can you confirm this?


Hi Danilo

Thanks for the reply. I’m not sure how to answer your question -

[quote]I tend to exclude problems with all usecases but Aclic - the presence of that path is in principle harmless: can you confirm this?[/quote] - what exactly do you mean?


Hi John,

I was trying to understand if you saw issues with this directory only when trying to use aclic or also in other situations. None of the LHC experiments for example saw any problem up to now.
In any case, the behaviour you identified and pin pointed so precisely was indeed not foreseen: I opened an item in our tracker ( and closed it.
The master of ROOT (6.09) is now fixed, the other branches will be updated after a successful round of nightlies. Thanks a lot for your precise report!


Hi Danilo

Thanks a lot!
I have only had this problem when using ACliC in batch jobs at the
IN2P3/IRFU computing centre in Lyon. The build directories which were 'included’
by rootcling are on an NFS disk mounted under /sps. When running batch jobs,
in order to be able to access /sps you have to declare an extra ‘sps’ resource for
when you submit the batch job, otherwise the /sps directory is inaccessible from
the job. However we do not want to systematically declare the ‘sps’ resource as
this can limit the number of concurrent batch jobs, so we avoid using it.
The problem showed up because when a user submits a batch analysis task,
we compile the user’s analysis class (TSelector) using ACliC at the beginning of
the job.


Hi John,

thanks for the complete explanation. This approach does indeed unveil the faulty behaviour: without this aclic usecase we were not able to detect it.