Since Gaudi v20r3 a new tool is available for easy patch creation in the framework itself. You can find more detailed informations for patches submissions to Savannah at this location
Here is a nice trick (thanks to Ivan Belyaev) for providing easily a set of patches to be applied on a whole Gaudi-like project. In order to use this trick, you have to apply it from a cmt directory. For Gaudi, in order to obtain the diffs for every package, one has to run it from the Gaudi/[version/]cmt (for Gaudi versions up to v19r0) or GaudiRelease/[version/]cmt directory (for Gaudi v19r1 or above).
> cmt broadcast "cd ..; cvs diff -u -r HEAD | tee /tmp/<package>.diff "
The "tee" command is the secret to make it work. It splits the output between the screen and the output file. The <package> word in this command is not a placeholder for a custom output. It is a CMT variable and has to be used as shown in the command. The "-u" option for the cvs diff command is not mandatory but it is quite useful to review the patch. It provides some context around the diff lines of the patch. Finally the list of output files will look like:
> ls /tmp/Gaudi* /tmp/GaudiAlg.diff /tmp/GaudiMonitor.diff /tmp/GaudiSiteSvc.diff /tmp/GaudiAud.diff /tmp/GaudiPolicy.diff /tmp/GaudiSvc.diff /tmp/GaudiExamples.diff /tmp/GaudiPoolDb.diff /tmp/GaudiSys.diff /tmp/GaudiGSL.diff /tmp/GaudiPython.diff /tmp/GaudiKernel.diff /tmp/GaudiRelease.diff
The final remark is that all of the output files content are not necessarily useful. Some of them only contain lines beginning with "?" and thus are meaningless.
As explained at the main page of the site, one has to use the :pserver:anonymous@isscvs.cern.ch:/local/reps/Gaudi value for the CVSROOT variable (or passed it to the cvs command with the "-d" option). There is a special CVS module in that CVS repository which allows to extract all the Gaudi packages in one shot. The name of the module is "all":
> cvs -d :pserver:anonymous@isscvs.cern.ch:/local/reps/Gaudi co -r \ HEAD all
The usual command to update to the CVS HEAD would look like:
> cvs update -dPA
For a more complete explanation please have a look at the CVS documentation. The "-A" forces the removal of any sticky tags. The "-d" retrieves the missing directories and the "-P" option removes empty directories.
If one has modifications for only one Gaudi package and would like to submit it to the Savannah site, unlike the trick in the CMT section, to create the patch, one can simply do:
> cvs diff -u -r HEAD > GaudiKernel.patch
What is more important is the location where this command is executed. It should be executed in the main directory of the package:
GaudiKernel> ls cmt/ CVS/ dict/ doc/ GaudiKernel/ scripts/ slc3_ia32_gcc323_dbg/ src/ GaudiKernel> cvs diff -u -r HEAD > GaudiKernel.patch
The "-u" command output a diff file with more context lines which tends to be more readable and the "-r HEAD" option ensures that the diff are computed against the CVS HEAD.
The dynamic_cast problem. This was solved for Gaudi some time ago and it is here for reference.
this->
". For more details,
please have a look at the C++ section of the changes
page of GCC 3.4 .When using the returned value of a function as a direct argument for an other function several times, the order of evaluation is not specified. For example:
double rdmg(); MyTrack track(rdmg(),rdmg(),rdmg());
In the above C++ code snippet, a constructor is initialized with 3 doubles which are returned values of the rdmg function. If that function returns each time a different value, the result is unpredictable. The compiler can decide which call it wants to execute first and typically there are differences between GCC 3.2.3 and GCC 3.4.5 . One trivial way to solve the ambiguity would be:
double rdmg(); double a=rdmg(); double b=rdmg(); double c=rdmg(); MyTrack track(a,b,c);
When using the std::string::find
function from the STL
library, one can often see the following use:
int sep = path.find(SEPARATOR,1); if ( sep > 0 )
This works well since
std::string::size_type
is unsigned
int
on 32 bits platforms but this is not the case on 64
bits platforms. On those machines,
std::string::size_type
is a 64 bits integer. So
the corrected code will be:
std::string::size_type = path.find(SEPARATOR,1); if ( sep != std::string::npos )
To ease a bit the use of the interactive python prompt with Linux, there is an interesting setting to put in your ${HOME}/.pystart file (the file which is identified by the PYTHONSTARTUP environment variable).
try: import readline except ImportError: print "Module readline not available" else: import rlcompleter readline.parse_and_bind("tab: complete")
This allows to have a line completion using the
readline library (this library is also used by bash, emacs and
gdb for examples) and it can be configured through the
${INPUTRC} file for all of its clients. Please have a look at
the documentation (man 3 readline
).
This is just an advertisement of one of the useful features present in the standard python library. The following line allow to show the call trace of the execution of a python script (myscript.py):
python /usr/lib/python2.4/trace.py -t myscript.py
If the path to the python installation has been produced by a CMT setup, the path to the trace.py program has to be set accordingly.
> which python /afs/cern.ch/sw/lcg/external/Python/2.4.2/slc3_ia32_gcc323/bin/python > python /afs/cern.ch/sw/lcg/external/\ Python/2.4.2/slc3_ia32_gcc323/lib/python2.4/trace.py -t myscript.py
To be able to use gdb to debug a Gaudi based
application, you should use the correct
environment. This means that you either can do a
source setup.[c]sh
before starting
gdb Gaudi.exe
or use the cmt run gdb
Gaudi.exe
command (the cmt run
command is only available on the v1r18 version of CMT or
later).
When gdb is running, you still have to provide the
command line arguments for your executable if any. This
can be achieved in two ways: you can give as an argument
of the run
and start
commands
of gdb,
gdb> run Gaudi.opts
or you can set the arguments of your program and run with the following instructions:
gdb> set args Gaudi.opts gdb> run
The difference between the run
and the
start
command resides in the fact that
start
only run the program until it reaches
the main
function and that run
run the program until a problem is found.
The usual way for gdb to start
a program prog
for debugging is to issue the
command: ${SHELL} -c prog
. While this is
perfectly regular action with Bash, some version of Tcsh
behave a bit strangely. For these versions, not only the
.tcshrc file is read when starting with the -c
option, but also the .login file. This could possibly lead
to the impossibility to debug anything with gdb under the
CMT environment.
In details, if you have a look on one hand the UNIX way of working, you noticed that the environment of your shell is quite stable: you first login, setting up your environment through the reading of the ~/.login file and then for each issued commands a new shell is spawned and initialized with the .tcshrc configuration. The new created shell inherits all of its environment variable from its parent shell. The environment variables are somehow independent of the given shell instance and that's why they should never be set up in the .tcshrc file since it is read for every new instance of tcsh. For example, one can set the LD_LIBRARY_PATH to one's favorite libraries in the following way in the .login file:
setenv LD_LIBRARY_PATH ${HOME}/lib
This will set your LD_LIBRARY_PATH when you login and it will be propagated to any other shell instance.
On the other hand, CMT is introducing new mecanism for the code development to increase the flexibility of the package management. It doesn't rely on a fix stable environment but rather set up a customized environment for each application. Typically, when one's is building a CMT application, the following steps are required:
cmt broadcast make
)source
setup.csh
)../${CMTCONFIG}/Gaudi.exe
../options/Gaudi.opts
)The second steps sets or updates different environment variables as, for examples, the LD_LIBRARY_PATH. These are necessary to run the application at the third step. Obviously this also mean that the debugger (gdb or one of its frontends, ddd or emacs) should be started at the same prompt where the setup step has been made.
If the .login or worse, the .tcshrc file is setting the
LD_LIBRARY_PATH in the way mentioned above, this would
reset the environment of the program run in the gdb
session and the debugging would be impossible. One simple
workaround would be to removed the "setenv
LD_LIBRARY_PATH ...
" command from the .login file or only
to update it if it doesn't already exist.
if (${?LD_LIBRARY_PATH} != "1") then setenv LD_LIBRARY_PATH ${HOME}/lib else setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${HOME}/lib endif