blob: bb076ea4610574da89eb06b180b96a8f23d2dcef [file] [log] [blame]
Marc Kupietz11df7852026-08-09 14:59:09 +02001#!/usr/bin/env bash
2#
3# Installs dereko2vec and everything it needs, in one go:
4#
5# 1. the packages of the distribution (dnf, apt-get or brew)
6# 2. rocksdb, but only where the distribution has none or none with the
7# static library (scripts/build-rocksdb.sh)
8# 3. collocatordb
9# 4. dereko2vec, with the fast static link of rocksdb and collocatordb
10#
11# Works on Fedora, Rocky Linux, RHEL, Debian, Ubuntu and MacOS.
12#
13# Options:
14# --shared link rocksdb and collocatordb shared (default:
15# static, which is about 22% faster when indexing)
16# --prefix DIR install there instead of /usr/local
17# --rocksdb-prefix DIR build rocksdb into DIR instead of $HOME/rocksdb
18# --rocksdb-version V build rocksdb version V instead of the one of the
19# distribution
20# --skip-deps do not install the packages of the distribution
21# --skip-tests do not run ctest
22# --static-binary build dereko2vec as a completely static binary
23# (needs static compression libraries, which Debian
24# and Ubuntu ship and Fedora, Rocky and RHEL do not)
25# -j N build with N jobs (default: all cores)
26#
27set -euo pipefail
28
29DEREKO2VEC_SRC=$(cd "$(dirname "$0")/.." && pwd)
30PREFIX=/usr/local
31ROCKSDB_PREFIX=$HOME/rocksdb
32ROCKSDB_VERSION=
33STATIC=1
34STATIC_BINARY=0
35SKIP_DEPS=0
36SKIP_TESTS=0
37JOBS=
38
39usage() {
40 sed -n '2,26p' "$0"
41 exit "${1:-0}"
42}
43
44while [ $# -gt 0 ]; do
45 case $1 in
46 --shared) STATIC=0; shift ;;
47 --static-binary) STATIC_BINARY=1; shift ;;
48 --prefix) PREFIX=$2; shift 2 ;;
49 --rocksdb-prefix) ROCKSDB_PREFIX=$2; shift 2 ;;
50 --rocksdb-version) ROCKSDB_VERSION=$2; shift 2 ;;
51 --skip-deps) SKIP_DEPS=1; shift ;;
52 --skip-tests) SKIP_TESTS=1; shift ;;
53 -j) JOBS=$2; shift 2 ;;
54 -h|--help) usage 0 ;;
55 *) echo "Unknown option: $1" >&2; usage 1 ;;
56 esac
57done
58
59if [ -z "$JOBS" ]; then
60 JOBS=$(getconf _NPROCESSORS_ONLN 2> /dev/null || sysctl -n hw.ncpu)
61fi
62export CMAKE_BUILD_PARALLEL_LEVEL=$JOBS
63
64step() { printf '\n=== %s ===\n' "$*"; }
65
66# sudo only where the target is not writable
67if [ -w "$PREFIX" ] || { [ ! -e "$PREFIX" ] && [ -w "$(dirname "$PREFIX")" ]; }; then
68 SUDO=
69else
70 SUDO=sudo
71fi
72
73# The rocksdb and the compression libraries of homebrew are below
74# /opt/homebrew on Apple Silicon, which is not searched by default
75BREW_PREFIX=
76if command -v brew > /dev/null; then
77 BREW_PREFIX=$(brew --prefix)
78fi
79
80# --- 1. the packages of the distribution -------------------------------------
81if [ $SKIP_DEPS = 0 ]; then
82 step "Installing the packages of the distribution"
83 if command -v dnf > /dev/null; then
84 $SUDO dnf install -y cmake gcc-c++ git make pkgconf-pkg-config \
85 snappy-devel zlib-devel bzip2-devel lz4-devel libzstd-devel
86 # Rocky Linux and RHEL have no rocksdb-devel everywhere, that is what
87 # step 2 is for
88 $SUDO dnf install -y rocksdb-devel || true
89 elif command -v apt-get > /dev/null; then
90 $SUDO apt-get update
91 $SUDO apt-get install -y cmake g++ git make pkg-config \
92 librocksdb-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
93 elif command -v brew > /dev/null; then
94 brew install cmake rocksdb snappy zlib bzip2 lz4 zstd
95 else
96 echo "No dnf, apt-get or brew - install cmake, a C++ compiler, git, rocksdb" >&2
97 echo "and the devel packages of snappy, zlib, bzip2, lz4 and zstd by hand." >&2
98 fi
99fi
100
101# --- 2. rocksdb --------------------------------------------------------------
102static_rocksdb_of_the_distribution() {
103 local f
104 for f in /usr/lib64/librocksdb.a /usr/lib/librocksdb.a /usr/lib/*/librocksdb.a; do
105 [ -e "$f" ] && return 0
106 done
107 if command -v brew > /dev/null && brew list --versions rocksdb > /dev/null 2>&1; then
108 [ -e "$(brew --prefix rocksdb)/lib/librocksdb.a" ] && return 0
109 fi
110 return 1
111}
112
113DISTRO_ROCKSDB=
114if { command -v rpm > /dev/null && rpm -q rocksdb > /dev/null 2>&1; } ||
115 { command -v dpkg-query > /dev/null && dpkg-query -W librocksdb-dev > /dev/null 2>&1; } ||
116 { command -v brew > /dev/null && brew list --versions rocksdb > /dev/null 2>&1; }; then
117 DISTRO_ROCKSDB=1
118fi
119
120ROCKSDB_PREFIX_USED=
121ROCKSDB_SHARED_BUILT=0
122if [ -n "$DISTRO_ROCKSDB" ] && [ -z "$ROCKSDB_VERSION" ]; then
123 if [ $STATIC = 1 ] && ! static_rocksdb_of_the_distribution; then
124 step "rocksdb: building the static library, same version as the distribution"
125 "$DEREKO2VEC_SRC/scripts/build-rocksdb.sh" --static-only -p "$ROCKSDB_PREFIX"
126 ROCKSDB_PREFIX_USED=$ROCKSDB_PREFIX
127 else
128 step "rocksdb: the one of the distribution is used"
129 fi
130else
131 if [ -z "$DISTRO_ROCKSDB" ]; then
132 step "rocksdb: no rocksdb package - building the shared and the static library"
133 else
134 step "rocksdb: building version $ROCKSDB_VERSION as asked"
135 fi
136 "$DEREKO2VEC_SRC/scripts/build-rocksdb.sh" -p "$ROCKSDB_PREFIX" ${ROCKSDB_VERSION:+-v "$ROCKSDB_VERSION"}
137 ROCKSDB_PREFIX_USED=$ROCKSDB_PREFIX
138 ROCKSDB_SHARED_BUILT=1
139fi
140
141# Programs that link the shared rocksdb of the prefix have to find it. Only a
142# system-wide install can register the directory; for one below $HOME the
143# programs carry the rpath of the libraries they were linked against.
144if [ $ROCKSDB_SHARED_BUILT = 1 ] && [ "$(uname)" = Linux ] && [ -n "$SUDO" ]; then
145 RDB_LIBDIR=$(dirname "$(find "$ROCKSDB_PREFIX_USED" -name 'librocksdb.so' | head -1)")
146 echo "$RDB_LIBDIR" | $SUDO tee /etc/ld.so.conf.d/rocksdb-prefix.conf > /dev/null
147 $SUDO ldconfig
148fi
149
150# --- 3. collocatordb ---------------------------------------------------------
151step "collocatordb"
152WORK=$(mktemp -d)
153trap 'rc=$?; if [ $rc = 0 ]; then rm -rf "$WORK"; else echo "Keeping $WORK for a look at what went wrong" >&2; fi' EXIT
154git clone "https://korap.ids-mannheim.de/gerrit/ids-kl/collocatordb" "$WORK/collocatordb"
155CDB_PREFIXES=$ROCKSDB_PREFIX_USED
156if [ -n "$BREW_PREFIX" ]; then
157 CDB_PREFIXES=${CDB_PREFIXES:+$CDB_PREFIXES;}$BREW_PREFIX
158fi
159cmake -S "$WORK/collocatordb" -B "$WORK/collocatordb/build" \
160 -DCMAKE_INSTALL_PREFIX="$PREFIX" \
161 ${CDB_PREFIXES:+-DCMAKE_PREFIX_PATH=$CDB_PREFIXES}
162cmake --build "$WORK/collocatordb/build" -j "$JOBS"
163$SUDO cmake --install "$WORK/collocatordb/build"
164if [ "$(uname)" = Linux ] && [ -n "$SUDO" ]; then
165 $SUDO ldconfig
166fi
167if [ $SKIP_TESTS = 0 ]; then
168 ctest --test-dir "$WORK/collocatordb/build" --output-on-failure
169fi
170
171# --- 4. dereko2vec -----------------------------------------------------------
172step "dereko2vec"
173# A stale build directory would silently keep the collocatordb and rocksdb it
174# was once configured with, and an install manifest of a root install breaks a
175# later install without sudo. Start over, the build takes a minute.
176rm -rf "$DEREKO2VEC_SRC/build"
177CMAKE_PREFIXES=$PREFIX
178if [ -n "$ROCKSDB_PREFIX_USED" ]; then
179 CMAKE_PREFIXES="$CMAKE_PREFIXES;$ROCKSDB_PREFIX_USED"
180fi
181if [ -n "$BREW_PREFIX" ]; then
182 CMAKE_PREFIXES="$CMAKE_PREFIXES;$BREW_PREFIX"
183fi
184STATIC_FLAG=
185if [ $STATIC_BINARY = 1 ]; then
186 STATIC_FLAG=-DSTATIC_DEREKO2VEC=ON
187elif [ $STATIC = 1 ]; then
188 STATIC_FLAG=-DSTATIC_ROCKSDB=ON
189fi
190cmake -S "$DEREKO2VEC_SRC" -B "$DEREKO2VEC_SRC/build" \
191 -DCMAKE_INSTALL_PREFIX="$PREFIX" \
192 -DCMAKE_PREFIX_PATH="$CMAKE_PREFIXES" \
193 $STATIC_FLAG
194cmake --build "$DEREKO2VEC_SRC/build" -j "$JOBS"
195if [ $SKIP_TESTS = 0 ]; then
196 ctest --test-dir "$DEREKO2VEC_SRC/build" --output-on-failure
197fi
198$SUDO cmake --install "$DEREKO2VEC_SRC/build"
199
200step "Done"
201echo "dereko2vec and vecs2mmap are in $PREFIX/bin"