Skip to content

Commit ee88ee7

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 ee88ee7

2 files changed

Lines changed: 199 additions & 0 deletions

File tree

ci/generate-build-info.sh

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
OPENSSL_SYS_OUTPUT=""
70+
# The output file is at target/<profile>/build/openssl-sys-<hash>/output
71+
# Search within the cargo target directory used by this build.
72+
CARGO_TARGET_DIR=$(cmake_cache_get "CARGO_TARGET_DIR")
73+
if [ "$CARGO_TARGET_DIR" = "unknown" ] || [ ! -d "$CARGO_TARGET_DIR" ]; then
74+
# Fallback: search in the standard location
75+
CARGO_TARGET_DIR="$SOURCE_DIR/scylla-rust-wrapper/target"
76+
fi
77+
if [ -d "$CARGO_TARGET_DIR" ]; then
78+
OPENSSL_SYS_OUTPUT=$(find "$CARGO_TARGET_DIR" -path "*/openssl-sys-*/output" -type f 2>/dev/null | head -1)
79+
fi
80+
81+
if [ -n "$OPENSSL_SYS_OUTPUT" ] && [ -f "$OPENSSL_SYS_OUTPUT" ]; then
82+
OPENSSL_VERSION_HEX=$(grep "^cargo:version_number=" "$OPENSSL_SYS_OUTPUT" | cut -d= -f2 || echo "")
83+
OPENSSL_INCLUDE=$(grep "^cargo:include=" "$OPENSSL_SYS_OUTPUT" | cut -d= -f2 || echo "unknown")
84+
OSSLCONF_FLAGS=$(grep "^cargo:rustc-cfg=osslconf=" "$OPENSSL_SYS_OUTPUT" | sed 's/cargo:rustc-cfg=osslconf="\(.*\)"/\1/' | paste -sd ' ' || echo "none")
85+
86+
# Quoting from openssl docs:
87+
# > A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys`
88+
# > crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER`
89+
# > environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version:
90+
# > `0xMNNFFPPS`. For example, version 1.0.2g’s encoding is `0x1_00_02_07_0`.
91+
#
92+
# However, OpenSSL 3.x changed the displaying, while encoding is still the same.
93+
# - In version 1.2.3.c, 3 was Fix and c was Patch.
94+
# - In version 3.2.1, 3 is Patch and Fix is not present (0).
95+
# We're only interested in OpenSSL 3+, so we can assume the version is in the Major.Minor.Patch format.
96+
if [ -n "$OPENSSL_VERSION_HEX" ]; then
97+
dec=$((16#$OPENSSL_VERSION_HEX))
98+
major=$(( (dec >> 28) & 0xF ))
99+
minor=$(( (dec >> 20) & 0xFF ))
100+
patch=$(( (dec >> 4) & 0xFF ))
101+
OPENSSL_VERSION="${major}.${minor}.${patch}"
102+
else
103+
OPENSSL_VERSION="unknown"
104+
fi
105+
else
106+
OPENSSL_VERSION=$(pkg-config --modversion openssl 2>/dev/null || echo "unknown")
107+
OPENSSL_INCLUDE=$(pkg-config --variable=includedir openssl 2>/dev/null || echo "unknown")
108+
OSSLCONF_FLAGS="unknown (openssl-sys build output not found)"
109+
fi
110+
111+
# --- Build configuration (from Cargo.toml) ---
112+
113+
CARGO_TOML="$SOURCE_DIR/scylla-rust-wrapper/Cargo.toml"
114+
if [ -f "$CARGO_TOML" ]; then
115+
LTO=$(grep "^lto" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown")
116+
PANIC=$(grep "^panic" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown")
117+
else
118+
LTO="unknown"
119+
PANIC="unknown"
120+
fi
121+
122+
# --- CMake options ---
123+
124+
CMAKE_BUILD_TYPE=$(cmake_cache_get "CMAKE_BUILD_TYPE")
125+
CMAKE_INSTALL_PREFIX=$(cmake_cache_get "CMAKE_INSTALL_PREFIX")
126+
CASS_BUILD_SHARED=$(cmake_cache_get "CASS_BUILD_SHARED")
127+
CASS_BUILD_STATIC=$(cmake_cache_get "CASS_BUILD_STATIC")
128+
129+
# --- Write output ---
130+
131+
cat > "$OUTPUT" <<EOF
132+
Build Information for scylla-cpp-driver $VERSION
133+
134+
Platform
135+
--------
136+
OS: $OS
137+
Architecture: $ARCH
138+
Kernel: $KERNEL
139+
glibc: $GLIBC
140+
141+
Toolchain
142+
---------
143+
Rust: $RUST_VERSION
144+
Cargo: $CARGO_VERSION
145+
CMake: $CMAKE_VERSION_STR
146+
CC: $CC_VERSION
147+
148+
OpenSSL (detected by openssl-sys at build time)
149+
------------------------------------------------
150+
Version: $OPENSSL_VERSION
151+
Include path: $OPENSSL_INCLUDE
152+
Disabled (osslconf): ${OSSLCONF_FLAGS:-none}
153+
154+
Build Configuration
155+
-------------------
156+
CMAKE_BUILD_TYPE: $CMAKE_BUILD_TYPE
157+
CMAKE_INSTALL_PREFIX: $CMAKE_INSTALL_PREFIX
158+
CASS_BUILD_SHARED: $CASS_BUILD_SHARED
159+
CASS_BUILD_STATIC: $CASS_BUILD_STATIC
160+
LTO: $LTO
161+
Panic strategy: $PANIC
162+
163+
Static Library Compatibility Notes
164+
----------------------------------
165+
The static archive (libscylladb_static.a) requires consumers to
166+
provide OpenSSL >= 3.0 at link time. The minimum OpenSSL version
167+
is determined by the build-time detection performed by the
168+
openssl-sys crate.
169+
170+
Consumers linking on systems with a different OpenSSL configuration
171+
(e.g. different osslconf flags) may encounter undefined symbol errors
172+
for conditionally-compiled functions.
173+
EOF
174+
175+
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)