| Marc Kupietz | 11df785 | 2026-08-09 14:59:09 +0200 | [diff] [blame^] | 1 | #!/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 | # |
| 27 | set -euo pipefail |
| 28 | |
| 29 | DEREKO2VEC_SRC=$(cd "$(dirname "$0")/.." && pwd) |
| 30 | PREFIX=/usr/local |
| 31 | ROCKSDB_PREFIX=$HOME/rocksdb |
| 32 | ROCKSDB_VERSION= |
| 33 | STATIC=1 |
| 34 | STATIC_BINARY=0 |
| 35 | SKIP_DEPS=0 |
| 36 | SKIP_TESTS=0 |
| 37 | JOBS= |
| 38 | |
| 39 | usage() { |
| 40 | sed -n '2,26p' "$0" |
| 41 | exit "${1:-0}" |
| 42 | } |
| 43 | |
| 44 | while [ $# -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 |
| 57 | done |
| 58 | |
| 59 | if [ -z "$JOBS" ]; then |
| 60 | JOBS=$(getconf _NPROCESSORS_ONLN 2> /dev/null || sysctl -n hw.ncpu) |
| 61 | fi |
| 62 | export CMAKE_BUILD_PARALLEL_LEVEL=$JOBS |
| 63 | |
| 64 | step() { printf '\n=== %s ===\n' "$*"; } |
| 65 | |
| 66 | # sudo only where the target is not writable |
| 67 | if [ -w "$PREFIX" ] || { [ ! -e "$PREFIX" ] && [ -w "$(dirname "$PREFIX")" ]; }; then |
| 68 | SUDO= |
| 69 | else |
| 70 | SUDO=sudo |
| 71 | fi |
| 72 | |
| 73 | # The rocksdb and the compression libraries of homebrew are below |
| 74 | # /opt/homebrew on Apple Silicon, which is not searched by default |
| 75 | BREW_PREFIX= |
| 76 | if command -v brew > /dev/null; then |
| 77 | BREW_PREFIX=$(brew --prefix) |
| 78 | fi |
| 79 | |
| 80 | # --- 1. the packages of the distribution ------------------------------------- |
| 81 | if [ $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 |
| 99 | fi |
| 100 | |
| 101 | # --- 2. rocksdb -------------------------------------------------------------- |
| 102 | static_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 | |
| 113 | DISTRO_ROCKSDB= |
| 114 | if { 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 |
| 118 | fi |
| 119 | |
| 120 | ROCKSDB_PREFIX_USED= |
| 121 | ROCKSDB_SHARED_BUILT=0 |
| 122 | if [ -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 |
| 130 | else |
| 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 |
| 139 | fi |
| 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. |
| 144 | if [ $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 |
| 148 | fi |
| 149 | |
| 150 | # --- 3. collocatordb --------------------------------------------------------- |
| 151 | step "collocatordb" |
| 152 | WORK=$(mktemp -d) |
| 153 | trap 'rc=$?; if [ $rc = 0 ]; then rm -rf "$WORK"; else echo "Keeping $WORK for a look at what went wrong" >&2; fi' EXIT |
| 154 | git clone "https://korap.ids-mannheim.de/gerrit/ids-kl/collocatordb" "$WORK/collocatordb" |
| 155 | CDB_PREFIXES=$ROCKSDB_PREFIX_USED |
| 156 | if [ -n "$BREW_PREFIX" ]; then |
| 157 | CDB_PREFIXES=${CDB_PREFIXES:+$CDB_PREFIXES;}$BREW_PREFIX |
| 158 | fi |
| 159 | cmake -S "$WORK/collocatordb" -B "$WORK/collocatordb/build" \ |
| 160 | -DCMAKE_INSTALL_PREFIX="$PREFIX" \ |
| 161 | ${CDB_PREFIXES:+-DCMAKE_PREFIX_PATH=$CDB_PREFIXES} |
| 162 | cmake --build "$WORK/collocatordb/build" -j "$JOBS" |
| 163 | $SUDO cmake --install "$WORK/collocatordb/build" |
| 164 | if [ "$(uname)" = Linux ] && [ -n "$SUDO" ]; then |
| 165 | $SUDO ldconfig |
| 166 | fi |
| 167 | if [ $SKIP_TESTS = 0 ]; then |
| 168 | ctest --test-dir "$WORK/collocatordb/build" --output-on-failure |
| 169 | fi |
| 170 | |
| 171 | # --- 4. dereko2vec ----------------------------------------------------------- |
| 172 | step "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. |
| 176 | rm -rf "$DEREKO2VEC_SRC/build" |
| 177 | CMAKE_PREFIXES=$PREFIX |
| 178 | if [ -n "$ROCKSDB_PREFIX_USED" ]; then |
| 179 | CMAKE_PREFIXES="$CMAKE_PREFIXES;$ROCKSDB_PREFIX_USED" |
| 180 | fi |
| 181 | if [ -n "$BREW_PREFIX" ]; then |
| 182 | CMAKE_PREFIXES="$CMAKE_PREFIXES;$BREW_PREFIX" |
| 183 | fi |
| 184 | STATIC_FLAG= |
| 185 | if [ $STATIC_BINARY = 1 ]; then |
| 186 | STATIC_FLAG=-DSTATIC_DEREKO2VEC=ON |
| 187 | elif [ $STATIC = 1 ]; then |
| 188 | STATIC_FLAG=-DSTATIC_ROCKSDB=ON |
| 189 | fi |
| 190 | cmake -S "$DEREKO2VEC_SRC" -B "$DEREKO2VEC_SRC/build" \ |
| 191 | -DCMAKE_INSTALL_PREFIX="$PREFIX" \ |
| 192 | -DCMAKE_PREFIX_PATH="$CMAKE_PREFIXES" \ |
| 193 | $STATIC_FLAG |
| 194 | cmake --build "$DEREKO2VEC_SRC/build" -j "$JOBS" |
| 195 | if [ $SKIP_TESTS = 0 ]; then |
| 196 | ctest --test-dir "$DEREKO2VEC_SRC/build" --output-on-failure |
| 197 | fi |
| 198 | $SUDO cmake --install "$DEREKO2VEC_SRC/build" |
| 199 | |
| 200 | step "Done" |
| 201 | echo "dereko2vec and vecs2mmap are in $PREFIX/bin" |