Differences between revisions 1 and 2
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:

== Configuring a Simple Build ==

```bash
cmake </path/to/repo>
```

So assuming you have a freesurfer repository stored at `~/dev/freesurfer`, you could configure a simple in-source build with

{{{
cd ~/dev/freesurfer
cmake .
}}}

or an out-of-source build with

{{{
cd ~/dev/fsbuild
cmake ~/dev/freesurfer
}}}

Alternatively, `ccmake` can be used instead of `cmake` to configure/edit cached variables in a terminal GUI.

CMake variables are set on the command line with the `-D` flag. For example, the standard way to configure a build with an install path is

{{{
cmake . -DCMAKE_INSTALL_PREFIX="/path/to/install/destination"
}}}

You can define any variable on the command line this way, even if the variable is never used in the cmake scripts. Boolean variables added with the `option()` function can be turned on/off on the command line as well. For example, freesurfer GUI builds can be disabled by running

{{{
cmake . -DBUILD_GUIS=OFF
}}}

Aside from this initial configuration step (which really only needs to be run once) and fact that `make check` is now `make test`, the rest of the build process is pretty much the same.

'''note:''' the `make` output is more condensed now, but `make VERBOSE=1` will output everything.

== Overview of the CMake Framework ==

The top-level CMakeLists.txt file is the main cmake configuration script (which replaces setup_configure, configure.in, and Makefile.am), and all subdirectories are added from here with the `add_subdirectory()` function. This main script is split into three parts: locating third-party packages, configuring compilation settings, and configuring freesurfer static libs and programs.

=== Third-Party Packages ===

Most of the packages required by freesurfer are located via custom "find-modules" stored in the `cmake` subdirectory. These find-modules expect each package to be installed under a common path defined by `FS_PACKAGES_DIR`. On Martinos machines, this variable automatically defaults to `/usr/pubsw/packages`, but external developers must provide this path manually:

{{{
cmake . -DFS_PACKAGES_DIR="/path/to/packages"
}}}

If a package is not found under `FS_PACKAGES_DIR`, cmake will continue to look through the default search paths. Alternative paths to package installs can also be specified with the `<PACKAGE>_DIR` variables. For example, to use a non-default ITK version:

{{{
cmake . -DITK_DIR="/usr/pubsw/packages/itk/4.9.1"
}}}

==== Find Modules ====

In CMakeLists.txt, packages are located by using the `find_package()` function. Some larger, modern projects, like Qt, VTK, and ITK, distribute cmake config files within their installations, so locating the package's include directory and libraries is a fairly straightfoward process:

{{{
find_package(ITK HINTS ${ITK_DIR} REQUIRED)
}}}

In this example, if ITK is found by cmake, then `ITK_FOUND` is set to true, and `ITK_INCLUDE_DIRS` and `ITK_LIBRARIES` are set accordingly.

However, most freesurfer dependencies don't ship with cmake configuration files, so we have to create our own find-modules. Fortunately, this isn't too difficult,

==== External Developers ====

In general, I think the goal should be to distance ourselves from distributing the pre-built package tarballs since they are difficult to maintain across multiple platforms. The `packages/build_packages.py` script is a potential alternative to the pre-built archives - it's a utility script to help external developers build freesurfer dependencies on their own.

The packages configured within `build_packages.py` are built using the tarballs and buildscripts stored in the `packages/source` dir and will get installed to a destination directory specified on the command-line:

{{{
build_packages.py "/path/to/install/destination"
}}}

This script loops through each package in the `pkgs` list, extracts the associated tarball to `destination/package-name/version/src`, and runs the package build script. The individual build scripts (like [this ITK one](??)) always expect a single input argument that points to the desired install directory. After each successful package build, the checksum of the tarball + build script is saved to the src dir. This way, if this script is rerun, the package is only rebuilt when the source code has been modified

Once the dependencies are built, developers can then point `FS_PACKAGES_DIR` to their local install directory.

freesurfer cmake

Configuring a Simple Build

`bash cmake </path/to/repo> `

So assuming you have a freesurfer repository stored at ~/dev/freesurfer, you could configure a simple in-source build with

cd ~/dev/freesurfer
cmake .

or an out-of-source build with

cd ~/dev/fsbuild
cmake ~/dev/freesurfer

Alternatively, ccmake can be used instead of cmake to configure/edit cached variables in a terminal GUI.

CMake variables are set on the command line with the -D flag. For example, the standard way to configure a build with an install path is

cmake . -DCMAKE_INSTALL_PREFIX="/path/to/install/destination"

You can define any variable on the command line this way, even if the variable is never used in the cmake scripts. Boolean variables added with the option() function can be turned on/off on the command line as well. For example, freesurfer GUI builds can be disabled by running

cmake . -DBUILD_GUIS=OFF

Aside from this initial configuration step (which really only needs to be run once) and fact that make check is now make test, the rest of the build process is pretty much the same.

note: the make output is more condensed now, but make VERBOSE=1 will output everything.

Overview of the CMake Framework

The top-level CMakeLists.txt file is the main cmake configuration script (which replaces setup_configure, configure.in, and Makefile.am), and all subdirectories are added from here with the add_subdirectory() function. This main script is split into three parts: locating third-party packages, configuring compilation settings, and configuring freesurfer static libs and programs.

Third-Party Packages

Most of the packages required by freesurfer are located via custom "find-modules" stored in the cmake subdirectory. These find-modules expect each package to be installed under a common path defined by FS_PACKAGES_DIR. On Martinos machines, this variable automatically defaults to /usr/pubsw/packages, but external developers must provide this path manually:

cmake . -DFS_PACKAGES_DIR="/path/to/packages"

If a package is not found under FS_PACKAGES_DIR, cmake will continue to look through the default search paths. Alternative paths to package installs can also be specified with the <PACKAGE>_DIR variables. For example, to use a non-default ITK version:

cmake . -DITK_DIR="/usr/pubsw/packages/itk/4.9.1"

Find Modules

In CMakeLists.txt, packages are located by using the find_package() function. Some larger, modern projects, like Qt, VTK, and ITK, distribute cmake config files within their installations, so locating the package's include directory and libraries is a fairly straightfoward process:

find_package(ITK HINTS ${ITK_DIR} REQUIRED)

In this example, if ITK is found by cmake, then ITK_FOUND is set to true, and ITK_INCLUDE_DIRS and ITK_LIBRARIES are set accordingly.

However, most freesurfer dependencies don't ship with cmake configuration files, so we have to create our own find-modules. Fortunately, this isn't too difficult,

External Developers

In general, I think the goal should be to distance ourselves from distributing the pre-built package tarballs since they are difficult to maintain across multiple platforms. The packages/build_packages.py script is a potential alternative to the pre-built archives - it's a utility script to help external developers build freesurfer dependencies on their own.

The packages configured within build_packages.py are built using the tarballs and buildscripts stored in the packages/source dir and will get installed to a destination directory specified on the command-line:

build_packages.py "/path/to/install/destination"

This script loops through each package in the pkgs list, extracts the associated tarball to destination/package-name/version/src, and runs the package build script. The individual build scripts (like [this ITK one](??)) always expect a single input argument that points to the desired install directory. After each successful package build, the checksum of the tarball + build script is saved to the src dir. This way, if this script is rerun, the package is only rebuilt when the source code has been modified

Once the dependencies are built, developers can then point FS_PACKAGES_DIR to their local install directory.

CMake (last edited 2021-03-03 01:25:26 by buildqa)