This page is severely outdated. I hope to update it soon. Sorry about that.
This page is a kind of tutorial to explain how to use some tools
to develop EmCal (online) software. This page cannot prevent you to
read the various pieces of documentation, but could help as a quick
reference for the following subjects :
Download section
CreateNewModule.csh : if you want to create a new package from scratch, this is a must have !CVS
CVS is a free tool to manage software revision and release control in a multi-developper, multi-directory, multi-group environment.
[ Parts of the following were simply stolen from http://wwwinfo.cern.ch/asd/cvs/. So if you like originals, go there. ]
Buzzwords
When working with CVS, you'd better know those words :
Repository, Module, Checkout, Commit, Update.
Repository
This is the central place where all the versions of the source code files are kept. It is a top level directory of a tree of directories. It is usually indicated in the CVSROOT environment variable. For example, if you have sourced the /opt/phenix/bin/phenix_setup.csh in your .login, you should be able to do this :mymachine: echo $CVSROOT mymachine: /afs/rhic/phenix/cvsroot
Module
A specific directory (or subtree of directories) in the Repository.Checkout
A local copy of (part of) the CVS repository, used e.g. to modify or examine files.Commit
If you have made some local modification in your checkout, you can put them in the central Repository by doing a commit.Update
This is to update your local checkout using any new information available in the Repository.Working with CVS (for EmCal software)
Getting help
Try this:
mymachine: cvs help CVS commands are: add Add a new file/directory to the repository admin Administration front end for rcs annotate Show last revision where each line was modified checkout Checkout sources for editing commit Check files into the repository diff Show differences between revisions edit Get ready to edit a watched file editors See who is editing a watched file export Export sources from CVS, similar to checkout history Show repository access history import Import sources into CVS, using vendor branches init Create a CVS repository if it doesn't exist log Print out history information for files login Prompt for password for authenticating server. logout Removes entry in .cvspass for remote repository. rdiff Create 'patch' format diffs between releases release Indicate that a Module is no longer in use remove Remove an entry from the repository rtag Add a symbolic tag to a module status Display status information on checked out files tag Add a symbolic tag to checked out version of files unedit Undo an edit command update Bring work tree in sync with repository watch Set watches watchers See who is watching a file (Specify the --help option for a list of other help options) mymachine: cvs --help checkout Usage: cvs checkout [-ANPRcflnps] [-r rev | -D date] [-d dir] [-j rev1] [-j rev2] [-k kopt] modules... -A Reset any sticky tags/date/kopts. -N Don't shorten module paths if -d specified. -P Prune empty directories. -R Process directories recursively. -c "cat" the module database. -f Force a head revision match if tag/date not found. -l Local directory only, not recursive -n Do not run module program (if any). -p Check out files to standard output (avoids stickiness). -s Like -c, but include module status. -r rev Check out revision or tag. (implies -P) (is sticky) -D date Check out revisions as of date. (implies -P) (is sticky) -d dir Check out into dir instead of module name. -k kopt Use RCS kopt -k option on checkout. -j rev Merge in changes made between current revision and rev. (Specify the --help global option for a list of other help options)
Creating a new module
There's several solution to do that. Here's one. Suppose you want to create the module my_module, which is part of the online/monitoring/emc/Common hierarchy. Download the script CreateNewModule.csh and execute it :
mymachine: cd ~/tmp mymachine: ./CreateNewModule.csh my_module ---------------------- We have created a my_module.h file in my_module/src directory. If you remove it, modify accordingly the my_module/configure.in file mymachine: ls -R my_module AUTHORS INSTALL README WARNING doc COPYING Makefile.am THANKS autogen.sh src ChangeLog NEWS TODO configure.in my_module/doc: Makefile.am my_module/src: Makefile.am my_module.h
The CreateNewModule.csh script has created a small directory tree under my_module. It's your module. You can put it in CVS using the import command (you'll do this only once for this package!) :
Please do not issue the following commands 'just to test', as it will create a new module in CVS, and removing CVS modules is not that easy...
mymachine: cd ~/tmp mymachine: ls -d my_module my_module mymachine: cvs import -m 'a comment?' online/monitoring/emc/Common/my_module my_module_0_1 my_module_0_1
Checkout
After you've created YOUR module in CVS, the normal way of working with it is a 1 checkout + local modifications + commit(s) + release.
Go to a fresh new directory, and checkout your module :
mymachine: cd ~ mymachine: mkdir work ; cd work mymachine: cvs checkout -d a_directory_name_for_my_module online/monitoring/emc/Common/my_module
The above command will create a local copy of the my_module under a_directory_name_for_my_module.
Shortcut: 'cvs checkout' can be shorten to cvs co.
Adding
Once you've checked-out your module, you will probably edit and/or add source files. To let CVS know that you want him to take care of a new file, do:
mymachine: pwd ~/tmp/a_directory_name_for_my_module/src mymachine: emacs new_file.C & play with new_file.C... mymachine: cvs add new_file.C cvs add: scheduling file `test' for addition cvs add: use 'cvs commit' to add this file permanently
The new_file.C file won't be written in the Repository until you do a commit (see below). You can cancel the addition by issuing a cvs remove new_file.C before doing the commit.
Commit
Once you've done some changes in YOUR package, you probably want to let other people access your latest changes/bug fixes. To do so, you copy your local files to the Repository by committing your changes. A change is meant as a modification of a file that was checkout OR a file that was add/removed using cvs add or cvs remove commands. The command to commit is :
cvs commit -m 'comment' list_of_files
If list_of_files is not specified, the current directory (and all its subdirs) is searched for modified files, and those one are committed.
Shortcut: 'cvs commit' can be shorten to cvs ci.
Update
To be sure that your checkout version reflects the latest versions in the Repository, just sit in your checkout directory, and type cvs update. This will tell you which files have been updated (their names are displayed with a U before them), and which have been modified by you and not yet committed (preceded by an M). It can be that when you do an update, the changes in the central copy clash with changes you have made in your own copy. You will be warned of any files that contain clashes by a preceding C. Inside the files the clashes will be marked in the file surrounded by lines of the form <<<< and >>>>. You have to resolve the clashes in your copy by hand. After an update where there have been clashes, your original version of the file is saved as `.#file.version'. If you feel you have messed up a file and wish to have CVS forget about your changes and go back to the version from the repository, delete the file and do an cvs update. CVS will announce that the file has been "lost" and will give you a fresh copy.
Removing
To remove file foo.C do a rm foo.C + cvs remove foo.C + cvs ci -m '' foo.C. The last command does not need to be issued right after the others. It can wait the commit of the full module for instance.
autogen.sh, Makefile.am and configure.in
All PHENIX packages should use the GNU tools of the automake suite. The idea behind those tools is to ease compilation/linking when travelling from one platform to another.
Being a client of a package
If you just want to build a package, here are the steps (we're back to the my_module example) :
mymachine: cd ~/tmp mymachine: cvs co -d my_module online/monitoring/emc/Common/my_module mymachine: mkdir my_module-build mymachine: ../my_module/autogen.sh --prefix=dir_where_you_want_to_install mymachine: make mymachine: make install
Doing so, the include files from my_module package will be installed under dir_where_you_want_to_install/include, the libraries under dir_where_you_want_to_install/lib, and the binaries under dir_where_you_want_to_install/bin.
Being a developper
If you are a developper, you'll need to know about two kind of files : configure.in (usually there's only one in the top level directory of your package) and some Makefile.am (one in the top level directory and one in each subdirectory containing installable stuff). You must edit the Makefile.am files to tell automake what it should build. Here's an example of such a Makefile.am, which builds a library (libemcOM.so) and a binary (main) :
INCLUDES = -I. -I$(srcdir) -I$(ROOTSYS)/include \ -I$(EMC_MON_MAIN)/include \ -I$(OFFLINE_MAIN)/include lib_LTLIBRARIES = libemcOM.la libemcOM_la_SOURCES = emcOMGains.C emcObjyObjectManager.C libemcOM_la_LIBADD = -L$(EMC_MON_MAIN) \ -lemcPdbCal -lemcDataManager -lEmcMonitor bin_PROGRAMS = main main_SOURCES = main.C main_LDADD = libemcOM.la include_HEADERS = emcOMGains.h emcObjyObjectManager.h
If you want to learn more about how to write Makefile.am, just try info automake or go the GNU web page about automake. Be sure for example to check the Generalities/Uniform section.
The configure.in file which is created by the
CreateNewModule.csh script will check that ROOT is installed and
will define some variables that you can use directly in your
Makefile.am :
- ROOTSYS : well, it's ROOTSYS (see Root Page if needed).
- CXXFLAGS : you should not care, but let's say it's already containing ROOT specific compilation directives.
- ROOTLIBS and ROOTGLIBS : the full set of Root libraries (without and with graphics libraries). Using ROOTGLIBS, you don't need to explicitely specify X11 libraries as they are already referenced by Root libraries.
Often you'll need to have a configure.in that checks that another package (which you depend on) is already installed before you can proceed with yours. Assuming the package is named XXX, here are an example of what to do (those lines are already in the generated configure.in, but commented out -lines starting with dnl-) :
dnl -------------------------------------------------------------- dnl Example of checking for another package library or so... dnl AC_ARG_WITH(XXX, [--with-XXX=something Your help message here (printing by configure --he lp)], A_VARIABLE_NAME_XXX=$withval, A_VARIABLE_NAME_XXX=${some_predefined_environment_variable}) AC_CHECK_FILE(${A_VARIABLE_NAME_XXX}/lib/libXXX.so,, AC_MSG_ERROR([can not find libXXX.so ! Use --with-XXX=])) dnl The A_VARIABLE_NAME_XXX might then be used in your Makefile.am. AC_SUBST(A_VARIABLE_NAME_XXX)
The --with-XXX option is passed to autogen.sh when preparing the package:
mymachine: cd ~/tmp/my_module mymachine: ../my_module/autogen.sh --with-XXX=some_directory --prefix=...