From f08062525ea9d7ad8990246a060b3ac23a506444 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Tue, 12 Feb 2019 21:20:27 +0100
Subject: [PATCH] [core] Add TROOT::AddExtraInterpreterArgs():

Some of the tests need to find headers at runtime. Previously, these headers
were found by their full path; now, ROOT_GENERATE_DICTIONARY prefers relative
paths, that make dictionaries relocatable.
To not force everyone to define ROOT_INCLUDE_PATH when running e.g. a stress
test, the binaries call TROOT::AddExtraInterpreterArgs() passing the location
of the header, at runtime, such that cling can find them.

This is possible because the interpreter is constructed lazily, not during
static init; providing the extra interpreter flags early in main() is thus
sufficient.
---
 core/base/inc/TROOT.h         |  3 +++
 core/base/src/TROOT.cxx       | 14 ++++++++++++++
 core/metacling/src/TCling.cxx |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/core/base/inc/TROOT.h b/core/base/inc/TROOT.h
index 0c3fe6f097d..321029e9bfe 100644
--- a/core/base/inc/TROOT.h
+++ b/core/base/inc/TROOT.h
@@ -30,6 +30,8 @@
 #include "RConfigure.h"
 
 #include <atomic>
+#include <string>
+#include <vector>
 
 class TClass;
 class TCanvas;
@@ -355,6 +357,7 @@ public:
    static Int_t       ConvertVersionCode2Int(Int_t code);
    static Int_t       ConvertVersionInt2Code(Int_t v);
    static Int_t       RootVersionCode();
+   static const std::vector<std::string> &AddExtraInterpreterArgs(const std::vector<std::string> &args);
    static const char**&GetExtraInterpreterArgs();
 
    static const TString& GetRootSys();
diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index ed9d317d97b..10a765747ea 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -2901,8 +2901,22 @@ Int_t TROOT::RootVersionCode()
 {
    return ROOT_VERSION_CODE;
 }
+////////////////////////////////////////////////////////////////////////////////
+/// Provide command line arguments to the interpreter construction.
+/// These arguments are added to the existing flags (e.g. `-DNDEBUG`).
+/// They are evaluated once per process, at the time where TROOT (and thus
+/// TInterpreter) is constructed.
+/// Returns the new flags.
+
+const std::vector<std::string> &TROOT::AddExtraInterpreterArgs(const std::vector<std::string> &args) {
+   static std::vector<std::string> sArgs = {};
+   sArgs.insert(sArgs.begin(), args.begin(), args.end());
+   return sArgs;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
+/// INTERNAL function!
+/// Used by rootcling to inject interpreter arguments through a C-interface layer.
 
 const char**& TROOT::GetExtraInterpreterArgs() {
    static const char** extraInterpArgs = 0;
diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx
index e8246b55e1c..208da4110f1 100644
--- a/core/metacling/src/TCling.cxx
+++ b/core/metacling/src/TCling.cxx
@@ -1254,6 +1254,10 @@ TCling::TCling(const char *name, const char *title, const char* const argv[])
       }
    }
 
+   for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
+      interpArgs.push_back(arg.c_str());
+   }
+
    fInterpreter = new cling::Interpreter(interpArgs.size(),
                                          &(interpArgs[0]),
                                          llvmResourceDir);
-- 
GitLab