ROOT Version: root_v6.14.06 Platform: Mac OS X High Sierra Compiler: *** NO COMPILER (that’s the problem) ***
After building a distribution on Mac OS X High Sierra, and transferring it to a VM with a bare install of the same OS, my program runs, including writing TNtuple-s to a TFile. But it gets the following error message from Root:
ERROR in cling::CIFactory::createCI(): cannot extract standard library include paths!
Invoking:
LC_ALL=C /Library/Developer/CommandLineTools/usr/bin/c++ -O2 -DNDEBUG -xc++ -E -v /dev/null 2>&1 >/dev/null | awk '/^#include </,/^End of search/{if (!/^#include </ && !/^End of search/){ print }}' | GREP_OPTIONS= grep -E "(c|g)\+\+"
Results was:
With exit code 256
input_line_1:1:10: fatal error: 'new' file not found
#include <new>
^~~~~
input_line_3:37:10: fatal error: 'string' file not found
#include <string>
^~~~~~~~
This is UGLY (to say the least). But the .root file is written correctly, and is readable in other Root programs.
On the build system (which has a C++ compiler) there is no such error message; it is clearly related to the absence of a C++ compiler on the test system. Why does cling depend on a C++ compiler?
How can we fix this?
I could add some fake header files to the distribution, but how do I get cling to find them? Moreover, it seems to invoke c++ via absolute path, which I cannot fake.
(Yes, I have fixed my problems building a Mac distribution; I’ll write about that once I have it working on Linux and Windows.)
cling doesn’t necessarily depend on the compiler but on its standard library: cling is like a compiler, and to make any sense of std::string etc (and even new()) it needs libstdc++ (in the g++ case, libc++ for clang by default) installed. To find it, we ask the compiler “where is your standard library” - so in practice and reality we do want the compiler installed.
It’s not that it’s a problem to install the compiler, it’s that I want to provide a distribution of G4beamline that works for users who don’t install the compiler. For direct users of Root that is not a problem, as anybody using Root directly knows C++. But G4beamline is used by many users who don’t know C++, and have no need for a compiler – it is a popular tool for non-programmer physicists to use Geant4. For me to say “install XCode before G4beamline” is hopeless.
So the question remains: how might I fake this out?
For instance, before calling any Root function I could modify PATH to find a fake gcc,g++,cc,c++,… in the app bundle; but how much functionality do they need? Remember the only Root classes that are used directly are TFile, TDirectory, and TNtuple. I fear that this would be a long and protracted effort to fake out major parts of the compiler…
As these messages seem benign, perhaps a simpler approach is to apply a filter to stderr and stdout.
A third approach is to just document these error messages and tell users to ignore them.
as a possible work-around (as you only need TFile, TDirectory and TNtuple), couldn’t you use the equivalent classes from inexlib (or its Geant4 embedded version) ?
inexlib is a great suggestion! I downloaded it and easily built its rroot example to read Root files. It can read the file written by its wroot example (as can Root v6.14.06). But when I gave it a .root file written by G4beamline (using root_v6.14.06), it fails, saying for each TNtuple: dont’t know how to read key with object class “TNtuple”.
So while this would be a lightweight solution if it worked, it does not work. The code is (deliberately!) undocumented, and impenetrable. So I cannot use it without a long and protracted effort; I don’t have time for that.
This is not “latest” Root, TNtuple is very basic – G4beamline has been using it since ~ 2006.
Attached is g4beamline.root, which contains one TDirectory and four TNtuples; ~1000 events. It is readable by root_v5.34.03 and by root_v6.14.06. g4beamline.root (103.9 KB)
After getting the program to build on Windows 10, my program runs, including writing TNtuple-s to a file. But it gets the following error message from Root while the DLLs are loading:
In file included from input_line_3:39:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\cassert:4:
In file included from C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h:131:12: error: redefinition of ‘_CrtEnableIf<true, _Ty>’
struct _CrtEnableIf<true, _Ty>
^~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h:131:12: note: previous definition is here
struct _CrtEnableIf<true, _Ty>
^
In file included from input_line_3:39:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\cassert:4:
In file included from C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h:488:16: error: redefinition of ‘__crt_locale_data_public’
typedef struct __crt_locale_data_public
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\stddef.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
In file included from input_line_3:39:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\cassert:4:
In file included from C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h:495:16: error: redefinition of ‘__crt_locale_pointers’
typedef struct __crt_locale_pointers
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\stddef.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
In file included from input_line_3:39:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\include\cassert:4:
In file included from C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h:503:16: error: redefinition of ‘_Mbstatet’
typedef struct _Mbstatet
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\stddef.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\assert.h:12:10: note: ‘C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt\corecrt.h’
included multiple times, additional include site here #include <corecrt.h>
^
Warning in TClassTable::Add: class ROOT::Detail::TTypedIter already in TClassTable
This is UGLY (to say the least). But the .root file is written correctly and readable by other Root programs.
This is being executed in my development CMD window, so it has a C++ compiler available.
How can we fix this?
As usual, Windows is quite different from either Mac OS X or Linux.