While writing simple macros or python scripts can be an effective way to quickly
get started with ROOT, cases frequently arise where it would be most effective
to create a library of compiled functions or even a compiled executable. Here is
the setup of a template package for compiling ROOT-dependent C++ classes and applications.
First, determine which ROOT installation you will use.
On lxplus5 (i.e., slc5 operating system at CERN), set environment variables with values like these:
export ROOTSYS=/afs/cern.ch/sw/lcg/app/releases/ROOT/5.22.00d/i686-slc5-gcc43-dbg/root
export LD_LIBRARY_PATH=${ROOTSYS}/lib:/afs/cern.ch/sw/lcg/external/Python/2.5/i686-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH}
export PATH=${ROOTSYS}/bin:/afs/cern.ch/sw/lcg/external/Python/2.5/i686-slc5-gcc43-opt/bin:${PATH}
export PYTHONPATH=$ROOTSYS/lib
cd
to it.CompiledRootAnalysis
template package, e.g.,wget http://mgwilson.web.cern.ch/mgwilson/Software/CompiledRootAnalysis_V01.tgz
tar -xzvf CompiledRootAnalysis_V01.tgz
CompiledRootAnalysis/scripts/RenamePackage.sh
with a new package name and namespace for the code inCompiledRootAnalysis/scripts/RenamePackage.sh
cd <package>; gmake shlib; gmake apps; gmake setup; cd ..
make dylib; make macapps
instead.bin/example
application to see that it runs correctly.Template package for building and running Athena algorithms and tools
void*
?C and C++ are strongly typed languages, meaning that blocks of memory are given a specific type (i.e., int, float, char, etc.) when allocated or used within a piece of code. Sometimes, it is desirable to write functions that can perform the same operations on different variable types. In C++, this is achievable through class inheritance. However, in C, this is done by telling the compiler not to check the type of the variable; this is done with the void*
declaration. Specifically, void*
is a pointer to untyped memory, and the programmer is free to cast this memory into any other type:
float fcn( void* var1, void* var2 ) {
float* f1 = (float*)var1;
float* f2 = (float*)var2;
/* return the product of these two floats */
return (*f1)*(*f2);
}
As you see, in doing this, the programmer assumes all responsibility for making sure that the types and operations
are correct, something normally (and best) done by the compiler.