This dedicated Bazel repository handles the download, isolation, and hermetic compilation of the C++ OpenSSL dependency suite. It sits at the bottom of the project's dependency graph, providing a clean, unidirectional cross-language (C++/Rust FFI) build path that decouples Bazel Bzlmod module releases.
In a centralized Bazel workspace setup, the @score_crates repository serves as the single registry for Rust packages and FFI bindings.
Compiling Rust FFI bindings (such as openssl-sys inside @score_crates) requires linking against compiled C++ OpenSSL binaries. Hosting OpenSSL build logic inside score_crypto or @score_baselibs introduces circular module-level dependencies:
score_crypto depends on @score_crates to fetch Rust dependencies (libc, serde, parking_lot). If @score_crates also depends on score_crypto to resolve C++ OpenSSL targets for openssl-sys, a circular module relationship is created:
score_crypto↔@score_crates
@score_baselibs consumes Rust packages from @score_crates. Storing OpenSSL in @score_baselibs creates a bidirectional module relationship:
@score_baselibs↔@score_crates
Circular module loops create a fatal "chicken-and-egg" release deadlock:
- You cannot publish or version
@score_crateswithout releasingscore_cryptofirst. - You cannot publish or version
score_cryptowithout releasing@score_cratesfirst.
Isolating OpenSSL into its own separate @score_openssl module breaks this loop completely. It allows us to tag, version, and release each repository independently, making our release pipeline clean and simple.
Extracting OpenSSL compilation into a standalone leaf-node module (@score_openssl) ensures a unidirectional dependency flow:
┌─────────────────────────────────────────────────────────────────────────┐
│ USER / CI PIPELINE │
└────────────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ score_crypto Repo │
│ (Main Cryptographic Provider Library) │
└─────────────┬─────────────────────────────────────────┬─────────────────┘
│ │
▼ (Depends on Rust crates) ▼ (Depends on C++ FFI)
┌───────────────────────────┐ ┌───────────────────────────┐
│ @score_crates │ │ @score_openssl │
│ (Central Rust Registry) │ │ (C++ Build Rules/Patches) │
│ │ │ │
│ * Central Rust crates │ │ * Zero external deps! │
│ * Pre-patched openssl-sys │ │ * Owns build rules/patch │
└─────────────┬─────────────┘ └───────────────────────────┘
│ │
└─────────────────────────────────────────┘
(@score_crates links down to @score_openssl//:openssl_link)
- Unidirectional Graph:
@score_opensslacts as a clean leaf module. Bothscore_cryptoand@score_cratesconsume it without creating circular release loops. - Independent Release Lifecycle:
@score_opensslcan be tagged, versioned, and updated independently of Rust crates or higher-level crypto daemons. - Workspace Cleanliness:
score_cryptoremains free of C++ OpenSSL target build rules, genrules, and platform patch files.
- Approach:
@score_openssluses Bazel'shttp_archiverule to pull pristine, official OpenSSL release archives at build time, applying target-compilation patches on the fly. - Rationale: This is currently the only mechanism that allows both Linux and QNX binaries to be built from source with exact, deterministic
OPENSSL_NO_*feature flag configurations. It guarantees strict feature control and identicalcryptokiFFI contracts across all target architectures.
- Approach: Import OpenSSL via Bzlmod using the standard BCR repository (
bazel_dep(name = "openssl")). - Why Discarded: The default BCR OpenSSL module lacks out-of-the-box support for QNX target platforms and toolchains. Adapting it for QNX would require extensive local patching and Bazel module overrides, negating the benefits of an off-the-shelf BCR package.
- Approach: Link directly against pre-compiled OpenSSL libraries shipped inside the QNX Software Development Platform (SDP).
- Status / Exploration Alternative: This is currently under investigation as a platform-specific alternative for QNX targets. However, because QNX SDP binaries only support QNX execution and do not provide Linux host/target capabilities, compiling from the source tarball remains our primary unified baseline to guarantee identical, deterministic feature configurations (
OPENSSL_NO_*gates) and perfect FFI contract matching across both Linux and QNX.
(Note: If the platform strategy later transitions to standardized OS/BCR modules across all target platforms, @score_openssl can be evaluated for consolidation into @score_crates.)
According to DR-002, the default delivery model for libraries across S-CORE is static linking to guarantee deterministic binary deployment and safety in automotive targets:
:openssl(Default): Staticcc_librarylinkinglibcrypto.aandlibssl.a.:openssl_shared(Opt-in): Dynamiccc_shared_libraryproducinglibopenssl.so.3.:openssl_shared_import: Adapter forrules_rustFFI linking.:openssl_link(Public Switchboard): Resolves between static and dynamic linking based on theuse_dynamic_opensslflag:
# Default: Static linking (honors DR-002)
bazel build //...
# Opt-in: Shared linking (requires alignment across all downstream modules)
bazel build --//:use_dynamic_openssl=True //...:openssl_impl(Master Override Point): Rootlabel_flagallowing top-level integrating workspaces (OEMs) to globally replace the OpenSSL compilation target (e.g. pointing to a prebuilt or hardware-certified library like@openssl//:ssl). Defaults to:openssl_make:
# Override example (e.g. in root .bazelrc):
build --@score_openssl//:openssl_impl=@openssl//:ssl