Skip to content

Commit 827ce5d

Browse files
committed
build: generate BUILD_INFO on every build
Add a script that captures build environment metadata (OS, toolchain, OpenSSL version and configuration, CMake options, Rust profile) into a BUILD_INFO file in the build directory. A CMake custom target runs the script after the cargo build completes, ensuring openssl-sys detection results are available. If bash is not present, the target is silently skipped. This addresses issue #455's request for transparency about what Linux version and OpenSSL configuration the static archive was built against.
1 parent 3dab115 commit 827ce5d

2 files changed

Lines changed: 194 additions & 0 deletions

File tree

ci/generate-build-info.sh

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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"

scylla-rust-wrapper/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,30 @@ if(CASS_BUILD_STATIC)
217217
endif()
218218
endif()
219219

220+
#-------------------------------------
221+
# Build metadata
222+
#-------------------------------------
223+
224+
# Generate BUILD_INFO capturing the build environment. The script is
225+
# bash-specific; if bash is unavailable the target is skipped silently.
226+
find_program(BASH_EXECUTABLE bash)
227+
if(BASH_EXECUTABLE)
228+
add_custom_command(
229+
OUTPUT ${CMAKE_BINARY_DIR}/BUILD_INFO
230+
COMMAND ${BASH_EXECUTABLE} ${CASS_ROOT_DIR}/ci/generate-build-info.sh
231+
${CMAKE_BINARY_DIR}/BUILD_INFO
232+
WORKING_DIRECTORY ${CASS_ROOT_DIR}
233+
COMMENT "Generating BUILD_INFO"
234+
VERBATIM
235+
)
236+
add_custom_target(build_info ALL DEPENDS ${CMAKE_BINARY_DIR}/BUILD_INFO)
237+
if(TARGET scylladb_staticlib_target)
238+
add_dependencies(build_info scylladb_staticlib_target)
239+
elseif(TARGET scylladb_cdylib_target)
240+
add_dependencies(build_info scylladb_cdylib_target)
241+
endif()
242+
endif()
243+
220244
#-------------------------------------
221245
# Installation
222246
#-------------------------------------

0 commit comments

Comments
 (0)