Install script: fall back to su without sudo, add --build-only
Change-Id: Ibfbaef4ee01a35a0bd8f430d423746f25939b10c
diff --git a/scripts/install.sh b/scripts/install.sh
index bb076ea..33a2a22 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -19,6 +19,9 @@
# distribution
# --skip-deps do not install the packages of the distribution
# --skip-tests do not run ctest
+# --build-only build everything but install nothing: no packages of
+# the distribution, no root needed, the binaries stay
+# in the build directory
# --static-binary build dereko2vec as a completely static binary
# (needs static compression libraries, which Debian
# and Ubuntu ship and Fedora, Rocky and RHEL do not)
@@ -34,6 +37,7 @@
STATIC_BINARY=0
SKIP_DEPS=0
SKIP_TESTS=0
+BUILD_ONLY=0
JOBS=
usage() {
@@ -50,12 +54,18 @@
--rocksdb-version) ROCKSDB_VERSION=$2; shift 2 ;;
--skip-deps) SKIP_DEPS=1; shift ;;
--skip-tests) SKIP_TESTS=1; shift ;;
+ --build-only) BUILD_ONLY=1; shift ;;
-j) JOBS=$2; shift 2 ;;
-h|--help) usage 0 ;;
*) echo "Unknown option: $1" >&2; usage 1 ;;
esac
done
+# Nothing is installed, so nothing of the distribution is needed either
+if [ $BUILD_ONLY = 1 ]; then
+ SKIP_DEPS=1
+fi
+
if [ -z "$JOBS" ]; then
JOBS=$(getconf _NPROCESSORS_ONLN 2> /dev/null || sysctl -n hw.ncpu)
fi
@@ -63,13 +73,28 @@
step() { printf '\n=== %s ===\n' "$*"; }
-# sudo only where the target is not writable
-if [ -w "$PREFIX" ] || { [ ! -e "$PREFIX" ] && [ -w "$(dirname "$PREFIX")" ]; }; then
- SUDO=
-else
- SUDO=sudo
+# Root is needed only where the target is not writable
+NEED_ROOT=
+if ! [ -w "$PREFIX" ] && ! { [ ! -e "$PREFIX" ] && [ -w "$(dirname "$PREFIX")" ]; }; then
+ NEED_ROOT=1
fi
+# Runs a command as root. Prefer sudo, fall back to su, which prompts for the
+# root password - a server may well have only that.
+root() {
+ if [ -z "$NEED_ROOT" ] || [ "$(id -u)" = 0 ]; then
+ "$@"
+ elif command -v sudo > /dev/null; then
+ sudo "$@" || su -c "$*"
+ elif command -v su > /dev/null; then
+ su -c "$*"
+ else
+ echo "Installing to $PREFIX needs root, but there is neither sudo nor su." >&2
+ echo "Use --prefix with a directory you can write to." >&2
+ return 1
+ fi
+}
+
# The rocksdb and the compression libraries of homebrew are below
# /opt/homebrew on Apple Silicon, which is not searched by default
BREW_PREFIX=
@@ -81,14 +106,14 @@
if [ $SKIP_DEPS = 0 ]; then
step "Installing the packages of the distribution"
if command -v dnf > /dev/null; then
- $SUDO dnf install -y cmake gcc-c++ git make pkgconf-pkg-config \
+ root dnf install -y cmake gcc-c++ git make pkgconf-pkg-config \
snappy-devel zlib-devel bzip2-devel lz4-devel libzstd-devel
# Rocky Linux and RHEL have no rocksdb-devel everywhere, that is what
# step 2 is for
- $SUDO dnf install -y rocksdb-devel || true
+ root dnf install -y rocksdb-devel || true
elif command -v apt-get > /dev/null; then
- $SUDO apt-get update
- $SUDO apt-get install -y cmake g++ git make pkg-config \
+ root apt-get update
+ root apt-get install -y cmake g++ git make pkg-config \
librocksdb-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
elif command -v brew > /dev/null; then
brew install cmake rocksdb snappy zlib bzip2 lz4 zstd
@@ -141,10 +166,10 @@
# Programs that link the shared rocksdb of the prefix have to find it. Only a
# system-wide install can register the directory; for one below $HOME the
# programs carry the rpath of the libraries they were linked against.
-if [ $ROCKSDB_SHARED_BUILT = 1 ] && [ "$(uname)" = Linux ] && [ -n "$SUDO" ]; then
+if [ $BUILD_ONLY = 0 ] && [ $ROCKSDB_SHARED_BUILT = 1 ] && [ "$(uname)" = Linux ] && [ -n "$NEED_ROOT" ]; then
RDB_LIBDIR=$(dirname "$(find "$ROCKSDB_PREFIX_USED" -name 'librocksdb.so' | head -1)")
- echo "$RDB_LIBDIR" | $SUDO tee /etc/ld.so.conf.d/rocksdb-prefix.conf > /dev/null
- $SUDO ldconfig
+ echo "$RDB_LIBDIR" | root tee /etc/ld.so.conf.d/rocksdb-prefix.conf > /dev/null
+ root ldconfig
fi
# --- 3. collocatordb ---------------------------------------------------------
@@ -160,9 +185,17 @@
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
${CDB_PREFIXES:+-DCMAKE_PREFIX_PATH=$CDB_PREFIXES}
cmake --build "$WORK/collocatordb/build" -j "$JOBS"
-$SUDO cmake --install "$WORK/collocatordb/build"
-if [ "$(uname)" = Linux ] && [ -n "$SUDO" ]; then
- $SUDO ldconfig
+CDB_STAGE=
+if [ $BUILD_ONLY = 1 ]; then
+ # install into a staging prefix only, where the dereko2vec build below
+ # finds the static library and the header
+ CDB_STAGE=$WORK/stage
+ cmake --install "$WORK/collocatordb/build" --prefix "$CDB_STAGE"
+else
+ root cmake --install "$WORK/collocatordb/build"
+ if [ "$(uname)" = Linux ] && [ -n "$NEED_ROOT" ]; then
+ root ldconfig
+ fi
fi
if [ $SKIP_TESTS = 0 ]; then
ctest --test-dir "$WORK/collocatordb/build" --output-on-failure
@@ -175,6 +208,9 @@
# later install without sudo. Start over, the build takes a minute.
rm -rf "$DEREKO2VEC_SRC/build"
CMAKE_PREFIXES=$PREFIX
+if [ -n "$CDB_STAGE" ]; then
+ CMAKE_PREFIXES="$CDB_STAGE;$CMAKE_PREFIXES"
+fi
if [ -n "$ROCKSDB_PREFIX_USED" ]; then
CMAKE_PREFIXES="$CMAKE_PREFIXES;$ROCKSDB_PREFIX_USED"
fi
@@ -195,7 +231,20 @@
if [ $SKIP_TESTS = 0 ]; then
ctest --test-dir "$DEREKO2VEC_SRC/build" --output-on-failure
fi
-$SUDO cmake --install "$DEREKO2VEC_SRC/build"
+if [ $BUILD_ONLY = 0 ]; then
+ root cmake --install "$DEREKO2VEC_SRC/build"
+fi
step "Done"
-echo "dereko2vec and vecs2mmap are in $PREFIX/bin"
+if [ $BUILD_ONLY = 1 ]; then
+ echo "dereko2vec and vecs2mmap are in $DEREKO2VEC_SRC/build"
+ echo "Nothing was installed. Install them with:"
+ echo " sudo cmake --install \"$DEREKO2VEC_SRC/build\""
+ if [ $STATIC = 0 ] && [ $ROCKSDB_SHARED_BUILT = 1 ]; then
+ RDB_LIBDIR=$(dirname "$(find "$ROCKSDB_PREFIX_USED" -name 'librocksdb.so' | head -1)")
+ echo "With --shared the programs need the rocksdb library at runtime, e.g."
+ echo " LD_LIBRARY_PATH=$RDB_LIBDIR $DEREKO2VEC_SRC/build/dereko2vec"
+ fi
+else
+ echo "dereko2vec and vecs2mmap are in $PREFIX/bin"
+fi