MINC/Tutorials/CVSandPackaging

This is a HOWTO for creating a BIC package and some guidelines to release it upon the world

Package naming rules

edit

The first thing you need to decide is what you are going to call your package. In general the prefix "minc" is reserved for packages/programs that will work on any MINC file (mincmath, mincresample, etc), be it 3D, 10D or even 1D. If your program/package is more suited to working on volumes (3D) then the suggestion is to prefix it with "vol". Granted this rule has not always been followed in the past (minctracc, mincmorph) but we needn't let that drag us back.

Your package name should also not contain UPPER CASE letters or underscores "_" as this will cause problems later on when you come to build binary packages for some systems (debian linux for example). Numbers and the dash character "-" are allowed in package names. Again, this rule has not always been followed (mni_autoreg for example) and subsequent pain has ensued.

Examples of good names include:

  mincshazam - the name we shall use in the examples on this page
  volpls-fmri - a package to analyse fmri data via PLS
  mincinvert - a package/program to invert a file
  voldegibbs - a package to remove gibbs ringing from an image

Don't do this:

  mincprocess - far too general
  vol-do-emma-processing - processing for emma, to generic and emma will leave eventually
  vol-do-something-with-a-really-long-name
  mincfoo
  mincb

Setting up CVS the BIC way

edit

By now you have probably written some of your code and have it stored in your home directory, this is good as it is backed up but if you wanted to know what changes you made 3 days ago you will need something like CVS to track changes. CVS allows you to do this via repositories of code. This HOWTO will assume that from now on you are using CVS for your code and know how to use it. If not, you'd be best advised to go away and read this: [1]

The current CVSROOT for the BIC is on cvs.bic.mni.mcgill.ca in /private-cvsroot so the following lines in your .bashrc will work wonders:

 $ export CVSROOT=cvs.bic.mni.mcgill.ca:/private-cvsroot
 $ export CVS_RSH=ssh

In your case the second line is probably not needed as you will be local to the bic, but should you wish to use a remote repository then it comes in very handy.

You may also like to define a few defaults for CVS commands via a ~/.cshrc file, here is what I use and recommend

  $ cat ~/.cvsrc
  checkout -P
  update -d -P
  diff -u -b -B
  tag -c
  
  # if you'd like cvs to be a bit quieter, comment out this
  # cvs -q

Use man to find out what these do but they are a good set of defaults for new users of CVS

Creating a package from scratch

edit

Whilst it might seem like a large amount of overhead we use automake and autoconf to package source so that we can be sure that they will compile on a multitude of platforms. To get started with this, create yourself a local cvs directory

  $ mkdir ~/cvs
  $ cd ~/cvs

Then export a copy of the BIC example package

  $ cvs export -r HEAD libraries/mni-example-package

Then decide where you are going to place your package in cvs (take a look about /software/source).; If you need help with where to place your package send Andrew Janke an email: a.janke@gmail.com For now we'll assume that we are going to place our package in libraries. Rename the example package

  $ mv libraries/mni-example-package libraries/mincshazam
  $ cd libraries/mincshazam

Place the name and email address of the package creators in the AUTHORS file

  $ cat AUTHORS 
  Andrew Janke <a.janke@gmail.com>

Add the licence you are going to use to the file COPYING. In this case we have used the MINC modified BSD style license. For guidelines/suggestions on which licence to use see Licensing below.

  $ cat COPYING 
  Copyright 2006-2007 Andrew L Janke
  McConnell Brain Imaging Centre
  Montreal Neurological Institute
  McGill University
  
  Permission to use, copy, modify, and distribute this software and its
  documentation for any purpose and without fee is hereby granted,
  provided that the above copyright notice appear in all copies.  The
  author and McGill University make no representations about the
  suitability of this software for any purpose.  It is provided "as is"
  without express or implied warranty.

Write the README. The README that you will already have in the current directory should be read and digested. It describes in better detail than this HOWTO where you can get more info on automake, autoconf and related tools. Remember that the README is the first file that a package builder will (or at least should) read.

  $ cat README
  The mincshazam package contains mincshazam
  
  It does magic on minc files so amazing that all people should have it.
  If you don't like it, too bad.

Copy in your source file(s) and remove the examples.

  $ cp ~/src/good_stuff/mincshazam.c .
  $ rm -f example_tags.c example_volume_io.c example_modify.c

Edit configure.ac to suit (read the autoconf man pages and the likes for more info). Suffice to say just editing the example that is given will suit most purposes. The most important parts to fill in are the three components of AC_INIT. Later when we build a proper BIC package this is the information that will be returned via the -version flag to your program.

  $ cat configure.ac 
  # Require autoconf 2.57 or newer.
  AC_PREREQ([2.57])
  
  # The arguments are package name, and package version.
  AC_INIT([mincshazam],[1.0], [Andrew Janke <a.janke@gmail.com>])
  
  # The argument is any source file distributed with the package.
  AC_CONFIG_SRCDIR([mincshazam.c])
  
  AM_INIT_AUTOMAKE
  
  # The argument is the name of the generated header file.
  # It is recommended to leave it as "config.h".
  AC_CONFIG_HEADERS([config.h])
  
  # This macro eases building the package; see m4/README.
  smr_WITH_BUILD_PATH
  
  # Checks for programs.
  AC_PROG_CC
  AC_PROG_INSTALL
  
  # Checks for libraries.  See m4/README.
  mni_REQUIRE_VOLUMEIO
  
  # Finish up by writing output files.
  AC_CONFIG_FILES([Makefile])
  AC_OUTPUT

Add your source files to Makefile.am. Again see the automake documentation for more info on this file. As always with anything to do with Make, be sure to uses tabs and not spaces when indenting. I suspect automake may handle spaces in some releases but you never know, best to err on the side of caution.

  $ cat Makefile.am 
  AUTOMAKE_OPTIONS = check-news
  ACLOCAL_AMFLAGS = -I m4
  
  bin_PROGRAMS = mincshazam
  
  EXTRA_DIST = $(m4_files)
  
  m4_files = m4/mni_REQUIRE_LIB.m4 m4/mni_REQUIRE_MNILIBS.m4       \
          m4/mni_REQUIRE_OPENINVENTOR.m4                           \
          m4/mni_cxx_have_koenig_lookup.m4 m4/smr_CGAL_MAKEFILE.m4 \
          m4/smr_OPTIONAL_LIB.m4 m4/smr_REQUIRED_LIB.m4            \
          m4/smr_WITH_BUILD_PATH.m4
  
  mincshazam_SOURCES = mincshazam.c

Write your entry in the Changelog. The purpose of the ChangeLog is to communicate in simple(r) terms a summary of changes that you have made to a repository as part of a CVS commit to other developers. It need not be as detailed as the information you enter as part of the cvs commit but should instead contain a summary of the general reason for the changes.

  $ cat ChangeLog 
  2006-04-06  Andrew L. Janke  <a.janke@gmail.com>
  
       * made this marvelous package
       * Added the -version option

Make an empty NEWS file. This file will get its turn when we make our first release later on.

  echo  > NEWS

You shouldn't have to modify anything in autogen.sh but we'll cat it here so that it doesn't feel left out. It probably already feels less important that configure.ac and Makefile.am for one good reason, it is. A script called autogen.sh is not required, you could just run the three commands listed below in order and all would be good. autogen.sh is merely a convention that most people who use automake and autoconf follow.

  $ cat autogen.sh 
  #! /bin/sh
  
  set -e
  
  aclocal -I m4
  autoheader
  automake --add-missing --copy
  autoreconf

Read README.CVS, remember it then remove it, the instructions it contains will be used later.

  $ rm -f README.CVS

It is now high time we did our initial cvs import

  $ cvs import -m 'initial import' libraries/mincshazam mni initial-import 

The "mni" argument is the vendor branch and the "initial-import" argument is the tag that is associated with this operation so that you can return to the initial import should you wish.

Now remembering what you were instructed to do in README.CVS, do this:

  $ cvs -d cvs.bic.mni.mcgill.ca:/private-cvsroot checkout -d m4 libraries/mni-acmacros

This will get you a copy of the most recent BIC m4 macros that are most commonly used. You should now have a directory called m4, it contains macros that autoconf uses to create the configure file for your package.

We are now finished creating our initial package, here is what you should have except of course with your own source files in there.

  $ ls -F
  AUTHORS  ChangeLog    NEWS    autogen.sh*   m4/
  COPYING  Makefile.am  README  configure.ac  mincshazam.c

Note that we get a copy of the m4 macros after our initial import such that we do not add them to our repository. We merely use them as a repository in its own right within our repository. Changes you make within m4 will be committed to the m4 repository. (be carefull here, others may well not like you much if you mess with the default m4 macros).

Building your package from scratch

edit

At this stage you have files that automake and autoconf can process to form a configure script and then a subsequent Makefile. The first stage is to generate a configure script that you can distribute. Others who download a source version of your package will use this configure script to make a Makefile and then compile from there. The commands required to make configure script from the files you have are in the little shell autogen.sh

  $ cat autogen.sh 
  #! /bin/sh
  
  set -e
   
  aclocal -I m4
  autoheader
  automake --add-missing --copy
  autoreconf

Run autogen.sh

  $ ./autogen.sh 
  /usr/share/aclocal/gtk.m4:7: warning: underquoted definition of AM_PATH_GTK
    run info '(automake)Extending aclocal'
    or see http://sources.redhat.com/automake/automake.html#Extending-aclocal
  /usr/share/aclocal/glib.m4:8: warning: underquoted definition of AM_PATH_GLIB
  configure.ac: installing `./install-sh'
  configure.ac: installing `./missing'
  Makefile.am: installing `./INSTALL'
  Makefile.am: installing `./depcomp'

The warnings above can be (very) safely ignored.

This will produce you a configure script, run it with appropriate options (./configure --help for more info). In our case we building against extra libraries that can be found in /usr/local/bic and also going to be installing our package in /usr/local/bic .

  $ configure --with-build-path=/usr/local/bic --prefix=/usr/local/bic
  checking for a BSD-compatible install... /usr/bin/install -c
  checking whether build environment is sane... yes
  <...>
  config.status: creating Makefile
  config.status: creating config.h
  config.status: executing depfiles commands

Presuming all went well with the configure step above, make your package. If things fail or you fail to get a Makefile the first thing to check is that you have up to date versions of automake and autoconf. Beyond this it really gets beyond the scope of this HOWTO.

  $ make
  <...>

At this stage you should have a directory looking something like this:

  $ ls
  AUTHORS    Makefile.am  autogen.sh*      config.status*  m4/           stamp-h1
  COPYING    Makefile.in  autom4te.cache/  configure*      mincshazam*
  ChangeLog  NEWS         config.h         configure.ac    mincshazam.c
  INSTALL    README       config.h.in      depcomp*        mincshazam.o
  Makefile   aclocal.m4   config.log       install-sh*     missing*

Note that we do not need to add any of these automake/autoconf generated files to our cvs repository as they all can (and should) be regenerated for differing software platforms and versions of autotools.

Release procedure -- creating a source package to distribute

edit

First decide on the type of versioning you are going to use for your package, typically only a dotted duple is needed. ie: 1.02 with occasional forrays into a dotted tuple if the package has many incremental releases (1.2.03).

Once you have a version numbering scheme in place, follow these set of rules (in strict order!)

1. If this is your first release, insert your initial version into configure.ac. If not, make sure that the version number is correct for this release. In our case, 1.0 is the first release so we can leave it as is from the previous section.

  AC_INIT([mincshazam],[1.0], [Andrew Janke <a.janke@gmail.com>])

2. update NEWS with info on the current release that can be digested by users of the package.

  $ cat NEWS 
  New in release 1.0 
  ------------------
  * Initial version.

3. Configure, build, and do a test install.

  $ ./configure --with-build-path=/usr/local/mni --prefix=/usr/local/mni
  $ make
  $ make install

4. commit to make sure we are up to date in case someone else has made some changes to the package.

  $ cvs commit

5. Create the distribution with distcheck.

  $ make distcheck

This will make a file called mincshazam-1.0.tar.gz

6. Test build from this tarball on another system.

7. Copy the tarball to your distribution site. (in our case typically http://packages.bic.mni.mcgill.ca/tgz for source packages.

8. Tag your release so that you can return to this version anytime you want. The tag should follow the following format

  <package-name>-<version number using '-'>

In our case this translates to

  $ cvs tag mincshazam-1-0

9. Update the version number in configure.in so that there is no chance that someone else or yourself can make a different release with the same version number. In this case it is best to update the version number only in the least most significant field.

  AC_INIT([mincshazam],[1.1], [Andrew Janke <a.janke@gmail.com>])

10. Commit the bumped version number

  $ cvs commit .


adding binary building capability to your package

edit

I really should finish this section

epm-header.in

adding a -version flag to your packages executables and scripts

edit

blankety blank blank


Licensing types

edit

Use the MINC one if possible (a modification of the older BSD license) or the GPL if you have included GPL code from elsewhere. A MINC tool that uses the GNU Scientific Library (GSL) is a good example of this.

other types in here?

migrating your cvs directory

edit

The original home (for many years) of CVS at the BIC was shadow:/software/source. This changed on the 23/08/2006 such that we could finally have a public CVS repository and a split public and private portion of CVS.

If you have an existing cvs directory that is already checked out and would like to migrate it as you have some changes in it to the new server (cvs.bic.mni.mcgill.ca) then all you need do is edit the CVS/Root files in each respository that you have checked out to reflect the new home. The files should have a single line in them as such:

  cvs.bic.mni.mcgill.ca:/private-cvs

I realise that this may cause some short-term pain but I do believe it to be for the better or I wouldn't have done it!

Good luck and email me (Andrew Janke - a.janke@gmail.com) if you have problems.