Newer
Older
################################################################################
# Copyright 2018-2021, Barcelona Supercomputing Center (BSC), Spain #
# Copyright 2015-2021, Johannes Gutenberg Universitaet Mainz, Germany #
# #
# This software was partially supported by the #
# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). #
# #
# This software was partially supported by the #
# ADA-FS project under the SPPEXA project funded by the DFG. #
# #
# This file is part of GekkoFS. #
# #
# GekkoFS is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# GekkoFS is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. #
# #
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
PATCH_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PATCH_DIR="${PATCH_DIR}/patches"
DEPENDENCY=""
CORES=""
SOURCE_DIR=""
INSTALL_DIR=""
PERFORM_TEST=
EXECUTION_MODE=
DEFAULT_PROFILE="default"
DEFAULT_VERSION="latest"
PROFILE_NAME=${DEFAULT_PROFILE}
PROFILE_VERSION=${DEFAULT_VERSION}
PROFILES_DIR="${PWD}/profiles"
declare -a PROFILE_DEP_LIST
declare -A PROFILE_DEP_NAMES
declare -A PROFILE_WGETDEPS PROFILE_CLONEDEPS PROFILE_SOURCES PROFILE_EXTRA_INSTALL_ARGS
declare -A PROFILE_CLONEDEPS_ARGS PROFILE_CLONEDEPS_PATCHES
usage_short() {
echo "
usage: compile_dep.sh -p PROFILE_NAME[:PROFILE_VERSION] |
-d DEPENDENCY_NAME[[@PROFILE_NAME][:PROFILE_VERSION]] |
-l [PROFILE_NAME:[PROFILE_VERSION]] | -n | -h
[ -j COMPILE_CORES]
"
}
help_msg() {
This script compiles all GekkoFS dependencies (excluding the fs itself)
positional arguments:
SOURCES_PATH path to the downloaded sources for the dependencies
INSTALL_PATH path to the installation directory for the built dependencies
optional arguments:
-h, --help shows this help message and exits
-l, --list-dependencies [[PROFILE_NAME:]PROFILE_VERSION]
list dependencies available for building and installation
-p, --profile PROFILE_NAME[:PROFILE_VERSION]
allows installing a pre-defined set of dependencies as defined
in \${PROFILES_DIR}/PROFILE_NAME.specs. This is useful to
deploy specific library versions and/or configurations,
using a recognizable name. Optionally, PROFILE_NAME may include
a specific version for the profile, e.g. 'mogon2:latest' or
'ngio:0.8.0', which will download the dependencies defined for
that specific version. If unspecified, the 'default:latest' profile
will be used, which should include all the possible dependencies.
-d, --dependency DEPENDENCY_NAME[[@PROFILE_NAME][:PROFILE_VERSION]]
build and install a specific dependency, ignoring any --profile
option provided. If PROFILE_NAME is unspecified, the 'default'
profile will be used. Similarly, if PROFILE_VERSION is
unspecified, the 'latest' version of the specified profile will
be used.
-j, --compilecores COMPILE_CORES
defaults to number of available cores
-t, --test Perform libraries tests.
-n, --dry-run
Do not actually run, print only what would be done.
}
exec_mode_error() {
echo "ERROR: --profile and --dependency options are mutually exclusive"
usage_short
exit 1
}
if [[ ! -d "${PROFILES_DIR}" ]]; then
echo "Directory '${PROFILES_DIR}' does not exist. No profiles available."
exit 1
fi
declare -A versions
while IFS= read -r -d '' filename; do
id="$(basename $(dirname ${filename}))"
profile="$(basename ${filename%%.specs})"
versions[$id]+="${profile} "
done < <(find -L "${PROFILES_DIR}" -type f -name "*.specs" -print0 | sort -z)
echo -e "Available versions and configuration profiles:\n"
for id in "${!versions[@]}"; do
echo " ${id}:"
echo -e " ${versions[${id}]}\n"
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
exit 0
}
list_profiles() {
local TAG=$1
if [[ "$TAG" =~ ^(.*):(.*)$ ]]; then
PROFILE="${BASH_REMATCH[1]}.specs"
if [[ -n ${BASH_REMATCH[2]} ]]; then
VERSION="${BASH_REMATCH[2]}"
else
VERSION="latest"
fi
else
VERSION="${TAG}"
fi
if [[ ! -d "${PROFILES_DIR}" ]]; then
echo "Directory '${PROFILES_DIR}' does not exist. No configuration profiles found."
exit 1
fi
if [[ ! -d "${PROFILES_DIR}/${VERSION}" ]]; then
echo "Version ${VERSION} does not exist. No configuration profiles found."
exit 1
fi
echo -e "Configuration profiles for '${VERSION}':\n"
find "${PROFILES_DIR}/${VERSION}/${PROFILE}" -type f -name "*.specs" -print0 | sort -z | while IFS= read -r -d '' filename; do
basename=$(basename "${filename}")
version=$(basename $(dirname "${filename}"))
profile="${basename%.*}"
echo "* ${profile}:${version} (${filename})"
source "${filename}"
if [[ -n "${comment}" ]]; then
echo -e "\n ${comment}\n"
fi
for d in "${order[@]}";
do
if [[ -n ${wgetdeps[${d}]} ]]; then
echo " ${d}: ${wgetdeps[${d}]}"
elif [[ -n ${clonedeps[${d}]} ]]; then
echo " ${d}: ${clonedeps[${d}]}"
else
echo " ${d}: ???"
fi
done
echo ""
unset wgetdeps
unset clonedeps
unset clonedeps_args
unset clonedeps_patches
unset comment
unset order
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
exit 0
}
load_profile() {
local profile=$1
local version=$2
shift
# make sure we are in a known state
PROFILE_DEP_NAMES=()
PROFILE_DEP_LIST=()
PROFILE_CLONEDEPS=()
PROFILE_CLONEDEPS_ARGS=()
PROFILE_CLONEDEPS_PATCHES=()
PROFILE_WGETDEPS=()
local filename="${PROFILES_DIR}/${version}/${profile}.specs"
if [[ ! -f "${filename}" ]]; then
echo "Profile '${profile}:${version}' does not exist."
exit 1
fi
source "${filename}"
# some checks
if [[ -z "${wgetdeps[*]}" && -z "${clonedeps[*]}" ]]; then
echo "Profile '${profile}' is invalid."
exit 1
fi
if [[ -z "${order[*]}" ]]; then
echo "Profile '${profile}' is invalid."
exit 1
fi
if [[ "$((${#wgetdeps[@]}+${#clonedeps[@]}))" -ne "${#order[@]}" ]]; then
echo "Profile '${profile}' is invalid."
exit 1
fi
# propagate results outside of function
for i in "${!order[@]}"; do
PROFILE_DEP_LIST[$i]="${order[${i}]}"
PROFILE_DEP_NAMES["${order[$i]}"]="$i"
for k in "${!clonedeps[@]}"; do
PROFILE_CLONEDEPS["${k}"]="${clonedeps[${k}]}"
for k in "${!clonedeps_args[@]}"; do
PROFILE_CLONEDEPS_ARGS["${k}"]="${clonedeps_args[${k}]}"
for k in "${!clonedeps_patches[@]}"; do
PROFILE_CLONEDEPS_PATCHES["${k}"]="${clonedeps_patches[${k}]}"
for k in "${!wgetdeps[@]}"; do
PROFILE_WGETDEPS["${k}"]="${wgetdeps[${k}]}"
done
for k in "${!extra_install_args[@]}"; do
PROFILE_EXTRA_INSTALL_ARGS["${k}"]="${extra_install_args["${k}"]}"
done
prepare_build_dir() {
if [ ! -d "$1/build" ]; then
mkdir "$1"/build
fi
rm -rf "$1"/build/*
}
local CMAKE
CMAKE=$(command -v cmake3 || command -v cmake)
echo >&2 "ERROR: could not find cmake"
echo "${CMAKE}"
while [[ $# -gt 0 ]]; do
key="$1"
case ${key} in
[ -n "${EXECUTION_MODE}" ] && exec_mode_error || EXECUTION_MODE='profile'
if [[ -z "$2" ]]; then
echo "ERROR: Missing argument for -p/--profile option"
exit 1
fi
if [[ "$2" =~ ^(.*):(.*)$ ]]; then
PROFILE_NAME="${BASH_REMATCH[1]}"
PROFILE_VERSION="${BASH_REMATCH[2]}"
else
PROFILE_NAME="$2"
PROFILE_VERSION="${DEFAULT_VERSION}"
shift # past argument
shift # past value
;;
-d | --dependency)
[ -n "${EXECUTION_MODE}" ] && exec_mode_error || EXECUTION_MODE='dependency'
if [[ -z "$2" ]]; then
echo "ERROR: Missing argument for -d/--dependency option"
exit
fi
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
PROFILE_NAME=${DEFAULT_PROFILE}
PROFILE_VERSION=${DEFAULT_VERSION}
# e.g. mercury@mogon1:latest
if [[ "$2" =~ ^(.*)@(.*):(.*)$ ]]; then
if [[ -n "${BASH_REMATCH[1]}" ]]; then
DEPENDENCY="${BASH_REMATCH[1]}"
fi
if [[ -n "${BASH_REMATCH[2]}" ]]; then
PROFILE_NAME="${BASH_REMATCH[2]}"
fi
if [[ -n "${BASH_REMATCH[3]}" ]]; then
PROFILE_VERSION="${BASH_REMATCH[3]}"
fi
# e.g. mercury@mogon1
elif [[ "$2" =~ ^(.*)@(.*)$ ]]; then
if [[ -n "${BASH_REMATCH[1]}" ]]; then
DEPENDENCY="${BASH_REMATCH[1]}"
fi
if [[ -n "${BASH_REMATCH[2]}" ]]; then
PROFILE_NAME="${BASH_REMATCH[2]}"
fi
# e.g. mercury
else
DEPENDENCY="$2"
fi
if [[ ! -n "${DEPENDENCY}" ]]; then
echo "ERROR: Missing dependency name."
exit 1
fi
shift # past argument
shift # past value
;;
-j | --compilecores)
CORES="$2"
shift # past argument
shift # past value
;;
-t | --test)
PERFORM_TEST=true
shift
;;
-l | --list-dependencies)
if [[ -z "$2" ]]; then
list_versions
else
list_profiles "$2"
fi
;;
-h | --help)
help_msg
exit
#shift # past argument
;;
-n | --dry-run)
DRY_RUN=true
shift
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
# deal with positional arguments
if [[ (-z ${1+x}) || (-z ${2+x}) ]]; then
echo "ERROR: Positional arguments missing."
SOURCE_DIR="$(readlink -mn "${1}")"
INSTALL_DIR="$(readlink -mn "${2}")"
# deal with optional arguments
if [[ "${CORES}" == "" ]]; then
CORES=$(grep -c ^processor /proc/cpuinfo)
echo "CORES = ${CORES} (default)"
if [[ ! "${CORES}" -gt "0" ]]; then
echo "ERROR: CORES set to ${CORES} which is invalid.
Input must be numeric and greater than 0."
usage_short
exit
else
echo CORES = "${CORES}"
fi
load_profile "${PROFILE_NAME}" "${PROFILE_VERSION}"
CMAKE=$(find_cmake)
CMAKE="${CMAKE} -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
echo "Sources download path = ${SOURCE_DIR}"
echo "Installation path = ${INSTALL_DIR}"
echo "------------------------------------"
######### From now on exits on any error ########
set -e
export CPATH="${CPATH}:${INSTALL_DIR}/include"
export LIBRARY_PATH="${LIBRARY_PATH}:${INSTALL_DIR}/lib:${INSTALL_DIR}/lib64"
export PKG_CONFIG_PATH="${INSTALL_DIR}/lib/pkgconfig:${PKG_CONFIG_PATH}"
if [[ -n "${DEPENDENCY}" && ! -n "${PROFILE_DEP_NAMES[${DEPENDENCY}]}" ]]; then
echo "Dependency '${DEPENDENCY}' not found in '${PROFILE_NAME}:${PROFILE_VERSION}'"
exit
for dep_name in "${PROFILE_DEP_LIST[@]}"; do
if [[ -n "${DEPENDENCY}" && "${dep_name}" != "${DEPENDENCY}" ]]; then
install_script="${PROFILES_DIR}/${PROFILE_VERSION}/install/${dep_name}.install"
echo -e "\n\n######## Installing: ${dep_name} ###############################\n"
if [[ -f "${install_script}" ]]; then
[[ "$DRY_RUN" == true ]] || source "${install_script}"
echo "WARNING: Install script for '${dep_name}' not found. Skipping."
if [[ "$DRY_RUN" == false ]]; then
pkg_install
[ "${PERFORM_TEST}" ] && pkg_check
fi