-
Notifications
You must be signed in to change notification settings - Fork 2
/
compile_and_install.sh
executable file
·221 lines (189 loc) · 7.87 KB
/
compile_and_install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
193
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
#!/usr/bin/env bash
set -eu
shopt -s nocasematch
# This script will attempt to build and install Ygor Clustering in a distribution-aware way.
#
# The distribution can be explicitly specified or detected automatically; if a specific distribution is specified, the
# package management system will be honoured, if possible.
#
# Existing build artifacts can either be retained, causing a faster partial re-build, or purged, causing a complete,
# clean re-build.
#
# Currently supported distributions: Arch Linux, Debian, and generic (i.e., direct-installation without package manager
# support).
# The temporary location in which to build.
#BUILDROOT="/home/hal/Builds/YgorClustering/"
BUILDROOT="/tmp/ygor_clustering_build"
#BUILDROOT="build"
DISTRIBUTION="auto" # used to tailor the build process for specific distributions/environments.
ALSOINSTALL="yes" # install the built binaries.
CLEANBUILD="no" # purge existing (cached) build artifacts before building.
INSTALLPREFIX="/usr"
INSTALLVIASUDO="yes" # whether to use sudo during installation.
# Argument parsing:
OPTIND=1 # Reset in case getopts has been used previously in the shell.
while getopts "b:d:i:unch" opt; do
case "$opt" in
h)
printf 'This script attempts to build and optionally install Ygor Clustering'
printf ' in a distribution-aware way using the system package manager.\n'
printf "\n"
printf "Usage: \n\t $0 <args> \n"
printf "\n"
printf "Available arguments: \n"
printf "\n"
printf " -h : Display usage information and terminate.\n"
printf "\n"
printf " -b <dir> : The location to use as the build root; build artifacts are cached here.\n"
printf " : Default: '%s'\n" "${BUILDROOT}"
printf "\n"
printf " -i <dir> : The location to use as the installation prefix.\n"
printf " : Default: '%s'\n" "${INSTALLPREFIX}"
printf "\n"
printf " -d <arg> : The distribution/environment to assume for building.\n"
printf " : This option controls how the build is controlled, packaged, and installed.\n"
printf " : Options are 'auto' (i.e., automatic detection), 'debian', 'arch', and 'generic'.\n"
printf " : Default: '%s'\n" "${DISTRIBUTION}"
printf "\n"
printf " -u : Attempt unprivileged installation (i.e., without using sudo).\n"
printf " : Default: sudo will be used: '%s'\n" "${INSTALLVIASUDO}"
printf "\n"
printf " -n : No-install; build, but do not install.\n"
printf " : Default: binaries will be installed: '%s'\n" "${ALSOINSTALL}"
printf "\n"
printf " -c : Clean-build; purge any existing build artifacts before building.\n"
printf " : Default: '%s'\n" "${CLEANBUILD}"
printf "\n"
exit 0
;;
b) BUILDROOT=$(realpath "$OPTARG")
printf 'Proceeding with user-specified build root "%s".\n' "${BUILDROOT}"
;;
d) DISTRIBUTION="$OPTARG"
printf 'Proceeding with user-specified distribution "%s".\n' "${DISTRIBUTION}"
;;
i) INSTALLPREFIX="$OPTARG"
printf 'Proceeding with user-specified installation prefix directory "%s".\n' "${INSTALLPREFIX}"
;;
u) INSTALLVIASUDO="no"
printf 'Disabling use of sudo.\n' "${INSTALLVIASUDO}"
;;
n) ALSOINSTALL="no"
printf 'Disabling installation; building only.\n'
;;
c) CLEANBUILD="yes"
printf 'Purging cached build artifacts for clean build.\n'
;;
esac
done
#shift $((OPTIND-1))
#[ "$1" = "--" ] && shift
#echo "Leftover arguments: $@"
if [ -z "${BUILDROOT}" ] ; then
# Proceeding with an empty build root can be dangerous, so refuse to do so.
printf 'Empty build root directory. Refusing to continue.\n' 1>&2
exit 1
elif [ "$(readlink -f "${BUILDROOT}")" == "/" ] ; then
# Proceeding with build root at '/' will destroy the filesystem if the 'clean' option is used.
printf 'Build root resolves to "/". Refusing to continue.\n' 1>&2
exit 1
fi
# Determine which distribution/environment to assume.
if [[ "${DISTRIBUTION}" =~ .*auto.* ]] &&
[ -e /etc/os-release ] ; then
DISTRIBUTION=$( bash -c '. /etc/os-release && printf "${NAME}"' )
fi
# Move to the repository root.
REPOROOT=$(git rev-parse --show-toplevel || true)
if [ ! -d "${REPOROOT}" ] ; then
# Fall-back on the source position of this script.
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}" )" )"
if [ ! -d "${SCRIPT_DIR}" ] ; then
printf "Cannot access repository root or root directory containing this script. Cannot continue.\n" 1>&2
exit 1
fi
REPOROOT="${SCRIPT_DIR}"
fi
cd "${REPOROOT}"
# Determine how we will escalate privileges.
SUDO="sudo"
if [[ $EUID -eq 0 ]] ; then
SUDO="" # no privileges needed.
fi
if [ "${INSTALLVIASUDO}" != "yes" ] ; then
SUDO=""
fi
#################
# Copy the repository to the build location to eliminate possibility of destroying the repo.
mkdir -p "${BUILDROOT}"
if [ -d "${BUILDROOT}"/.git ] ; then
printf 'Build root directory "%s" contains a .git subdirectory. Refusing to overwrite it.\n' 1>&2
exit 1
fi
if [[ "${CLEANBUILD}" =~ ^y.* ]] ; then
$SUDO find "${BUILDROOT}/" -type f -exec chmod 644 '{}' \+
$SUDO find "${BUILDROOT}/" -type d -exec chmod 755 '{}' \+
$SUDO find "${BUILDROOT}/" -exec chown "$( id -n -u ):$( id -n -g )" '{}' \+
rsync -rpt --delete --no-links --exclude="${BUILDROOT}" --cvs-exclude ./ "${BUILDROOT}/"
else
rsync -rpt --no-links --exclude="${BUILDROOT}" --cvs-exclude ./ "${BUILDROOT}/"
fi
cd "${BUILDROOT}"
# Perform the build (+ optional install) for each distribution type.
if [[ "${DISTRIBUTION}" =~ .*debian.* ]] ; then
printf 'Compiling for Debian...\n'
mkdir -p build
cd build
if [ -f CMakeCache.txt ] ; then
touch CMakeCache.txt # To bump CMake-defined compilation time.
else
cmake \
-DCMAKE_INSTALL_PREFIX="${INSTALLPREFIX}" \
-DCMAKE_BUILD_TYPE=Release \
../
fi
JOBS=$(nproc)
JOBS=$(( JOBS < 8 ? JOBS : 8 )) # Limit to reduce memory use.
make -j "$JOBS" VERBOSE=1
make package
if [[ "${ALSOINSTALL}" =~ ^y.* ]] ; then
$SUDO apt-get --yes install -f ./*deb
fi
elif [[ "${DISTRIBUTION}" =~ .*arch.* ]] ; then
printf 'Compiling for Arch Linux...\n'
# Arch's makepkg is picky, disallowing being run as root, but also requiring the non-root user to be a sudoer. What
# a pain ... especially for chroots and controlled environments. So either create a user and dance around using
# root/sudo, or rely on the current user to have sudo priveleges.
if [[ $EUID -eq 0 ]] ; then
useradd -M --shell /bin/bash dummy_build_user || true
chown -R dummy_build_user .
runuser dummy_build_user -c "INSTALL_PREFIX='$INSTALLPREFIX' makepkg --syncdeps --needed --noconfirm"
if [[ "${ALSOINSTALL}" =~ ^y.* ]] ; then
pacman --noconfirm -U $( ls -t ./*pkg.tar* | head -n 1 )
fi
userdel dummy_build_user
else
INSTALL_PREFIX="$INSTALLPREFIX" makepkg --syncdeps --needed --noconfirm
if [[ "${ALSOINSTALL}" =~ ^y.* ]] ; then
INSTALL_PREFIX="$INSTALLPREFIX" makepkg --syncdeps --needed --noconfirm --install
fi
fi
else # Generic build and install.
printf 'Compiling for generic Linux distribution...\n'
mkdir -p build
cd build
cmake \
-DCMAKE_INSTALL_PREFIX="${INSTALLPREFIX}" \
-DCMAKE_BUILD_TYPE=Release \
../
JOBS=$(nproc)
JOBS=$(( $JOBS < 8 ? $JOBS : 8 )) # Limit to reduce memory use.
make -j "$JOBS" VERBOSE=1
if [[ "${ALSOINSTALL}" =~ ^y.* ]] ; then
printf 'Warning! Bypassing system package management and installing directly!\n'
$SUDO make install
fi
fi
compile_ret_val=$?
printf 'Done.\n'
exit $compile_ret_val