#!/bin/bash #+ # ARES/HADES/BORG Package -- ./build.sh # Copyright (C) 2016-2018 Guilhem Lavaux # Copyright (C) 2020 Florent Leclercq # # Additional contributions from: # Guilhem Lavaux (2023) # #+ print_help() { cat < /dev/null 2>&1; then echo "${cmd} is not available. ${msg}"; exit 1 fi echo -e "-- ${C_WHITE}${C_BG_GREEN}Found:${C_DEFAULT} ${C_WHITE}${cmd}${C_DEFAULT}" } check_existence() { if test "$1" = "-q"; then quiet=1 shift else quiet=0 fi file="$1" error_message="$2" if ! test -e "${file}"; then echo "-- ${C_RED}${C_BG_WHITE}Not found:${C_DEFAULT} ${file}" echo "${error_message}" exit 1 fi if test $quiet = 0; then echo -e "-- ${C_WHITE}${C_BG_GREEN}Found:${C_DEFAULT} ${file}" fi } echo "Ensure the current directory is ARES" check_existence -q "src/ares3.cpp" "Please move current working directory to ares3 source directory." check_existence -q "external/cosmotool/CMakeLists.txt" "Submodules were not cloned. Please run 'git submodule update --init --recursive' (WARNING! You might have to start from afresh.)." srcdir=$(pwd) build_dir=${srcdir}/build build_type=Release cmake=cmake cmake_flags=() c_compiler=$(which cc) cxx_compiler=$(which c++) USE_PREDOWNLOAD=1 julia_binary= do_purge=0 cmake_generator= while test $# -gt 0; do key="$1" case $key in --cmake) cmake="$2" shift ;; --extra-flags) cmake_flags+=($2) shift ;; --without-openmp) cmake_flags+=(-DENABLE_OPENMP:BOOL=OFF) ;; --with-mpi) cmake_flags+=(-DENABLE_MPI:BOOL=ON) ;; --c-compiler) c_compiler=$(which $2) shift ;; --cxx-compiler) cxx_compiler=$(which $2) shift ;; --julia) julia_binary="$2" shift ;; --build-dir) build_dir="$2" shift ;; --debug) build_type="Debug" ;; --no-debug-log) cmake_flags+=(-DDISABLE_DEBUG_OUTPUT:BOOL=ON) ;; --eclipse) cmake_generator=eclipse ;; --native) cmake_flags+=(-DUSE_NATIVE_ARCH:BOOL=ON) ;; --perf) cmake_flags+=(-DCONTEXT_TIMER:BOOL=ON) ;; --with-julia) cmake_flags+=(-DBUILD_JULIA:BOOL=ON) ;; --install-user-python) cmake_flags+=(-DINSTALL_PYTHON_LOCAL=ON) ;; --install-system-python) cmake_flags+=(-DINSTALL_PYTHON_LOCAL=OFF) ;; --python|--python=*) if [[ $1 =~ ^--python=(.+)$ ]]; then PYTHON_PATH=${BASH_REMATCH[1]} cmake_flags+=(-DPYTHON_EXECUTABLE=${PYTHON_PATH}) fi cmake_flags+=(-DBUILD_PYTHON_EXTENSION:BOOL=ON) ;; --hades-python) cmake_flags+=(-DBUILD_PYTHON_EXTENSION:BOOL=ON -DBUILD_PYTHON_EMBEDDER:BOOL=ON) ;; --skip-building-tests) cmake_flags+=(-DBUILD_TESTING:BOOL=OFF) ;; --ninja) cmake_generator=ninja ;; --no-predownload) USE_PREDOWNLOAD=0 ;; --use-predownload) USE_PREDOWNLOAD=1 ;; --download-deps) #This step requires wget. if ! command -v wget > /dev/null 2>&1; then echo "The command wget is required to pre-download the dependencies. Please install it before retrying. Also it must be" echo "available from the PATH" exit 1 fi lf=$'\n' grep -E "SET\\([a-zA-Z0-9_]+_URL" ${srcdir}/external/external_build.cmake |grep -e 'ftp://' | sed -e "s%^.*(\([a-zA-Z0-9_]*\)_URL[ ]*\"\(ftp.*\)\"[ ]*CACHE.*$%\1_URL \\$lf\2%g" > pre_list grep -E "SET\\([a-zA-Z0-9_]+_URL" ${srcdir}/external/external_build.cmake | grep -E 'https?://' |sed -e "s%^.*(\([a-zA-Z0-9_]*\)_URL[ ]*\"\(http.*\)\"[ ]*CACHE.*$%\1_URL \\$lf\2%g" >> pre_list test -e ${srcdir}/downloads || mkdir ${srcdir}/downloads; ( \ cd ${srcdir}/downloads; \ rm -f deps.txt; \ echo $dlist while read url_name; do \ read d; \ prename=$(echo $url_name | sed -e 's%^\([a-zA-Z0-9]\+\)_URL%\L\1%g') ; \ d_tmp=$(echo $d | cut -d/ -f2-); \ if [[ $d_tmp =~ /.*/([^/]*(tar\.|zip)[^/]*).* ]]; then \ out_d=${BASH_REMATCH[1]}; \ else \ echo "Error matching $d"; \ exit 1; \ fi; \ out_d=${prename}_$out_d; \ echo "Downloading $d for ${url_name} to ${out_d}"; \ if ! test -e ${out_d}; then wget --no-check-certificate --quiet -O $out_d $d || (echo "${C_RED}Failure to download $d to $out_d${C_DEFAULT}"; exit 1) || exit 1; \ else echo "=> Already downloaded ${out_d}"; \ fi; \ echo ${url_name} >> deps.txt; \ echo ${out_d} >> deps.txt; \ done \ ) < pre_list || echo "${C_RED}Error.${C_DEFAULT} " rm -f pre_list echo "Done. You can now upload the ${srcdir}/downloads/ directory to the remote computer in the source directory and use --use-predownload." exit 0 ;; -h|--h|--he|--hel|--help) print_help exit 1 ;; --use-system-fftw|--use-system-fftw=*) if [[ $1 =~ ^--use-system-fftw=(.+)$ ]]; then FFTW_PATH=${BASH_REMATCH[1]} else if [[ $FFTW_INC =~ ^(.+)/include$ ]]; then FFTW_PATH=${BASH_REMATCH[1]} fi fi cmake_flags+=(-DINTERNAL_FFTW:BOOL=OFF) if [ "x$FFTW_PATH" != x ]; then CMAKE_PREFIX_PATH="${FFTW_PATH};${CMAKE_PREFIX_PATH}" fi add_skip FFTW_URL ;; --use-system-hdf5|--use-system-hdf5=*) if [[ $1 =~ ^--use-system-hdf5=(.+)$ ]]; then HDF5_ROOT=${BASH_REMATCH[1]} cmake_flags+=(-DINTERNAL_HDF5:BOOL=OFF "-DHDF5_ROOT=${HDF5_ROOT}") else cmake_flags+=(-DINTERNAL_HDF5:BOOL=OFF) fi add_skip HDF5_URL ;; --use-system-boost|--use-system-boost=*) cmake_flags+=(-DINTERNAL_BOOST:BOOL=OFF) if [[ $1 =~ ^--use-system-boost=(.+)$ ]]; then boost_root=${BASH_REMATCH[1]} cmake_flags+=("-DBOOST_ROOT=${boost_root}") fi add_skip BOOST_URL ;; --use-system-eigen|--use-system-eigen=*) cmake_flags+=(-DINTERNAL_EIGEN:BOOL=OFF) if [[ $1 =~ ^--use-system-eigen=(.+)$ ]]; then EIGEN_PATH=${BASH_REMATCH[1]} cmake_flags+=(-DEIGEN_PATH:PATH=${EIGEN_PATH}) fi add_skip EIGEN_URL ;; --use-system-gsl) cmake_flags+=(-DINTERNAL_GSL:BOOL=OFF) if ! command -v gsl-config > /dev/null 2>&1; then errormsg "Missing 'gsl-config' in the execution path.\n I cannot detect location of GSL" exit 1 fi CMAKE_PREFIX_PATH="$(gsl-config --prefix);${CMAKE_PREFIX_PATH}" add_skip GSL_URL ;; --purge) do_purge=1 ;; --update-tags) echo "Updating tags file." rm -f ctags for module in . extra/hades extra/borg extra/virbius extra/hmclet extra/dm_sheet; do if test -e ${module}; then (cd ${module}; git ls-files '*.[ch]pp' | awk "{ print \"${module}/\" \$0;}") | xargs ctags -a fi done echo "Done. Exiting." exit 0 ;; *) echo "Unknown option. Abort." print_help exit 1 ;; esac shift done if test ${USE_PREDOWNLOAD} = 1; then if ! test -d "${srcdir}/downloads"; then echo "--- ${C_RED}No deps predownloaded. Stop${C_DEFAULT} ---" exit 1 fi cmd=$( ( flags=() while read url_name; do if [[ "${url_name}" =~ ^(${skip_url})$ ]]; then read path; continue fi read path; path="${srcdir}/downloads/${path}"; flags+=("-D${url_name}:URL=file://${path}"); done; echo "cmake_flags+=(${flags[@]})" ) < ${srcdir}/downloads/deps.txt ) eval ${cmd} else echo "--- ${C_ORANGE}WARNING: Not using predownloaded deps.${C_DEFAULT} --- " fi export CMAKE_PREFIX_PATH #CMAKE_PREFIX_PATH=$(printf %q "${CMAKE_PREFIX_PATH}") cmake_flags+=(-DARES_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_BUILD_TYPE=${build_type} -DCMAKE_C_COMPILER=${c_compiler} -DCMAKE_CXX_COMPILER=${cxx_compiler}) if test x"${julia_binary}" != x""; then cmake_flags+=(-DJULIA_EXECUTABLE=${julia_binary}) fi if test x$cmake_generator = "xninja"; then cmake_flags+=("-GNinja") elif test x$cmake_generator = "xeclipse"; then cmake_flags+=("-GEclipse CDT4 - Unix Makefiles") fi echo "Summary of CMAKE_FLAGS:" for f in "${cmake_flags[@]}"; do printf " %s\n" "$f" done if test -e ${build_dir}; then if test x${do_purge} == x1; then rm -f -r ${build_dir} else while true; do echo -n "${build_dir} already exists. Remove ? [y/n] " read RESULT if test "x${RESULT}" = "xn"; then echo "Abort" exit 1 fi if test "x${RESULT}" = "xy"; then echo "Removing" rm -f -r ${build_dir} break fi done fi fi check_command "${cmake}" "Please install CMake or provide --cmake to build.sh" #check_command autoconf "Autoconf is missing. Please install it." #check_command automake "Automake is missing. Please install it." check_command patch "Patch is missing. Please install it." check_command pkg-config "Pkgconfig is missing. Please install it." if ! mkdir -p ${build_dir}; then echo -e "${C_WHITE}--------------------------${C_DEFAULT}" echo -e "${C_BG_RED}Cannot create build directory.${C_DEFAULT}" echo -e "${C_WHITE}--------------------------${C_DEFAULT}" echo exit 1 fi if ! ( \ cd ${build_dir} && \ ${cmake} "${cmake_flags[@]}" ${srcdir}; \ exit $? \ ); then echo -e "${C_WHITE}-------------------------------------------------${C_DEFAULT}" echo -e "${C_BG_RED}An error occured in CMake.${C_DEFAULT}" echo -e "${C_BG_RED}Please collect the messages above in your report.${C_DEFAULT}" echo -e "${C_WHITE}-------------------------------------------------${C_DEFAULT}" echo exit 1 fi cat <