Skip to content

Commit 38b61e5

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 5eae362 commit 38b61e5

2 files changed

Lines changed: 191 additions & 0 deletions

File tree

ci/generate-build-info.sh

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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+
# Convert hex version to human-readable: 30500030 -> 3.5.0
87+
# openssl-sys prints the version number without 0x prefix but it is hex.
88+
if [ -n "$OPENSSL_VERSION_HEX" ]; then
89+
dec=$((16#$OPENSSL_VERSION_HEX))
90+
major=$(( (dec >> 28) & 0xF ))
91+
minor=$(( (dec >> 20) & 0xFF ))
92+
patch=$(( (dec >> 12) & 0xFF ))
93+
OPENSSL_VERSION="${major}.${minor}.${patch}"
94+
else
95+
OPENSSL_VERSION="unknown"
96+
fi
97+
else
98+
OPENSSL_VERSION=$(pkg-config --modversion openssl 2>/dev/null || echo "unknown")
99+
OPENSSL_INCLUDE=$(pkg-config --variable=includedir openssl 2>/dev/null || echo "unknown")
100+
OSSLCONF_FLAGS="unknown (openssl-sys build output not found)"
101+
fi
102+
103+
# --- Build configuration (from Cargo.toml) ---
104+
105+
CARGO_TOML="$SOURCE_DIR/scylla-rust-wrapper/Cargo.toml"
106+
if [ -f "$CARGO_TOML" ]; then
107+
LTO=$(grep "^lto" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown")
108+
PANIC=$(grep "^panic" "$CARGO_TOML" | head -1 | sed 's/.*=[ ]*//' | tr -d '"' || echo "unknown")
109+
else
110+
LTO="unknown"
111+
PANIC="unknown"
112+
fi
113+
114+
# --- CMake options ---
115+
116+
CMAKE_BUILD_TYPE=$(cmake_cache_get "CMAKE_BUILD_TYPE")
117+
CMAKE_INSTALL_PREFIX=$(cmake_cache_get "CMAKE_INSTALL_PREFIX")
118+
CASS_BUILD_SHARED=$(cmake_cache_get "CASS_BUILD_SHARED")
119+
CASS_BUILD_STATIC=$(cmake_cache_get "CASS_BUILD_STATIC")
120+
121+
# --- Write output ---
122+
123+
cat > "$OUTPUT" <<EOF
124+
Build Information for scylla-cpp-driver $VERSION
125+
126+
Platform
127+
--------
128+
OS: $OS
129+
Architecture: $ARCH
130+
Kernel: $KERNEL
131+
glibc: $GLIBC
132+
133+
Toolchain
134+
---------
135+
Rust: $RUST_VERSION
136+
Cargo: $CARGO_VERSION
137+
CMake: $CMAKE_VERSION_STR
138+
CC: $CC_VERSION
139+
140+
OpenSSL (detected by openssl-sys at build time)
141+
------------------------------------------------
142+
Version: $OPENSSL_VERSION
143+
Include path: $OPENSSL_INCLUDE
144+
Disabled (osslconf): ${OSSLCONF_FLAGS:-none}
145+
146+
Build Configuration
147+
-------------------
148+
CMAKE_BUILD_TYPE: $CMAKE_BUILD_TYPE
149+
CMAKE_INSTALL_PREFIX: $CMAKE_INSTALL_PREFIX
150+
CASS_BUILD_SHARED: $CASS_BUILD_SHARED
151+
CASS_BUILD_STATIC: $CASS_BUILD_STATIC
152+
LTO: $LTO
153+
Panic strategy: $PANIC
154+
155+
Static Library Compatibility Notes
156+
----------------------------------
157+
The static archive (libscylladb_static.a) requires consumers to
158+
provide OpenSSL >= 3.0 at link time. The minimum OpenSSL version
159+
is determined by the build-time detection performed by the
160+
openssl-sys crate.
161+
162+
Consumers linking on systems with a different OpenSSL configuration
163+
(e.g. different osslconf flags) may encounter undefined symbol errors
164+
for conditionally-compiled functions.
165+
EOF
166+
167+
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)