Differences between revisions 23 and 24
Revision 23 as of 2005-08-26 14:18:43
Size: 20254
Comment: incorporated contents of README-compiling.txt file (found in dev/)
Revision 24 as of 2005-08-26 14:52:09
Size: 19970
Comment:
Deletions are marked like this. Additions are marked like this.
Line 63: Line 63:
Prior to running the configure script, the following is necessary to create the platform specific tools required by configure (execute in the dev/ directory):
{{{
  ./setup_configure
Prior to running the configure script, the following is necessary to create the platform specific tools required by configure (execute in the dev/ directory created by cvs checkout):
{{{
./setup_configure
Line 71: Line 71:
  ./configure ./configure
Line 77: Line 77:
The prefix option determines where your build will be installed when you use the 'make install' command. This is your private copy of FreeSurfer, not a release for others, so put it in your own directory space. The prefix option determines where your build will be installed when you use the 'make install' command. This is your private copy of FreeSurfer, not a release for others, so put it in your own directory space.  Generally, for a developer, this directory is your $FREESURFER_HOME (in this case FREESURFER_HOME is ~/work/freesurfer).

These options specify where certain packages are:
Line 80: Line 81:

These options specify where certain packages are. These are often
needed so configure can find libraries installed in /usr/pubsw. Note
that you should have /usr/pubsw mounted on your machine. This is
normal for NMR computers.

Freesurfer builds against the following set of open-sourced libraries,
thus, these must be installed prior to building:
These are often needed so configure can find libraries installed in /usr/pubsw. Note that you should have /usr/pubsw mounted on your machine. This is normal for NMR computers.

Freesurfer builds against the following set of open-sourced libraries, thus, these must be installed prior to building:
Line 99: Line 95:
Freesurfer also builds against certain packages of the MINC toolkit.
A special bundle of the source code for the packages require by
Freesurfer also builds against certain packages of the MINC toolkit. A special bundle of the source code for the packages require by
Line 105: Line 100:
Look for mni.srcbuild.tar.gz, and mni.srcbuild.README.txt describes the
build process.
{{{
  CFLAGS=-I/sw/include
  CXXFLAGS=-I/sw/include
  LDFLAGS=-L/sw/lib
}}}
The above are needed on Macs on which software is installed in /sw by
fink or FinkCommander. Note that you can also use these options to
specify other compile-line flags. Note that these options aren't
preceded by dashes.

{{{--with-tixwish=/usr/sw/bin/tixwish8.1.8.4}}}

This one is also often needed for Macs.

A sample configure line for the Mac:
{{{
  ./configure --prefix=~/home/freesurfer \
        CFLAGS=-I/sw/include \
        CXXFLAGS=-I/sw/include \
        LDFLAGS=-L/sw/lib \
        --with-mni-dir=/usr/local/mni \
        --with-tixwish=/usr/sw/bin/tixwish8.1.8.4
Look for mni.srcbuild.tar.gz, and mni.srcbuild.README.txt describes the build process.

A sample configure line for a Linux machine:
{{{
./configure \
        --prefix="$FREESURFER_HOME" \
        --with-mni-dir="/usr/pubsw/packages/mni/current" \
        --with-tcl-dir="/usr/local/freesurfer/dev/lib/tcltktixblt"
Line 139: Line 118:
  cd mri_info
  make
cd mri_info
make
Line 226: Line 205:
=== autoconf Troubleshooting ===

Here's a list of common problems and solutions for autotools problems:

[AutoconfTroubleshooting
]
=== Troubleshooting autoconf ===

[wiki:Self:AutoconfTroubleshooting Here's a list of common problems and solutions for autotools problems.]
Line 304: Line 281:
  cvs update -r cvs update -r
Line 308: Line 285:
  U myFile.c U myFile.c
Line 314: Line 291:
  C myFile.c C myFile.c
Line 318: Line 295:
Once the up to date check has been performed, you can commit your changes. If you are in a directory and want to commit all the files in that directory that you have changed, just use  {{{
  
cvs commit
}}}
This will commit changes in the current directory and any subdirectories. If you want to commit only certain files, use  {{{
  
cvs commit <filename>
Once the up to date check has been performed, you can commit your changes. If you are in a directory and want to commit all the files in that directory that you have changed, just use:
{{{
cvs commit
}}}
This will commit changes in the current directory and any subdirectories. If you want to commit only certain files, use:
{{{
cvs commit <filename>
Line 329: Line 306:
  cvs commit -l cvs commit -l
Line 333: Line 310:
  cvs commit -m "some descriptive changelog comment" <filename> cvs commit -m "some descriptive changelog comment" <filename>
Line 337: Line 314:
  cvs ci -m "fixed stuff" <filename> cvs ci -m "fixed stuff" <filename>
Line 341: Line 318:
  cvs update -d
}}}
The -d switch adds any new directories and is not strictly necessary, but is a good habit, because if you don't use it you will update existing files but will now add new directories.
cvs update -d -P
}}}
The -d switch adds any new directories and is not strictly necessary, but is a good habit, because if you don't use it you will update existing files but will now add new directories.  The -P option purges directories of files that have been removed in the past.
Line 347: Line 324:
  cvs ci -m "fixed many things" cvs ci -m "fixed many things"
Line 353: Line 330:
  cvs add <filename>
  cvs commit -m "added the file" <filename>
cvs add <filename>
cvs commit -m "added the file" <filename>
Line 358: Line 335:
  cvs remove -f <filename>
  cvs commit -m "removed the file" <filename>
cvs remove -f <filename>
cvs commit -m "removed the file" <filename>
Line 367: Line 344:
  cvs tag alpha-1 cvs tag alpha-1
Line 371: Line 348:
  cvs update -r alpha-1 cvs update -r alpha-1
Line 381: Line 358:
  cvs commit cvs commit
Line 385: Line 362:
  cvs update -A cvs update -A
Line 389: Line 366:
  cvs tag -c tag-name cvs tag -c tag-name
Line 395: Line 372:
  cvs checkout -r tag-name archive cvs checkout -r tag-name archive
Line 400: Line 377:
  cvs tag -b branch-name
}}}
note doesn't make working copy the branch
cvs tag -b branch-name
}}}
note: doesn't make working copy the branch.
Line 406: Line 383:
  cvs rtag -b -r tag-name branch-name archive cvs rtag -b -r tag-name branch-name archive
Line 411: Line 388:
  cvs checkout -r branch-name archive cvs checkout -r branch-name archive
Line 416: Line 393:
  cvs update -r branch-name archive cvs update -r branch-name archive
Line 420: Line 397:
  BCD archive; cvs update -r branch-name BCD archive; cvs update -r branch-name
Line 425: Line 402:
  cvs status
}}}
look for sticky tag field
cvs status
}}}
look for sticky tag field.
Line 431: Line 408:
  cvs update -j branch-to-join file cvs update -j branch-to-join file
Line 437: Line 414:
  cvs update -j rev file cvs update -j rev file
Line 443: Line 420:
  cvs add file; cvs commit file cvs add file; cvs commit file
Line 448: Line 425:
  rm file; cvs remove file; cvs commit file rm file; cvs remove file; cvs commit file
Line 453: Line 430:
  mv old new; cvs remove old; cvs add new; cvs commit old new mv old new; cvs remove old; cvs add new; cvs commit old new

Navigation(children)

Index

TableOfContents

1. CVS Checkout

You can checkout the FreeSurfer source code from the NMR center using local CVS access or remotely by using SSH as the CVS remote connection method.

1.1. Local CVS Access

The CVS repository is /space/repo/1/dev. Use this as your CVSROOT. You can either set it as an environment variable:

setenv CVSROOT /space/repo/1/dev

or specify it in the checkout command with the -d option. Note that the CVS root is cached in a CVS checkout directory, so if you choose to use the -d method, you will only have to do it once during your first checkout.

Check out the code with the CVS checkout command. The archive name is dev.

cvs checkout -P dev

or

cvs -d /space/repo/1/dev checkout -P dev

This will copy the entire archive to your directory, creating a directory called dev/. The -P option will purge the old directories that have been removed from the CVS repository.

Generally it is handy to define an environment variable called FSDEV which is set to your Freesurfer development directory. Be sure also to define your FREESURFER_HOME environment variable set to the intended Freesurfer installation directory.

1.2. Remote CVS Access

Tell CVS to use SSH to access the archive by setting the following environment variable:

setenv CVS_RSH ssh

Use the following string as your CVS root:

setenv CVSROOT :ext:USER@MACHINE.nmr.mgh.harvard.edu:/space/repo/1/dev

Where USER is your username and MACHINE is one of the NMR machines visible to the outside, i.e. gate, entry, or door. Then use the CVS commands normally.

Note that using this method makes an SSH connection for every CVS command, and you will be required to enter your password every time. You may want to look into a utility to automatically authenticate SSH connections, such as SSH agent. See:

http://mah.everybody.org/docs/ssh

When working in a CVS checkout directory, cvs knows where the CVSROOT is for that directory. However, it doesn't know what CVS_RSH method to use, so if you are grabbing files remotely, you may want to set this in your login file.

2. Configuring

Prior to running the configure script, the following is necessary to create the platform specific tools required by configure (execute in the dev/ directory created by cvs checkout):

./setup_configure

This script runs a set of commands (aclocal, libtoolize, automake, autoconf) that creates the platform specific files for configure and puts them in the 'dev/config' directory.

Now you need to configure your building paramters for your machine:

./configure

This runs the configure script which checks a bunch of local settings and libraries that are needed. You will probably need to supply some extra options:

--prefix=~/work/freesurfer

The prefix option determines where your build will be installed when you use the 'make install' command. This is your private copy of FreeSurfer, not a release for others, so put it in your own directory space. Generally, for a developer, this directory is your $FREESURFER_HOME (in this case FREESURFER_HOME is ~/work/freesurfer).

These options specify where certain packages are: --with-mni-dir=/usr/pubsw/packages/mni/current --with-tcl-dir=/usr/pubsw/packages/qt/current These are often needed so configure can find libraries installed in /usr/pubsw. Note that you should have /usr/pubsw mounted on your machine. This is normal for NMR computers.

Freesurfer builds against the following set of open-sourced libraries, thus, these must be installed prior to building:

  • GSL JPEG TIFF Tcl 8.4 Tk 8.4 Tix 8.4 BLT GLut Qt 3.3.4

Freesurfer also builds against certain packages of the MINC toolkit. A special bundle of the source code for the packages require by Freesurfer has been put together and is available on the download site:

ftp://surfer.nmr.mgh.harvard.edu/pub/dist/

Look for mni.srcbuild.tar.gz, and mni.srcbuild.README.txt describes the build process.

A sample configure line for a Linux machine:

./configure \
        --prefix="$FREESURFER_HOME" \
        --with-mni-dir="/usr/pubsw/packages/mni/current" \
        --with-tcl-dir="/usr/local/freesurfer/dev/lib/tcltktixblt"

3. Building

You can now run 'make', edit and build code, etc. The first thing you should do is 'make' to build libraries like libutils. (Note that all libs will be built to your local checkout directory.) To just build libutils, cd into utils/ and run make.

You can now compile individual programs or all of them at once. To compile all of them, just run 'make' from dev/. Binaries will automatically be placed in their individual subdirectories.

However you may just want to compile one of them at a time. To do so, cd to the directory of the program you want and use 'make' to compile it:

cd mri_info
make

This creates mri_info in the mri_info/ directory.

4. Adding a new binary to the tree

Assuming that you have a source file MYPROG.c that compiles into MYPROG and want to add it to the FreeSurfer tree:

1) Make the directory in dev and copy the source file there. Name the directory MYPROG and the source file MYPROG.c.

mkdir dev/MYPROG
cp MYPROG.c dev/MYPROG

2) Tell the autotools to build your program when you type make from the top dir.

a) Modify dev/configure.in to add MYPROG/Makefile to the list at the end of the file in the definition of AC_OUTPUT. Be sure to add a backslash at the end of line:

AC_OUTPUT( \
... other files ...
MYPROG/Makefile \
)

b) Modify dev/Makefile.am to add MYPROG to the SUBDIRS definition. (You can also alternatively it to the end of MRISUBDIRS or MRISSUBDIRS if more appropriate.)

SUBDIRS= ... other directories ... MYPROG

c) Copy dev/dummy/Makefile.am into MYPROG/ and customize it, replacing 'dummy' with 'MYPROG'. Be sure to change:

bin_PROGRAMS = MYPROG

d) Copy in the additional testing file dev/dummy/myown.c. You can customize it for your test program later.

3) Run automake from dev/. You should get no errors. If you do, make sure you followed the above instructions properly. Also try the AutoconfTroubleshooting page. Verify that this stepped work by checking if MYPROG/Makefile.in was created.

4) Run autoconf to generate a new configure script that now includes your new MYPROG directory.

5) Run ./configure with the parameters you previously used. To check these out, run head config.log from dev/. The output should include the ./configure line you used. Copy it, but leave out the --no-create --no-recursion options if present.

[dev/]$ head config.log
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by Freesurfer configure 0.1, which was
generated by GNU Autoconf 2.57.  Invocation command line was

  $ ./configure --with-mni-dir=/usr/pubsw/packages/mni/current --prefix=/home/kteich/freesurfer/dev --no-create --no-recursion

## --------- ##
## Platform. ##
[dev/]$ ./configure --with-mni-dir=/usr/pubsw/packages/mni/current --prefix=/home/kteich/freesurfer/dev

Note: Do not just copy this example, use what's in your own config.log file!

6) Run make and verify that your binary program MYPROG/MYPROG was created.

7) Check in your changes.

[dev/] cvs ci -m "Added MYPROG" configure configure.in Makefile.am Makefile.in
[dev/] cvs add MYPROG
[dev/] cd MYPROG
[MYPROG/] cvs add Makefile.am Makefile.in MYPROG.c myown.c
[MYPROG/] cvs commit -m "First checkin." Makefile.am Makefile.in MYPROG.c myown.c

5. Installing

To install all binaries and support files into your private FreeSurfer, use 'make install' from the toplevel dev/ directory. This will make a directory called freesurfer/ in the directory specified by the --prefix option to configure, above. Note that if you do not specify this location, it will try to install to /usr/local, which you probably don't have permission to do. Even if you do, i.e. you are installing on a laptop, it's generally better to specify a prefix of /usr/local/freesurfer to keep everything in the same place.

Note that you can also run 'make release'. 'make install' makes and installs the NMR internal version of FreeSurfer, while 'make release' makes the public version which omits some stuff.

The first time you run 'make install', it will take a while to copy all the big data files to the new installation. Subsequent 'make installs' will only copy the changed files.

If you only want to install a single binary, run 'make install' from a subdirectory. For example, running 'make install' from the scuba/ directory will copy the scuba binary and its support script files to the proper locations. Running 'make install' from scripts/ will copy all the necessary scripts to the right location.

6. Troubleshooting autoconf

[wiki:AutoconfTroubleshooting Here's a list of common problems and solutions for autotools problems.]

7. Making changes live (at the Martinos Center)

The current setup allows you to have your own private installation of FreeSurfer using configure --prefix=/your/private/directory. This lets you use make install to easily install the entire FreeSurfer environment into a local copy.

The purpose of having your own private installation of FreeSurfer is to use it as a testbed to make sure that (1) your updates, whatever they be, work in freesurfer/ setup that is just like a real one, and (2) your updates are properly installed using 'make install' and 'make release'. Once you are sure of these two things, check in your updated files, including any Makefile.am and Makefile.in changes, etc, and the nightly build script will take care of the rest.

The nightly build stuff automatically updates and installs the dev/ distribution on all seven build platforms. The next morning, just check if your changes are in any /usr/local/freesurfer/dev; if not, notify me. If they are in one /usr/local/freesurfer, they will be in the rest of them. (If any build/installs fail, I am notified, and will do the build/install manually for that day.)

Things not to do:

- Don't test your local setup by manually copying files into your local freesurfer/. Otherwise you can't be sure that the automated build will correctly install your files with 'make install' and 'make release'. The only way files should get into your freesurfer/ distro as with 'make install' and 'make release'.

- Don't try to install into /usr/local/freesurfer yourself (i.e. by setting your .configure --prefix=... to target it). It's set up so the build scripts can do their job automatically. Also, you would only be installing on one of the seven platforms. It's a pain to do all three builds on all build machines and verify it all worked - that's what the nightly build script is for, so let it do it for you.

If you absolutely need a 'hot fix' right away, and need to make changes live in any of the /usr/local/freesurfers before the nightly build stuff goes, let KevinTeich know and he'll do it.

8. How the nightly build works (at the Martinos Center)

First a note on the directory structure. In /space/freesurfer/build there is a directory for each build machine. Each builds a platform in /space/freesurfer, i.e. /space/freesurfer/rh9. Currently these are as follows:

Build machine

Platform

fishie

centos4.0

icelin

centos4.0_x86_64

kani

rh9

martinos01

rh7.3

minnehaha

fc2

storm

tiger

Inside each /space/freesurfer/build/MACHINE is trunk/ and stable/, as well as directories for local Qt installs, and on Tiger, MNI, and files for automated building. configure_options.txt contain command-line arguments for configure for that platform, and source_before_building.csh (optional) contains environment variables that must be set (mainly things like CPPFLAGS that are used by configure but can't be passed in to configure via the command line from a cronjob). The trunk and stable directories contain cvs checkouts.

In /space/freesurfer/build/scripts is build_dev.csh and build_betapub.csh. Each build machine runs build_dev.csh nightly. It basically goes to /space/freesurfer/build/MACHINE/trunk/dev and does the following:

cvs update -d
make distclean
rm -rf autom4te.cache
aclocal
autoconf
automake
./configure  `cat ${BUILD_DIR}/configure_options.txt` --prefix=/usr/local/freesurfer/dev
make
rm -rf freesurfer/bin_old
mv freesurfer/bin freesurfer/bin_old
make install

The build_betapub.csh works in /space/freesurfer/build/MACHINE/stable/dev and also does:

make release prefix=/usr/local/freesurfer/pub

All the autotools stuff gaurantees that enough of the Makefiles will be regenerated to ensure that new directories will be added to all Makefiles. This wouldn't normally be done with a simple ./config.status because configure may need to be regenerated to know about new directories.

Currently (as of 4/8/2005) the build_betapub.csh script is not run regularly. This is to minimize interruption to the freesurfer/beta build.

Note that all machines can run these scripts at any time from the command line. This lets maintainers (KevinTeich and NickSchmansky) explicity do a build and install on any machine if a 'hot fix' is needed.

Additionally, a developer can go to each machine's /space/freesurfer/build/MACHINE/trunk/dev, update code, and do a make install from an individual binary directory if a hot fix is needed for a single binary before the nightly build. This is the quick and dirty way of doing an update for a single binary without waiting for the nightly build. For example, to update tkmedit, the developer would, for each build machine:

cd /space/freesurfer/build/MACHINE/trunk/dev/tkmedit
cvs update
make install

This would install the files to /usr/local/freesurfer/dev. However, the developer must know about file dependencies. In this case, the script files that tkmedit may also need to be updated, so the developer would also have to cvs update and make install from dev/scripts.

9. Using CVS

When you want to commit your changes, use the cvs commit command. However, you must first check to see if the file(s) in the archive have changed since the last time you checked them out. To do so, run the cvs update command on the files you have changed. The -r option will remove files that have been removed from the CVS.

cvs update -r

If any have changed, you will see the letter U followed by the file name.

U myFile.c

This means somebody else committed a newer version of the file, and your copy was just updated.

If you and somebody else have made changes on the same file that conflict each other, you will see the letter C along with a message about the conflicts.

C myFile.c

If the message states the conflicts have been resolved, you don't have to worry: cvs has merged the differences properly. If it says it couldn't merge the differences, you need to open the file in question, search for the string >>>, and merge the differences yourself.

Once the up to date check has been performed, you can commit your changes. If you are in a directory and want to commit all the files in that directory that you have changed, just use:

cvs commit

This will commit changes in the current directory and any subdirectories. If you want to commit only certain files, use:

cvs commit <filename>

Or you can only commit the code in the current directory with the -l switch:

cvs commit -l

Each time, an editor will open and ask you to enter a log message. To bypass this, use the -m option and enter your log message on the command line:

cvs commit -m "some descriptive changelog comment" <filename>

A synonym for commit is ci, so you can just:

cvs ci -m "fixed stuff" <filename>

Periodically, you should update your working copy to be in sync with the archive. CVS will look at all your files and see if the ones in the archive are different. If so, it will update your copy. CVS will not delete local modifications you have made. To do this update:

cvs update -d -P

The -d switch adds any new directories and is not strictly necessary, but is a good habit, because if you don't use it you will update existing files but will now add new directories. The -P option purges directories of files that have been removed in the past.

Similarly, you can update an entire directory or a single file. To commit all the code in the current directory (code that has not been changed will not be commited):

cvs ci -m "fixed many things"

To restore an edited version to the version in the archive, either delete the file and cvs update, and the archive version will be copied to the local work area, or use the -C option to cvs update to replace your copy with one from the archive.

To add a new file to the archive, use the add command and then commit the file:

cvs add <filename>
cvs commit -m "added the file" <filename>

To remove a file, remove in cvs and locally (with the -f flag), and commit:

cvs remove -f <filename>
cvs commit -m "removed the file" <filename>

That covers most of the CVS commands you'll have to to use.

Additional stuff:

To tag a group of code with a text label:

cvs tag alpha-1

To retrieve a tagged group of code:

cvs update -r alpha-1

There are more useful commands, but these are the most commonly used ones. See http://www.cvshome.org for more info.

For more info on CVS, check out www.cvshome.org or the CVS man pages.

Summary:

check in a file

cvs commit

get newest versions. merges newer versions than the ones you had with your working versions.

cvs update -A

tag working files:

cvs tag -c tag-name

if any working copies are edited, will report an error. check in first.

checkout a tag:

cvs checkout -r tag-name archive

split off a branch based on current revisions in working copy:

cvs tag -b branch-name

note: doesn't make working copy the branch.

split off a branch:

cvs rtag -b -r tag-name branch-name archive

check out a branch:

cvs checkout -r branch-name archive

switch working copy to a branch:

cvs update -r branch-name archive

-or-

BCD archive; cvs update -r branch-name

to find out what branch the working copy is on:

cvs status

look for sticky tag field.

join the changes in a branch to current working copy:

cvs update -j branch-to-join file

best to tag merged branches after every merge.

joing the changes in a revision to current working copy:

cvs update -j rev file

i.e. two people check out 1.3, someone checks it in 1.4, you try to check it in and get a conflict, can join in the changes with cvs update -j 1.4 file.c

add a new file:

cvs add file; cvs commit file

remove a file (but keep in older revisions):

rm file; cvs remove file; cvs commit file

rename a file:

mv old new; cvs remove old; cvs add new; cvs commit old new

10. RPM

See RpmInfo

11. Medical Image Format FAQ

[http://www.dclunie.com/medical-image-faq/html Medical Image Format FAQ]

DevelopersGuide (last edited 2023-09-13 15:46:41 by JacksonNolan)