Attachment 'makefile.txt'
DownloadSHELL:=/bin/sh
define help_text
# All subdirs will be created under the sudirectory where this makefile lives, i.e.,
# ./freesurfer ./packages ./install
#
# ----- build from scratch starting with these steps ----
#
# $$ make nuke <--- remove subdirs ./freesurfer ./packages ./install (the source/build, install trees)
# - you will have to re-check out the annex if you run nuke
#
# $$ make fsco <--- checkout the freesurfer source tree here under ./freesurfer
# $$ make pkg_download <--- get 3rd party packages and place here under ./packages
# $$ make annexco <--- annex checkout of data files. While not required to compile freesurfer, the install pass
# "make install" will fail w/o some annex files. Beware that annexco takes a while.
#
# ----- incrementaly update source and build with steps below -----
#
# $$ make fsupdate <--- tell git to update the ./freesurfer source tree only if no merge is required
#
# $$ make config_print <--- print the cmake command to see the configured options before generating makefiles
# config <--- generate all makefiles with options configured below, CentOS 6,7, Ubuntu 16,18, MacOS
# config_min <--- generate makefiles for a minimal build, i.e., freeview and many mri* commands are not built
#
# $$ make clean <--- run the clean target in the cmake generated Makefiles
#
# $$ make build <--- run parellel build with -j8 under ./freesurfer (using cmake generated makefiles)
# build_s <--- run serial build with -j1 (useful for debugging if errors harder to see in parallel make output)
# build_k <--- run parallel build with -j8 and -k to continue if errors encountered (useful for debugging)
# build_s_k <--- run serial build with -j1 and -k
#
# $$ make run_freeview <--- if the freeview binary was built, try to run it and load a volume file
#
# $$ make install <--- run the install pass creating distribution under ./install
# install_s <--- same as _s above for build target
# install_k <--- same as _k above for build target
# install_s_k <--- same as _k_s above for build target
#
# $$ make test <--- run some individual command tests - requires a python rev 3 in PATH, e.g., anaconda python
#
# *** For more complete testing run a recon-all command, e.g., on subject bert data
endef
this_makefile:=$(firstword $(MAKEFILE_LIST))
this_makefile_abspath:=$(abspath $(dir $(firstword $(MAKEFILE_LIST))))
TOPDIR:=$(this_makefile_abspath)
PKGS_URL:=http://surfer.nmr.mgh.harvard.edu/pub/data/fspackages/prebuilt
# darwin or linux
os:=$(shell uname -s | tr -s '[A-Z]' '[a-z]')
os_type:=$(shell uname -v | tr -s '[A-Z]' '[a-z]')
# LINUX
ifeq ($(os),linux)
# linux: Ubuntu or CentOS
os_rhel:=none
os_rhel_release:= none
os_ubuntu_release:=none
ifneq (,$(wildcard /etc/redhat-release))
# CentOS version
os_rhel:=$(shell cat /etc/redhat-release)
os_rhel_release:=$(shell cat /etc/redhat-release | sed 's;^.*release ;;' | awk '{print $$1}' | sed 's;\..*;;')
else ifneq (,$(wildcard /etc/os-release))
# Ubuntu version
os_ubuntu_release:=$(shell cat /etc/os-release | grep "^VERSION_ID" | sed 's;^.*=;;' | sed 's;\";;g' | sed 's;\..*;;')
endif
# assume permission to run sudo on linux system
# SUDO_CMD:=
SUDO_CMD:=sudo
ifneq (,$(findstring ubuntu,$(os_type)))
# UBUNTU
# *** Not guaranteed to be a comprehensive list
# sudo apt-get install build-essential
# sudo apt-get install libgl1-mesa-dev freeglut3-dev mesa-common-dev
# sudo apt-get install libblas-dev liblapack-dev
# sudo apt-get install ocl-icd-opencl-dev
# sudo apt-get install libxmu-dev libxi-dev
# sudo apt-get install libopencv-dev
# Ubuntu 16: sudo apt-get install gcc-4.9 g++-4.9 gfortran-4.9
# Ubuntu 18: sudo apt-get install gcc-4.8 g++-4.8 gfortran-4.8
# sudo apt-get install xorg xorg-dev libx11-dev
# sudo apt-get install tcl tcl-dev tk tk-dev
# sudo apt-get install qt5-default qtcreator
# sudo apt-get install libqt5x11extras5-dev
# sudo apt-get install git-annex
DEVTOOL_BASE=/usr/bin
BIN_BASE:=$(DEVTOOL_BASE)
LIB_BASE:=/usr/lib
EXTRA_UBUNTU_LINKER_FLAGS:=
ifeq (18,$(os_ubuntu_release))
# gcc-4.8
DEVTOOL_REV:=4.8
# tell linker not to ignore RPATH in binaries (needed as of Ubuntu 17+)
EXTRA_UBUNTU_LINKER_FLAGS:=-Wl,--disable-new-dtags
else ifeq (16,$(os_ubuntu_release))
# gcc-4.9
DEVTOOL_REV:=4.9
else
# Will fail for now - FIX ME: need default
DEVTOOL_REV:=
endif
CMAKE:=/usr/bin/cmake
# CMAKE:=/usr/local/bin/cmake
MAKE:=$(BIN_BASE)/make
CC:=$(BIN_BASE)/gcc-$(DEVTOOL_REV)
CXX:=$(BIN_BASE)/g++-$(DEVTOOL_REV)
GFORTRAN_LIB_BASE:=$(LIB_BASE)/gcc/x86_64-linux-gnu
GFORTRAN_LIBS:=$(GFORTRAN_LIB_BASE)/$(DEVTOOL_REV)
F77:=$(BIN_BASE)/gfortran-$(DEVTOOL_REV)
PKGS_ARCH:=centos7-packages.tar.gz
qt_base:=$(LIB_BASE)/x86_64-linux-gnu/qt5
# else ifneq (,$(findstring CentOS,$(os_rhel)))
else # end Ubuntu
# Start with CentOS settings as default for all other linux systems
# CENTOS
# *** Not guaranteed to be a comprehensive list
# sudo yum install qt-create qt-config.x86_64
# sudo yum install qt5-qtx11extras.x86_64 qt5-qtx11extras-devel.x86_64
# sudo yum install boost.x86_64 boost-devel.x86_64
# sudo yum install tk-devel.x86_64
# sudo yum install opencl-filesystem.noarch opencl-headers.noarch
# sudo yum install opencv.x86_64 opencv-devel.x86_64
# CentOS 6: use scl enable devtoolset-2 bash to get gcc4.8 when running the build target
# centOS 7: sudo yum install cmake3.x86_64 cmake3-data.noarch cmake3-doc.noarch cmake3-gui.x86_64
# yum install git-annex
DEVTOOL_BASE=/usr/bin
BIN_BASE:=$(DEVTOOL_BASE)
LIB_BASE:=/usr/lib
DEVTOOL_REV:=4.8.2
ifeq (6,$(os_rhel_release))
CMAKE:=/usr/pubsw/bin/cmake
else
CMAKE:=$(BIN_BASE)/cmake3
endif
MAKE:=$(BIN_BASE)/make
CC:=$(shell which gcc)
CXX:=$(shell which g++)
F77:=$(shell which gfortran)
ifeq (6,$(os_rhel_release))
GFORTRAN_LIBS:=/opt/rh/devtoolset-2/root/usr/lib/gcc/x86_64-redhat-linux/$(DEVTOOL_REV)
else
GFORTRAN_LIBS:=$(LIB_BASE)/gcc/x86_64-redhat-linux/$(DEVTOOL_REV)
endif
PKGS_ARCH:=centos7-packages.tar.gz
qt_base:=/usr/lib64
endif # CentOS
# DARWIN (MAC)
#
# Homebrew requires a full install of Xcode (not just the command line tools). You can get the
# most recent version fo Xcode from the App Store. For older versions of MacOS, you can get
# a matching older version of Xcode from the Apple Developers web site (you will need an account
# there), https://developer.apple.com/
#
# In addition to installing homebrew (by default under /usr/local), install the gcc-5 compilers
#
# brew update
# brew install gcc@5
else ifeq ($(os),darwin)
# assume permission to run sudo on Mac
SUDO_CMD:=sudo
# SUDO_CMD:=
# use homebrew
HOMEBREW_ROOT:=/usr/local
HOMEBREW_BIN_BASE:=$(HOMEBREW_ROOT)/bin
HOMEBREW_CELLAR_BASE:=$(HOMEBREW_ROOT)/Cellar
HOMEBREW_OPT_BASE:=$(HOMEBREW_ROOT)/opt
CMAKE:=$(HOMEBREW_BIN_BASE)/cmake
BIN_NO_CCACHE_BASE:=$(HOMEBREW_BIN_BASE)
BIN_CCACHE_BASE:=$(HOMEBREW_OPT_BASE)/ccache/libexec
# no ccache version of F77
F77:=$(BIN_NO_CCACHE_BASE)/gfortran-5
ifneq (,$(USE_CCACHE))
BIN_BASE:=$(BIN_CCACHE_BASE)
$(warning +++ USING CCACHE versions of gcc and g++)
else
BIN_BASE:=$(BIN_NO_CCACHE_BASE)
endif
CC:=$(BIN_BASE)/gcc-5
CXX:=$(BIN_BASE)/g++-5
# GNU make 4.0 and above preserves correct order of log output with -jN for N>1
# brew install homebrew/core/make
ifneq (,$(wildcard $(HOMEBREW_BIN_BASE)/gmake))
MAKE:=$(HOMEBREW_BIN_BASE)/gmake
else
# default should be make 3.8x
MAKE:=/usr/bin/make
endif
PKGS_ARCH:=osx10.11-packages.tar.gz
# qt_base=/Volumes/hd-3/Qt5.10.0/5.10.0/clang_64
qt_base=$(HOMEBREW_CELLAR_BASE)/qt/5.11.2
endif # darwin
GIT_BASE:=$(TOPDIR)
EXTRA_PKGS_BASE:=$(GIT_BASE)/packages
BUILD_BASE:=$(GIT_BASE)/freesurfer
INSTALL_BASE:=$(TOPDIR)/install
# first or default target is help
.PHONY: help nuke fsco pkg_download annexco fsupdate
help:
$(call help_text)
# For complete checkout and build from scratch run targets:
# nuke, fsco, pkg_download, annexco, config, build, install
# Everything will be created underneath the parent subdir where this makefile fragment is located
all_src: nuke fsco pkg_download annexco fsupdate
nuke:
mkdir -p $(GIT_BASE)
(cd $(GIT_BASE) && $(SUDO_CMD) rm -rf ./freesurfer)
fsco:
mkdir -p $(GIT_BASE)
(cd $(GIT_BASE) && git clone -b dev https://github.com/freesurfer/freesurfer.git)
.PHONY: pkg_download
pkg_download:
(cd $(GIT_BASE) && mkdir -p ./packages && chmod -R 777 ./packages)
(cd $(GIT_BASE) && rm -rf ./packages)
(cd $(GIT_BASE) && curl -O $(PKGS_URL)/$(PKGS_ARCH))
(cd $(GIT_BASE) && tar zxpf $(PKGS_ARCH))
ls ./packages
# Try to speed up with number of jobs for git annex get > 1
ifeq ($(os),darwin)
# ANNEX_JOBS:=--jobs=10
ANNEX_JOBS:=
else
# option not available on linux
ANNEX_JOBS:=
endif
annexco:
(cd $(BUILD_BASE) && git remote add datasrc http://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/repo/annex.git)
(cd $(BUILD_BASE) && git fetch datasrc)
(cd $(BUILD_BASE) && git annex get $(ANNEX_JOBS) .)
(cd $(BUILD_BASE) && git status)
# ignore this error, but check for broken soft links which means annex fetch had a problem
-(cd $(BUILD_BASE) && find . | xargs file | grep -i "broken")
# only update source if can fast forward (no merge required)
fsupdate:
(cd $(BUILD_BASE) && git pull --ff-only)
ifndef config_cmd
ifeq ($(os),linux)
ifneq (,$(findstring ubuntu,$(os_type)))
# Ubuntu
config_cmd:=\
CC=$(CC) \
CXX=$(CXX) \
FC=$(F77) \
$(CMAKE) \
-DCMAKE_MAKE_PROGRAM=$(MAKE) \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DFS_PACKAGES_DIR=$(EXTRA_PKGS_BASE) \
-DCMAKE_CXX_FLAGS:STRING="${CMAKE_CXX_FLAGS} -I/usr/include/tcl -Wno-deprecated -Wno-deprecated-declarations" \
-DX11_INCLUDE_DIR=/usr/include/X11 \
-DOPENGL_glu_LIBRARY=$(LIB_BASE)/x86_64-linux-gnu/libGLU.so.1 \
-DOpenCL_INCLUDE_DIRS=/usr/include \
-DCMAKE_RULE_MESSAGES:BOOL=ON \
-DCMAKE_INSTALL_PREFIX="$(INSTALL_BASE)" \
-DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS} $(EXTRA_UBUNTU_LINKER_FLAGS) -L$(LIB_BASE)/x86_64-linux-gnu -L/usr/local/lib -lz" \
-DGFORTRAN_LIBRARIES=$(GFORTRAN_LIBS)/libgfortran.so
# else ifneq (,$(findstring CentOS,$(os_rhel)))
else # end Ubuntu
# Start with CentOS settings as default for all other linux systems
config_cmd:=\
$(CMAKE) \
-DCMAKE_MAKE_PROGRAM=$(MAKE) \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DFS_PACKAGES_DIR=$(EXTRA_PKGS_BASE) \
-DCMAKE_CXX_FLAGS:STRING="${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-deprecated-declarations" \
-DCMAKE_RULE_MESSAGES:BOOL=ON \
-DCMAKE_INSTALL_PREFIX="$(INSTALL_BASE)" \
-DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS} -lz" \
-DGFORTRAN_LIBRARIES=$(GFORTRAN_LIBS)/libgfortran.so
endif # CentOS/default linux
else ifeq ($(os),darwin)
config_cmd=\
CC=$(CC) \
CXX=$(CXX) \
FC=$(F77) \
$(CMAKE) \
-DCMAKE_MAKE_PROGRAM=$(MAKE) \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DFS_PACKAGES_DIR=$(EXTRA_PKGS_BASE) \
-DCMAKE_RULE_MESSAGES:BOOL=ON \
-DCMAKE_INSTALL_PREFIX="$(INSTALL_BASE)"
endif # darwin
endif # config_cmd
# Do minimal build for target config_min
ifeq (config_min,$(findstring config_min,$(MAKECMDGOALS)))
config_cmd+=-DMINIMAL:BOOL=ON
endif
ifneq (,$(wildcard $(qt_base)))
config_cmd+=-DCMAKE_PREFIX_PATH=$(qt_base)
else
$(warning Could not stat path to qt distribution $(qt_base), so skipping adding it via -DCMAKE_PREFIX_PATH)
endif
export config_cmd
.PHONY: config_print config config_min config_common clean
config_print:
@echo "$(config_cmd)"
# Allow devtoolsets (with different compilers) to be used for CentOS builds
devtoolset_config_cmd=
config config_min:
ifeq (6,$(os_rhel_release))
scl enable devtoolset-2 '$(MAKE) config_cmd=$(config_cmd) -f $(this_makefile) config_common'
else
$(MAKE) -f $(this_makefile) config_common
endif
config_common:
(cd $(BUILD_BASE) && rm -f CMakeCache.txt && rm -f cmake.log)
(cd $(BUILD_BASE) && $(config_cmd) . 2>&1 | tee -a cmake.log)
ifndef MAKE_OPTS
MAKE_OPTS:=VERBOSE=1
define make_opt_keepgoing
MAKE_OPTS+=-k
endef
define make_opt_serial
MAKE_OPTS+=-j1
endef
define make_opt_parallel
MAKE_OPTS+=-j8
endef
endif # MAKE_OPTS
export MAKE_OPTS
clean:
(cd $(BUILD_BASE) && $(MAKE) $(MAKE_OPT) clean)
# target "build" default is to build with VERBOSE and -j8
# target "build_k" or append _k to target for -k keepgoing option past any compilation errors
# target "build_s" or append _s to build serially (-j1) which is useful for debugging builds especially
# target "build_k_s" to combine options -k and -j1
# default is to build parallel with -j8
.PHONY: build build_k build_s build_k_s build_s_k
build build_k build_s build_k_s build_s_k:
$(if $(findstring _s,$@),$(eval $(make_opt_serial)),$(eval $(make_opt_parallel)))
$(if $(findstring _k,$@),$(eval $(make_opt_keepgoing)),)
ifeq (6,$(os_rhel_release))
scl enable devtoolset-2 '$(MAKE) -f $(this_makefile) build_common'
else
# assume native compilers should work
$(MAKE) $(MAKE_OPTS) -f $(this_makefile) build_common
endif
.PHONY: build_common
# build target above runs common build target
build_common:
which $(MAKE) && $(MAKE) --version
(cd $(BUILD_BASE) && rm -f make.log && $(MAKE) $(MAKE_OPTS) 2>&1 | tee -a make.log)
# default is to build parallel with -j8
.PHONY: install install_k install_s install_k_s install_s_k
# Assume nothing left to be compiled when install target is run, so scl enable does not need to be run
install install_k install_s install_k_s install_s_k:
$(if $(findstring _s,$@),$(eval $(make_opt_serial)),$(eval $(make_opt_parallel)))
$(if $(findstring _k,$@),$(eval $(make_opt_keepgoing)),)
mkdir -p $(INSTALL_BASE)
(cd $(INSTALL_BASE) && $(SUDO_CMD) rm -rf *)
(cd $(BUILD_BASE) && rm -f install.log && $(SUDO_CMD) $(MAKE) $(MAKE_OPTS) install 2>&1 | tee -a install.log)
ls $(INSTALL_BASE)
.PHONY: test
python_rev:=$(shell python --version)
# uncomment and add the path to your license here
# test: export FS_LICENSE=
test: export FREESURFER_HOME=$(INSTALL_BASE)
test: export CTEST_OUTPUT_ON_FAILURE=1
test:
ifeq (,$(findstring Python 3,$(python_rev)))
@echo "Cannot run $@ target without a python version 3.X in PATH"
else
(cd $(BUILD_BASE) && rm -f test.log && $(MAKE) $(MAKE_OPT) test 2>&1 | tee -a test.log)
endif
# After install target, check if GUI based freeview runs.
# Note that freeview is not built in a "minimal" buid with -DMININAL cmake option
freeview_volume:=$(INSTALL_BASE)/subjects/cvs_avg35/mri/T1.mgz
ifeq (,$(wildcard $(freeview_volume)))
freeview_volume:=
endif
ifeq ($(os),linux)
freeview_binary:=freeview
freeview_cmd:=./$(freeview_binary) $(freeview_volume)
freeview_install_dir:=$(INSTALL_BASE)/bin
else ifeq ($(os),darwin)
freeview_binary:=Freeview.app
freeview_cmd:=open -a $(freeview_binary) $(freeview_volume)
freeview_install_dir:=$(INSTALL_BASE)
endif
.PHONY: run_freeview
run_freeview:
ifneq (,$(wildcard $(BUILD_BASE)/freeview/$(freeview_binary)))
(cd $(BUILD_BASE)/freeview && $(freeview_cmd))
else ifneq (,$(wildcard $(freeview_install_dir)/$(freeview_binary)))
(cd $(freeview_install_dir) && $(freeview_cmd))
else
$(warning No freeview binary to run under $(BUILD_BASE)/freeview or $(INSTALL_BASE))
$(warning Please check that freeview was built ad/or installed)
endif # test for freeview
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.
