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 :

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=...