The C++ interpreter Cling
ROOT has a C++ interpreter called cling built in. It is used for the prompt, both C++ and Python. It also serves as a source of information to store C++ objects, and provides the back-end for ROOT’s signal/slot and plug-in mechanisms.
This chapter focuses on the parts of cling that you will encounter while interacting with ROOT.
The ROOT Prompt
Start up a ROOT session by typing root
at the system prompt.
Now we create a TLine
object:
Note some of the features of the ROOT prompt:
- Terminating with ‘
;
‘ is not required, see “C++ Extensions To Ease Scripting” below. Emacs
style command line editing.- Raw interpreter commands start with a dot;
.g l
for instance shows the interpreter information on the global calledl
. - To show the result of an expression just do not type the trailing
;
.
For the further examples we will “abbreviate” root [0]
etc by root []
.
Here we see:
- Use
.Class
as quick help and reference - Unix like I/O redirection using
.> test.log
and unredirection with.>
Now let us execute a multi-line command:
Here we note:
- A multi-line command starts with a { and ends with a }.
- Inside continuation, every line has to be correctly terminated with a ; (like in “real’’ C++).
- All objects are created in global scope.
- There is no way to back up; you are better off writing a script.
- Use
.q
to exit root.
Full list of metacommands
This list is also available by typing .?
or .help
in the ROOT prompt.
Cling (C/C++ interpreter) meta commands usage
All commands must be preceded by a '.', except
for the evaluation statement { }
==============================================================================
Syntax: .Command [arg0 arg1 ... argN]
.L <filename> - Load the given file or library
.(x|X) <filename>[(args)] - Same as .L and runs a function with
signature: ret_type filename(args)
.> <filename> - Redirect command to a given file
'>' or '1>' - Redirects the stdout stream only
'2>' - Redirects the stderr stream only
'&>' (or '2>&1') - Redirects both stdout and stderr
'>>' - Appends to the given file
.undo [n] - Unloads the last 'n' inputs lines
.U <filename> - Unloads the given file
.(I|include) [path] - Shows all include paths. If a path is given,
adds the path to the include paths.
.O <level> - Sets the optimization level (0-3)
If no level is given, prints the current setting.
.class <name> - Prints out class <name> in a CINT-like style (one-level).
If no name is given, prints out list of all classes.
.Class <name> - Prints out class <name> in a CINT-like style (all-levels).
If no name is given, prints out list of all classes.
.namespace - Prints list of all known namespaces
.typedef <name> - Prints out typedef <name> in a CINT-like style
If no name is given, prints out list of all typedefs.
.files - Prints names of all included (parsed) files
.fileEx - Prints out included (parsed) file statistics
as well as a list of their names
.g <var> - Prints out information about global variable
'var' - if no name is given, print them all
.@ - Cancels and ignores the multiline input
.rawInput [0|1] - Toggle wrapping and printing the
execution results of the input
.dynamicExtensions [0|1] - Toggles the use of the dynamic scopes
and the late binding
.debug <level> - Generates debug symbols (level is optional, 0 to disable)
.printDebug [0|1] - Toggles the printing of input's corresponding
state changes
.storeState <filename> - Store the interpreter's state to a given file
.compareState <filename> - Compare the interpreter's state with the one
saved in a given file
.stats [name] - Show stats for internal data structures
'ast' abstract syntax tree stats
'asttree [filter]' abstract syntax tree layout
'decl' dump ast declarations
'undo' show undo stack
.T <filePath> <comment> - Generate autoload map
.trace <repr> <id> - Dump trace of requested respresentation
(see .stats arguments for <repr>)
.help - Shows this information (also .?)
.q - Exit the program
ROOT special commands.
==============================================================================
.L <filename>[flags]: load the given file with optional flags like
+ to compile or ++ to force recompile.
Type .? TSystem::CompileMacro for a list of all flags.
<filename> can also be a shared library; skip flags.
.(x|X) <filename>[flags](args) :
same as .L <filename>[flags] and runs then a function
with signature: ret_type filename(args).
.credits : show credits
.demo : launch GUI demo
.forum bug : ask for help with a bug or crash at the ROOT forum.
.gh [bug|feature|improvement]
: submit a bug report, feature or improvement suggestion
.help Class::Member : open reference guide for that class member (or .?).
Specifying '::Member' is optional.
.help edit : show line editing shortcuts (or .?)
.libraries : show loaded libraries
.license : show license
.ls : list contents of current TDirectory
.pwd : show current TDirectory, pad and style
.quit (or .exit) : quit ROOT (long form of .q)
.R [user@]host[:dir] [-l user] [-d dbg] [script] :
launch process in a remote host
.qqq : quit ROOT - mandatory
.qqqqq : exit process immediately
.qqqqqqq : abort process
.which [file] : show path of macro file
.![OS_command] : execute OS-specific shell command
.!root -? : print ROOT usage (CLI options)
List of terminal keyboard shortcuts
This list is also available by typing .? edit
or .help edit
in the ROOT prompt.
ROOT terminal keyboard shortcuts (GNU-readline style).
==============================================================================
Arrow_Left : move cursor left [Ctrl+B]
Arrow_Right : move cursor right [Ctrl+F] [Ctrl+G]
Home : move cursor to beginning of line [Ctrl+A]
End : move cursor to end of line [Ctrl+E]
Ctrl+Arrow_Left : jump to previous word [Esc,B] [Alt,B]
Ctrl+Arrow_Right : jump to next word [Esc,F] [Alt,F]
Backspace : delete previous character [Ctrl+H]
Del : delete next character [Ctrl+D]
Esc,Backspace : delete previous word [Ctrl+W] [Esc,Ctrl+H] [Alt+Backspace] [Esc,Del] [Esc,Ctrl+Del]
Ctrl+Del : delete next word [Esc,D] [Alt,D]
Ctrl+U : cut all characters between cursor and start of line
Ctrl+K : cut all characters between cursor and end of line
Ctrl+T : transpose characters
Esc,C : character to upper and jump to next word
Esc,L : word to lower case and jump to its end
Esc,U : word to upper case and jump to its end
Ctrl+Shift+C : copy clipboard content
Ctrl+Shift+V : paste clipboard content [Ctrl+Y] [Alt+Y]
Ins : toggle overwrite mode
Ctrl+_ : undo last keypress action
Tab : autocomplete command or print suggestions [Ctrl+I] [Esc,Tab]
Enter : execute command [Ctrl+J] [Ctrl+M]
Ctrl+L : clear prompt screen
Ctrl+D : quit ROOT (if empty line)
Ctrl+C : send kSigInt interrupt signal
Ctrl+Z : send kSigStop pause job signal
Ctrl+\ : send kSigQuit quit job signal
Arrow_Down : navigate downwards in command history [Ctrl+N]
Arrow_Up : navigate upwards in command history [Ctrl+P]
Ctrl+R ; Ctrl+S : search command in your history by typing a string.
Use Backspace if you mistyped (but not arrows).
Press Ctrl+R (Ctrl+S) repeateadly to navigate matches in reverse (forward) order
Arrow_Right : after Ctrl+R (Ctrl+S), select current match of the history search
[Ctrl+O] [Enter] [Ctrl+J] [Ctrl+M] [Arrow_Left] [Esc,Esc].
Use Ctrl+F or Ctrl+G to cancel search and revert original line
Feeding Sources Files To ROOT: C++ Scripts
ROOT script files (often called “Macros”) contain pure C++ code. They can contain a simple sequence of statements like in the multi command line example given above, but also arbitrarily complex class and function definitions.
The most frequent interaction with the ROOT prompt uses .x
to “run” a file:
This loads myScript.C into the interpreter and calls the function myScript()
.
You can pass arguments using .x myScript.C(12, "A String")
.
Alternatively you can load the script and then run a function explicitly:
The above is equivalent to .x myScript.C
.
In a named script, the objects created on the stack are deleted when the function exits. In a common scenario you create a histogram in a named script on the stack. You draw the histogram, but when the function exits the canvas is empty and the histogram has disappeared. To avoid the histogram from disappearing you can create it on the heap (by using new). This will leave the histogram object intact, but the pointer in the named script scope will be “gone”. Since histograms (and trees) are added to the list of objects in the current directory, you can always retrieve them to delete them if needed.
In addition, histograms and trees are automatically deleted when the current directory is closed. This will automatically take care of the clean up. See “Input/Output”.
Executing a Script From a Script
You may want to execute a script conditionally inside another script.
To do it you need to call the interpreter and you can do that with
TROOT::ProcessLine()
. The example
$ROOTSYS/tutorials/tree/cernstaff.C
calls a script to build the root
file if it does not exist:
ProcessLine
takes a parameter, which is a pointer to an int
or to
a TInterpreter::EErrorCode
to let you access the interpreter error
code after an attempt to interpret. This will contain the error
as defined in enum TInterpreter::EErrorCode
with TInterpreter::kSuccess
being
the value for a successful execution.
Executing a Script From the Invocation
Instead if starting ROOT and running a script on the prompt you can also pass it to ROOT in its invocation:
The exact kind of quoting depends on your shell; the one shown here works for bash-like shells.
ROOT can evaluate any expression as part of the invocation; another version of the previous example can be spelled like this:
C++ Extensions To Ease Scripting
In the next example, we demonstrate three of the most important
extensions ROOT and Cling make to C++. Start ROOT in the directory
$ROOTSYS/tutorials
(make sure to have first run .x hsimple.C
):
The root [0]
command shows the first extension; the declaration of f
may be omitted as a shortcut for auto
. Cling will correctly
create f
as pointer to object of class TFile
. Nonetheless we recommend
to use auto f = new TFile("hsimple.root")
.
The second extension is more important. In case Cling cannot find an
object being referenced, it will ask ROOT to search for an object with
an identical name in the search path defined by TROOT::FindObject()
.
If ROOT finds the object, it returns a pointer to this object to Cling and
a pointer to its class definition and Cling will execute the requested
member function. This shortcut is quite natural for an interactive
system and saves much typing. In this example, ROOT searches for hpx
and finds it in hsimple.root.
The next, fundamental extension is shown below. There is no need to put a semicolon at the end of a line. When you leave it off the value of the expression will be printed on the next line. For example:
Be aware that these extensions do not work when a compiler replaces the interpreter. Your code will not compile, hence when writing large scripts, it is best to stay away from these shortcuts. It will save you from having problems compiling your scripts using a real C++ compiler.
ACLiC: Compiling Scripts Into Libraries
Instead of having Cling interpret your script there is a way to have your scripts compiled, linked and dynamically loaded using the C++ compiler and linker. The advantage of this is that your scripts will run with the speed of compiled C++ and that you can use language constructs that are not fully supported by Cling. On the other hand, you cannot use any Cling shortcuts (see “C++ Extensions To Ease Scripting” above) and for small scripts, the overhead of the compile/link cycle might be larger than just executing the script in the interpreter.
ACLiC (The Automatic Compiler of Libraries in Cling) will build a dictionary and a shared library from your C++ script, using the compiler and the compiler options that were used to compile the ROOT executable. You do not have to write a Makefile remembering the correct compiler options, and you do not have to exit ROOT.
Usage
Before you can compile your interpreted script you need to add include
statements for the classes used in the script. Once you did that, you
can build and load a shared library containing your script. To load it
use the command .L
and append the file name with a +
.
The + option generates the shared library and names it by taking
the name of the file “filename” but replacing the dot before the
extension by an underscore and by adding the shared library extension
for the current platform. For example on most platforms, hsimple.cxx
will generate hsimple_cxx.so
.
The + command rebuilds the library only if the script or any of the
files it includes are newer than the library. When checking the
timestamp, ACLiC generates a dependency file which name is the same as
the library name, just replacing the ‘so’ extension by the extension
‘d’. For example on most platforms, hsimple.cxx
will generate
hsimple_cxx.d
.
To ensure that the shared library is rebuilt you can use the ++ syntax:
To build, load, and execute the function with the same name as the
file you can use the .x
command. This is the same as executing a
named script; you can also provide parameters. The only
difference is you need to append a + or a ++.
You can select whether the script in compiled with debug symbol or with optimization by appending the letter ‘g’ or ‘O’ after the ‘+’ or ‘++’. Without the specification, the script is compiled with the same level of debugging symbol and optimization as the currently running ROOT executable. For example:
will compile MyScript.C
with debug symbols; usually this means
giving the -g
option to compiler.
will compile MyScript.C
with optimizations; usually this means
giving the -O
option to compiler. The syntax:
is using the default optimization level. The initial default is to compile with the same level of optimization as the root executable itself. The default can be changed by:
Note that the commands:
respectively compile MyScript.C
with debug and optimization if the
library does not exist yet; they will not change the debug and the
optimization level if the library already exist and it is up to date.
To see the full list of possible flags, see the TSystem::CompileMacro documentation.
To use ACLiC from compiled code or from inside another macro, we
recommend using gROOT->ProcessLine()
. For
example, in one script you can use ACLiC to compile and load another
script.
To change the compilation output directory in order not to pollute your source directory, see TSystem::SetBuildDir.
Setting the Include Path
You can get the include path by typing:
You can append to the include path by typing:
In a script you can append to the include path:
You can also overwrite the existing include path:
The $ROOTSYS/include
directory is automatically appended to the
include path, so you do not have to worry about including it. To add
library that should be used during linking of the shared library use
something like:
This is especially useful for static libraries. For shared ones you can also simply load them before trying to compile the script:
ACLiC uses the directive fMakeSharedLibs
to create the shared
library. If loading the shared library fails, it tries to output a
list of missing symbols by creating an executable (on some platforms
like OSF, this does not HAVE to be an executable) containing the
script. It uses the directive fMakeExe
to do so. For both
directives, before passing them to TSystem::Exec()
, it expands the
variables $SourceFiles
, $SharedLib
, $LibName
, $IncludePath
,
$LinkedLibs
, $ExeName
and $ObjectFiles
. See SetMakeSharedLib()
for more information on those variables. When the file being passed to
ACLiC is on a read only file system, ACLiC warns the user and creates
the library in a temporary directory:
To select the temporary directory ACLiC looks at $TEMP
, $TEMP_DIR
,
$TEMPDIR
, $TMP
, $TMPDIR
, $TMP_DIR
or uses /tmp (
or C:/)
.
Also, a new interface TSystem::Get/SetBuildDir
is introduced
to let users select an alternative ‘root’ for building of the ACLiC
libraries. For filename/full/path/name/macro.C
, the library is
created as fBuildDir/full/path/name/macro_C.so.
Dictionary Generation
You can direct what is added to the dictionary generated by ACLiC in two ways. The simplest way is to add at the end of script (i.e. after the symbols have been defined) something like:
You can also write this portion of code in a file name
MyScript_linkdef.h
where the suffix '_linkdef'
is the prefix
defined by the key ‘ACLiC.Linkdef
‘ in the currently used resource
file (usually .rootrc
or $ROOTSYS/etc/system.rootrc
) and the
prefix is the name of your script.
The default behavior of rootcling
is to
not link in (i.e. generate the dictionary for) any of the symbols. In
particular, this means that the following lines are, in the
general case, unnecessary.
This also means that linking the instantiation of a class template:
ONLY links this specific class. You need to request the generation of the iterators explicitly.
See the documentation of rootcling
for details how pragma
can be
used.
NOTE: You should not call ACLiC with a script that has a function
called main()
.
Intermediate Steps and Files
ACLiC executes two steps and a third one if needed. These are:
- Calling
rootcling
to create a dictionary usingrootcling
. - Calling the compiler to build the shared library from the script.
- If there are errors, it calls the compiler to build a dummy executable to clearly report unresolved symbols.
ACLiC makes a shared library with a dictionary containing the
classes and functions declared in the script. It also adds the
classes and functions declared in included files with the same name
as the script file and any of the following extensions: .h
, .hh
,
.hpp
, .hxx
, .hPP
, .hXX
. This means that, by default, you
cannot combine scripts from different files into one library by using
#include
statements; you will need to compile each script
separately. In a future release, we plan to add the global variables
declared in the script to the dictionary also. If you are curious
about the specific calls, you can raise the ROOT debug level: gDebug=3
and ACLiC will print these steps. If you need to keep the intermediate
files around, for example when debugging the script using gdb, use
gDebug=7.
Moving between Interpreter and Compiler
The best way to develop portable scripts is to make sure you can
always run them with both, the interpreter and with ACLiC. To do so,
do not use the Cling extensions and program around the Cling
limitations. When it is not possible or desirable to program around
the Cling limitations, you can use the C preprocessor symbols defined
for Cling and rootcling
.
The preprocessor symbol __CLING__
is defined for both ROOT and
rootcling
. The symbol __ROOTCLING__
(and __MAKECINT__
for backward
compatibility) is only defined in rootcling
.
Use !defined(__CLING__) || defined(__ROOTCLING__)
to bracket code that
needs to be seen by the compiler and rootcling
, but will be invisible
to the interpreter.
Use !defined(__CLING__)
to bracket code that should be seen only by
the compiler and not by Cling nor rootcling.
For example, the following
will hide the declaration and initialization of the array gArray
from both Cling and rootcling
.
Because ACLiC calls rootcling
to build a dictionary, the declaration
of gArray
will not be included in the dictionary, and consequently,
gArray
will not be available at the command line even if ACLiC is
used. Cling and rootcling
will ignore all statements between the
"#if !defined
(__CLING__)"
and “#endif"
. If you want to use
gArray
in the same script as its declaration, you can do so.
However, if you want use the script in the interpreter you have to
bracket the usage of gArray
between #if's,
since the definition is
not visible. If you add the following preprocessor statements:
gArray
will be visible to rootcling
but still not visible to Cling.
If you use ACLiC, gArray
will be available at the command line and
be initialized properly by the compiled code.
We recommend you always write scripts with the needed include statements. In most cases, the script will still run with the interpreter. However, a few header files are not handled very well by Cling.
These types of headers can be included in interpreted and compiled mode:
-
The subset of standard C/C++ headers defined in
$ROOTSYS/Cling/include.
-
Headers of classes defined in a previously loaded library (including ROOT own). The defined class must have a name known to ROOT (i.e. a class with a
ClassDef
).
Hiding header files from rootcling
that are necessary for the
compiler but optional for the interpreter can lead to a subtle but
fatal error. For example:
In this case, rootcling
does not have enough information about the
TTree
class to produce the correct dictionary file. If you try
this, rootcling
and compiling will be error free, however,
instantiating a subTree
object from the Cling command line will cause
a fatal error. In general, it is recommended to let rootcling
see as
many header files as possible.
Classes Defined By Scripts
Lets create a small class TMyClass
and a derived class
TChild
. The virtual method TMyClass::Print()
is overridden in
TChild
. Save this in file called script4.C
.
To execute script4.C
do:
As you can see, an interpreted class behaves just like a compiled class. See “Adding a Class” for ways how to add a class with a shared library and with ACLiC.
Inspecting Objects
An object of a class inheriting from TObject
can be inspected,
with the Inspect()
method. The TObject::Inspect
method creates a
window listing the current values of the objects members. For example,
the next picture is of TFile
.
You can see the pointers are in red and can be clicked on to follow
the pointer to the object. If you clicked on fList
, the list of
objects in memory and there were none, no new canvas would be shown.
On top of the page are the navigation buttons to see the previous and
next screen.
Figure: ROOT object inspector of TFile.
Figure: The object inspector of fKeys
, the list of keys in the memory.