|
Size: 5342
Comment:
|
Size: 2604
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 1: | Line 1: |
| ## page was renamed from cmake = FreeSurfer CMake Port = This page is mostly for documenting the process of converting the automake framework to cmake. General documentation for using cmake with freesurfer can be found here. <<BR>> |
= FreeSurfer CMake = |
| Line 10: | Line 5: |
| CMake replaces the `setup_configure` and `configure` build steps. A build can be initialized in the working directory by running `cmake </path/to/repo>`. So, assuming you have a freesurfer repository stored in `~/dev/freesurfer`, you could set up a simple in-source build with | CMake replaces the `setup_configure` and `configure` build steps. A build can be initialized in the working directory by running `cmake </path/to/repo>`. So, assuming you have a freesurfer repository stored in `~/dev/freesurfer` (and you're developing on the Martinos filesystem), you could set up a simple in-source build with: |
| Line 17: | Line 12: |
| or an out-of-source build with | '''note:''' if this is your first time transitioning from an automake configuration, you might need to run `make clean` before building with cmake. Some of the previously generated freeview moc files might interfere with the configuration. |
| Line 19: | Line 14: |
| {{{ cd ~/dev/fsbuild cmake ~/dev/freesurfer }}} |
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 exactly the same. Alternatively, `ccmake` can be used instead of `cmake` to configure/edit cached variables in a terminal GUI. Out-of-source builds are also possible with cmake. |
| Line 24: | Line 16: |
| Alternatively, `ccmake` can be used instead of `cmake` to configure/edit cached variables in a terminal GUI. | '''note:''' the `make` output is more condensed now, but `make VERBOSE=1` will output everything. |
| Line 40: | Line 32: |
| 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. | == Adding a binary == |
| Line 42: | Line 34: |
| '''note:''' the `make` output is more condensed now, but `make VERBOSE=1` will output everything. <<BR>> == 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 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: |
All freesurfer binaries should contain a CMakeLists.txt file (replacing Makefile.am) in their corresponding subdirectory, and the name of the subdirectory should be added to the large list at the end of the top-level CMakeLists.txt. As an example, the CMakeLists.txt for a standard freesurfer executable (called my_program) that only links to the utils library would look something like this: |
| Line 55: | Line 37: |
| cmake . -DFS_PACKAGES_DIR="/path/to/packages" | project(my_program) include_directories(${FS_INCLUDE_DIRS}) add_executable(my_program my_program.c) target_link_libraries(my_program utils) install(TARGETS my_program DESTINATION bin) |
| Line 58: | Line 47: |
| 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_DIR` and `ITK_LIBRARIES` are set accordingly. This syntax and variables generated by `find_package()` all follow the same pattern. 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, the goal is 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 variable, 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 is saved to the src dir - this way, the package is only rebuilt when the source code has been modified. Once the dependencies are compiled and installed, developers can then point `FS_PACKAGES_DIR` to their local install directory. For now, we should still offer the prebuilt packages since it's just easier for most developers and we need them for the travis builds anyway. ==== Removing packages From Source ==== The non-FS libraries (like jpeg, glut, xml2, expat, minc, netcdf, etc...) that used to be built within freesurfer no longer get built by cmake. These packages are now expected in FS_PACKAGES_DIR. The main advantage of this |
A more complex CMakeLists.txt might be required for binaries that depend on other libraries. For example, [[https://github.com/freesurfer/freesurfer/blob/dev/mris_mesh_subdivide/CMakeLists.txt|here's the configuration file]] for mris_mesh_subdivide, which requires VTK. |
FreeSurfer CMake
Configuring a Simple Build
CMake replaces the setup_configure and configure build steps. A build can be initialized in the working directory by running cmake </path/to/repo>. So, assuming you have a freesurfer repository stored in ~/dev/freesurfer (and you're developing on the Martinos filesystem), you could set up a simple in-source build with:
cd ~/dev/freesurfer cmake .
note: if this is your first time transitioning from an automake configuration, you might need to run make clean before building with cmake. Some of the previously generated freeview moc files might interfere with the configuration.
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 exactly the same. Alternatively, ccmake can be used instead of cmake to configure/edit cached variables in a terminal GUI. Out-of-source builds are also possible with cmake.
note: the make output is more condensed now, but make VERBOSE=1 will output everything.
Configuration Options
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 CMakeLists.txt 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
Adding a binary
All freesurfer binaries should contain a CMakeLists.txt file (replacing Makefile.am) in their corresponding subdirectory, and the name of the subdirectory should be added to the large list at the end of the top-level CMakeLists.txt. As an example, the CMakeLists.txt for a standard freesurfer executable (called my_program) that only links to the utils library would look something like this:
project(my_program)
include_directories(${FS_INCLUDE_DIRS})
add_executable(my_program my_program.c)
target_link_libraries(my_program utils)
install(TARGETS my_program DESTINATION bin)A more complex CMakeLists.txt might be required for binaries that depend on other libraries. For example, here's the configuration file for mris_mesh_subdivide, which requires VTK.
