|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Generate BUILD_INFO metadata file capturing the build environment. |
| 3 | +# Usage: ci/generate-build-info.sh <output-path> |
| 4 | +# |
| 5 | +# The script degrades gracefully: fields that cannot be determined are |
| 6 | +# printed as "unknown". If bash is not available, CMake will skip this |
| 7 | +# step without failing the build (see CMakeLists.txt). |
| 8 | + |
| 9 | +set -euo pipefail |
| 10 | + |
| 11 | +OUTPUT="${1:?Usage: $0 <output-path>}" |
| 12 | +BUILD_DIR="$(cd "$(dirname "$OUTPUT")" && pwd)" |
| 13 | +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" |
| 14 | +SOURCE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" |
| 15 | + |
| 16 | +# --- Helpers --- |
| 17 | + |
| 18 | +cmake_cache_get() { |
| 19 | + local key="$1" |
| 20 | + local cache="$BUILD_DIR/CMakeCache.txt" |
| 21 | + if [ -f "$cache" ]; then |
| 22 | + grep "^${key}:" "$cache" 2>/dev/null | cut -d= -f2- || echo "unknown" |
| 23 | + else |
| 24 | + echo "unknown" |
| 25 | + fi |
| 26 | +} |
| 27 | + |
| 28 | +# --- Driver version --- |
| 29 | + |
| 30 | +VERSION=$(cd "$SOURCE_DIR" && git describe --tags --always 2>/dev/null || echo "unknown") |
| 31 | + |
| 32 | +# --- Platform --- |
| 33 | + |
| 34 | +ARCH=$(uname -m 2>/dev/null || echo "unknown") |
| 35 | +KERNEL=$(uname -r 2>/dev/null || echo "unknown") |
| 36 | + |
| 37 | +case "${OSTYPE:-}" in |
| 38 | + linux-gnu*|linux*) |
| 39 | + if [ -f /etc/os-release ]; then |
| 40 | + OS=$(. /etc/os-release && echo "${PRETTY_NAME:-unknown}") |
| 41 | + else |
| 42 | + OS="Linux (unknown distro)" |
| 43 | + fi |
| 44 | + GLIBC=$(ldd --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+$' || echo "unknown") |
| 45 | + ;; |
| 46 | + darwin*) |
| 47 | + OS="macOS $(sw_vers -productVersion 2>/dev/null || echo unknown)" |
| 48 | + GLIBC="N/A" |
| 49 | + ;; |
| 50 | + msys*|cygwin*|mingw*) |
| 51 | + OS="Windows" |
| 52 | + GLIBC="N/A" |
| 53 | + ;; |
| 54 | + *) |
| 55 | + OS="unknown (${OSTYPE:-not set})" |
| 56 | + GLIBC="unknown" |
| 57 | + ;; |
| 58 | +esac |
| 59 | + |
| 60 | +# --- Toolchain --- |
| 61 | + |
| 62 | +RUST_VERSION=$(rustc --version 2>/dev/null || echo "unknown") |
| 63 | +CARGO_VERSION=$(cargo --version 2>/dev/null || echo "unknown") |
| 64 | +CMAKE_VERSION_STR=$(cmake --version 2>/dev/null | head -1 || echo "unknown") |
| 65 | +CC_VERSION=$(${CC:-cc} --version 2>/dev/null | head -1 || echo "unknown") |
| 66 | + |
| 67 | +# --- OpenSSL (from openssl-sys build script output) --- |
| 68 | + |
| 69 | +# Search for the openssl-sys build script output. When built via CMake, |
| 70 | +# CARGO_TARGET_DIR is set to the build subdirectory (e.g. build/scylla-rust-wrapper/). |
| 71 | +# When built standalone with cargo, it's under scylla-rust-wrapper/target/. |
| 72 | +# Search both locations. |
| 73 | +OPENSSL_SYS_OUTPUT=$(find "$BUILD_DIR" "$SOURCE_DIR/scylla-rust-wrapper/target" \ |
| 74 | + -path "*/openssl-sys-*/output" -type f 2>/dev/null | head -1) |
| 75 | + |
| 76 | +if [ -n "$OPENSSL_SYS_OUTPUT" ] && [ -f "$OPENSSL_SYS_OUTPUT" ]; then |
| 77 | + OPENSSL_VERSION_HEX=$(grep "^cargo:version_number=" "$OPENSSL_SYS_OUTPUT" | cut -d= -f2 || echo "") |
| 78 | + OPENSSL_INCLUDE=$(grep "^cargo:include=" "$OPENSSL_SYS_OUTPUT" | cut -d= -f2 || echo "unknown") |
| 79 | + OSSLCONF_FLAGS=$(grep "^cargo:rustc-cfg=osslconf=" "$OPENSSL_SYS_OUTPUT" | sed 's/cargo:rustc-cfg=osslconf="\(.*\)"/\1/' | paste -sd ' ' || echo "none") |
| 80 | + |
| 81 | + # Quoting from openssl docs: |
| 82 | + # > A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys` |
| 83 | + # > crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` |
| 84 | + # > environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version: |
| 85 | + # > `0xMNNFFPPS`. For example, version 1.0.2g’s encoding is `0x1_00_02_07_0`. |
| 86 | + # |
| 87 | + # However, OpenSSL 3.x changed the displaying, while encoding is still the same. |
| 88 | + # - In version 1.2.3.c, 3 was Fix and c was Patch. |
| 89 | + # - In version 3.2.1, 3 is Patch and Fix is not present (0). |
| 90 | + # We're only interested in OpenSSL 3+, so we can assume the version is in the Major.Minor.Patch format. |
| 91 | + if [ -n "$OPENSSL_VERSION_HEX" ]; then |
| 92 | + dec=$((16#$OPENSSL_VERSION_HEX)) |
| 93 | + major=$(( (dec >> 28) & 0xF )) |
| 94 | + minor=$(( (dec >> 20) & 0xFF )) |
| 95 | + patch=$(( (dec >> 4) & 0xFF )) |
| 96 | + OPENSSL_VERSION="${major}.${minor}.${patch}" |
| 97 | + else |
| 98 | + OPENSSL_VERSION="unknown" |
| 99 | + fi |
| 100 | +else |
| 101 | + OPENSSL_VERSION=$(pkg-config --modversion openssl 2>/dev/null || echo "unknown") |
| 102 | + OPENSSL_INCLUDE=$(pkg-config --variable=includedir openssl 2>/dev/null || echo "unknown") |
| 103 | + OSSLCONF_FLAGS="unknown (openssl-sys build output not found)" |
| 104 | +fi |
| 105 | + |
| 106 | +# --- Build configuration (from Cargo.toml) --- |
| 107 | + |
| 108 | +CARGO_TOML="$SOURCE_DIR/scylla-rust-wrapper/Cargo.toml" |
| 109 | +if [ -f "$CARGO_TOML" ]; then |
| 110 | + LTO=$(grep "^lto" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown") |
| 111 | + PANIC=$(grep "^panic" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown") |
| 112 | +else |
| 113 | + LTO="unknown" |
| 114 | + PANIC="unknown" |
| 115 | +fi |
| 116 | + |
| 117 | +# --- CMake options --- |
| 118 | + |
| 119 | +CMAKE_BUILD_TYPE=$(cmake_cache_get "CMAKE_BUILD_TYPE") |
| 120 | +CMAKE_INSTALL_PREFIX=$(cmake_cache_get "CMAKE_INSTALL_PREFIX") |
| 121 | +CASS_BUILD_SHARED=$(cmake_cache_get "CASS_BUILD_SHARED") |
| 122 | +CASS_BUILD_STATIC=$(cmake_cache_get "CASS_BUILD_STATIC") |
| 123 | + |
| 124 | +# --- Write output --- |
| 125 | + |
| 126 | +cat > "$OUTPUT" <<EOF |
| 127 | +Build Information for scylla-cpp-driver $VERSION |
| 128 | +
|
| 129 | +Platform |
| 130 | +-------- |
| 131 | +OS: $OS |
| 132 | +Architecture: $ARCH |
| 133 | +Kernel: $KERNEL |
| 134 | +glibc: $GLIBC |
| 135 | +
|
| 136 | +Toolchain |
| 137 | +--------- |
| 138 | +Rust: $RUST_VERSION |
| 139 | +Cargo: $CARGO_VERSION |
| 140 | +CMake: $CMAKE_VERSION_STR |
| 141 | +CC: $CC_VERSION |
| 142 | +
|
| 143 | +OpenSSL (detected by openssl-sys at build time) |
| 144 | +------------------------------------------------ |
| 145 | +Version: $OPENSSL_VERSION |
| 146 | +Include path: $OPENSSL_INCLUDE |
| 147 | +Disabled (osslconf): ${OSSLCONF_FLAGS:-none} |
| 148 | +
|
| 149 | +Build Configuration |
| 150 | +------------------- |
| 151 | +CMAKE_BUILD_TYPE: $CMAKE_BUILD_TYPE |
| 152 | +CMAKE_INSTALL_PREFIX: $CMAKE_INSTALL_PREFIX |
| 153 | +CASS_BUILD_SHARED: $CASS_BUILD_SHARED |
| 154 | +CASS_BUILD_STATIC: $CASS_BUILD_STATIC |
| 155 | +LTO: $LTO |
| 156 | +Panic strategy: $PANIC |
| 157 | +
|
| 158 | +Static Library Compatibility Notes |
| 159 | +---------------------------------- |
| 160 | +The static archive (libscylladb_static.a) requires consumers to |
| 161 | +provide OpenSSL >= 3.0 at link time. The minimum OpenSSL version |
| 162 | +is determined by the build-time detection performed by the |
| 163 | +openssl-sys crate. |
| 164 | +
|
| 165 | +Consumers linking on systems with a different OpenSSL configuration |
| 166 | +(e.g. different osslconf flags) may encounter undefined symbol errors |
| 167 | +for conditionally-compiled functions. |
| 168 | +EOF |
| 169 | + |
| 170 | +echo "Generated: $OUTPUT" |
0 commit comments