From d0d58072d1f5cd56f235f6607943b27ea3f9b070 Mon Sep 17 00:00:00 2001 From: patchzyy <64382339+patchzyy@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:50:19 +0200 Subject: [PATCH] Bundle mbed TLS in Linux native prebuilt (#272) --- Launcher/Prepare-NativePrebuilt.sh | 39 +++++++++++++++++++----- Launcher/build-appimage.sh | 5 +-- runtime/CMakeLists.txt | 37 +++++++++++----------- runtime/cmake/MbedTLSPin.cmake | 4 +++ runtime/cmake/NativePrebuilt.cmake | 22 +++++++++++++ runtime/cmake/NativePrebuiltExport.cmake | 14 +++++++++ 6 files changed, 92 insertions(+), 29 deletions(-) create mode 100644 runtime/cmake/MbedTLSPin.cmake diff --git a/Launcher/Prepare-NativePrebuilt.sh b/Launcher/Prepare-NativePrebuilt.sh index 3d4e6ed..004fce8 100755 --- a/Launcher/Prepare-NativePrebuilt.sh +++ b/Launcher/Prepare-NativePrebuilt.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Builds the redistributable precompiled aurora + third-party package for native Linux: aurora -# (~43% of local build CPU time per Prepare-NativePrebuilt.ps1) and vendored Crypto++ are identical +# (~43% of local build CPU time per Prepare-NativePrebuilt.ps1), Crypto++ and mbed TLS are identical # for every user under the pinned toolchain prepare-portable-tools.sh bundles, so this configures # runtime/ against that toolchain, builds just that closure, and harvests the archives plus a # generated CMake description into an output package - the Linux counterpart to @@ -39,8 +39,7 @@ Usage: Prepare-NativePrebuilt.sh --arch {x86_64|aarch64} [options] --reuse-stage Reuse an existing staging build directory (maintainer iteration aid: a re-harvest does not recompile aurora from scratch) --parallel N Ninja build parallelism (default: nproc) - --print-fingerprint-only Print the four provenance inputs (compiler_sha256, flag_fingerprint, - aurora_fingerprint, third_party_fingerprint) as "key=value" lines and + --print-fingerprint-only Print the provenance inputs as "key=value" lines and exit, without configuring/building/harvesting anything - lets a caller (build-appimage.sh) decide whether an existing package is still current without paying for a full aurora rebuild just to find out. @@ -131,6 +130,8 @@ fixed_configure_flags=( -DCMAKE_DISABLE_FIND_PACKAGE_absl=ON -DCMAKE_DISABLE_FIND_PACKAGE_PNG=ON -DCMAKE_DISABLE_FIND_PACKAGE_Freetype=ON + -DUSE_STATIC_MBEDTLS_LIBRARY=ON + -DUSE_SHARED_MBEDTLS_LIBRARY=OFF # Freetype's own vendored CMakeLists.txt separately probes for system BZip2 (optional # bzip2-compressed-font support aurora-main never asked for) regardless of the Freetype # find_package disable above, since that only stops aurora's own outer find_package(Freetype) @@ -148,11 +149,10 @@ flag_fingerprint=$(printf '%s\n' "${fixed_configure_flags[@]}" | sha256sum | awk aurora_fingerprint=$(fingerprint_tree "$aurora_source" extern build) [[ -n "$aurora_fingerprint" ]] || fail "The aurora source tree could not be fingerprinted: $aurora_source" -# The harvested Crypto++ archive is consumed against this tree's headers, so it is fingerprinted -# for the same reason as aurora above. No exclusions: unlike aurora's extern/, nothing under -# runtime/third_party is shipped separately. +# The harvested Crypto++ archive is consumed against this tree's headers, so it is fingerprinted. third_party_fingerprint=$(fingerprint_tree "$runtime_source/third_party") [[ -n "$third_party_fingerprint" ]] || fail "The vendored third-party tree could not be fingerprinted: $runtime_source/third_party" +mbedtls_fingerprint=$(sha256_of "$runtime_source/cmake/MbedTLSPin.cmake") compiler_sha256=$(sha256_of "$clang_binary") @@ -161,6 +161,7 @@ if [[ "$print_fingerprint_only" -eq 1 ]]; then printf 'flag_fingerprint=%s\n' "$flag_fingerprint" printf 'aurora_fingerprint=%s\n' "$aurora_fingerprint" printf 'third_party_fingerprint=%s\n' "$third_party_fingerprint" + printf 'mbedtls_fingerprint=%s\n' "$mbedtls_fingerprint" exit 0 fi @@ -361,6 +362,21 @@ while IFS='|' read -r name type file linkerfile; do linker_file_to_reference["$linkerfile"]="@PKG@/$relative_linker" fi done < "$targets_txt" +mbedtls_refs=() +mbedtls_txt="$export_dir/mbedtls.txt" +assert_file "$mbedtls_txt" "Mbed TLS export targets list" +while IFS='|' read -r name linkerfile; do + [[ -n "$name" ]] || continue + linkerfile=$(normalize "$linkerfile") + ref=${linker_file_to_reference["$linkerfile"]:-} + [[ -n "$ref" ]] || fail "Mbed TLS archive was not harvested: $name ($linkerfile)" + mbedtls_refs+=("$ref") +done < "$mbedtls_txt" +[[ ${#mbedtls_refs[@]} -eq 3 ]] || fail "Expected three Mbed TLS archives, got ${#mbedtls_refs[@]}" +mbedtls_source_dir=$(get_meta mbedtls_source_dir) +assert_dir "$mbedtls_source_dir/include/mbedtls" "Mbed TLS headers" +mkdir -p "$output_dir/include/mbedtls" +cp -a "$mbedtls_source_dir/include/." "$output_dir/include/mbedtls/" # Unlike Windows (SDL/zlib/libpng ship as DLLs by default), everything here was forced static above # and Dawn's own Linux package (verified directly) ships libwebgpu_dawn.a, also static - so zero # shared imports is the expected, normal outcome, not a failure. @@ -426,6 +442,9 @@ for item in "${link_items[@]}"; do if [[ "$item" = /* ]]; then item_abs=$(normalize "$item"); else item_abs=$(normalize "$stage_dir/$item"); fi ref=${linker_file_to_reference["$item_abs"]:-} if [[ -n "$ref" ]]; then + for mbedtls_ref in "${mbedtls_refs[@]}"; do + [[ "$ref" == "$mbedtls_ref" ]] && continue 2 + done package_link_items+=("$ref") continue fi @@ -505,6 +524,9 @@ generated_cmake="$output_dir/native_prebuilt.cmake" format_cmake_block MKW_NP_COMPILE_DEFINITIONS "${package_definitions[@]}" format_cmake_block MKW_NP_COMPILE_OPTIONS "${package_compile_options[@]}" format_cmake_block MKW_NP_LINK_LIBRARIES "${package_link_items[@]}" + format_cmake_block MKW_NP_MBEDTLS_LIBRARIES "${mbedtls_refs[@]}" + echo 'set(MKW_NP_MBEDTLS_INCLUDE_DIR "@PKG@/include/mbedtls")' + printf 'set(MKW_NP_MBEDTLS_FINGERPRINT "%s")\n' "$mbedtls_fingerprint" format_cmake_block MKW_NP_AURORA_TARGETS "aurora::gx" "aurora::pad" "aurora::si" "aurora::vi" "aurora::mtx" echo "" printf 'set(MKW_NP_DAWN_CONFIG_DIR "%s")\n' "$dawn_config_token" @@ -540,12 +562,12 @@ harvested_count=${#linker_file_to_reference[@]} python3 - "$output_dir" "$compiler_sha256" "$compiler_version" "$flag_fingerprint" \ "$dawn_version" "$dawn_runtime_sha256" "$aurora_fingerprint" "$third_party_fingerprint" \ - "$sdl3_target" "$harvested_count" <<'PY' + "$sdl3_target" "$harvested_count" "$mbedtls_fingerprint" <<'PY' import hashlib, json, os, sys, datetime (output_dir, compiler_sha256, compiler_version, flag_fingerprint, dawn_version, dawn_runtime_sha256, aurora_fingerprint, third_party_fingerprint, sdl3_target, - harvested_count) = sys.argv[1:] + harvested_count, mbedtls_fingerprint) = sys.argv[1:] contents = [] for root, dirs, files in os.walk(output_dir): @@ -570,6 +592,7 @@ provenance = { "DawnRuntimeSha256": dawn_runtime_sha256, "AuroraSourceFingerprint": aurora_fingerprint, "ThirdPartySourceFingerprint": third_party_fingerprint, + "MbedTlsFingerprint": mbedtls_fingerprint, "Sdl3Target": sdl3_target, "HarvestedLibraryCount": int(harvested_count), "Contents": contents, diff --git a/Launcher/build-appimage.sh b/Launcher/build-appimage.sh index 5612405..d8c0a76 100755 --- a/Launcher/build-appimage.sh +++ b/Launcher/build-appimage.sh @@ -128,9 +128,9 @@ cp -a "$workspace/Launcher/artifacts/portable-tools/toolchain-$appimagetool_arch # Precompiled aurora + third-party package (see Prepare-NativePrebuilt.sh) so a user's own # local-build.sh never has to compile aurora itself (~43% of local build CPU time). Re-harvesting -# recompiles the whole aurora/Crypto++ closure with the toolchain above, so this is skipped unless +# recompiles the aurora/Crypto++/mbed TLS closure with the toolchain above, so this is skipped unless # --print-fingerprint-only (a fast, build-free check) says the existing package no longer matches -# the current compiler/flags/aurora/third_party sources. +# the current compiler, flags, source trees or mbed TLS pin. native_prebuilt_dir="$workspace/Launcher/artifacts/native-prebuilt-$appimagetool_arch" echo "Checking whether the precompiled aurora + third-party package ($appimagetool_arch) is current..." current_fingerprint=$(bash "$script_dir/Prepare-NativePrebuilt.sh" --arch "$appimagetool_arch" --print-fingerprint-only) @@ -148,6 +148,7 @@ fields = { "flag_fingerprint": "FlagFingerprint", "aurora_fingerprint": "AuroraSourceFingerprint", "third_party_fingerprint": "ThirdPartySourceFingerprint", + "mbedtls_fingerprint": "MbedTlsFingerprint", } print(1 if all(provenance.get(v) == current.get(k) for k, v in fields.items()) else 0) PY diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 336370b..6c573e0 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -113,11 +113,10 @@ endif() # compiles cleanly for Android with nothing beyond a plain C toolchain (no perl/asm build-script # dependency the way OpenSSL's build has), matching how this project already prefers toolchain- # simple libraries (see Crypto++ above, similarly stripped of ASM/SIMD for portability). -# Fetched at build time from a pinned upstream release tarball with a checked SHA-256, the same way -# aurora-main's own dependencies (SDL, zlib, etc.) are pulled in - not committed as a vendored -# source tree, so the repository ships the compiled dependency rather than ~280 tracked upstream -# files. Bump MKW_MBEDTLS_VERSION/MKW_MBEDTLS_SHA256 together when updating; the hash comes from -# upstream's own signed `mbedtls--sha256sum.txt` release asset. +# The from-source build fetches a pinned upstream tarball with a checked SHA-256. +# The Linux native prebuilt package instead ships its compiled archives and headers. +# Bump both values in cmake/MbedTLSPin.cmake when updating; the hash comes from +# upstream's signed `mbedtls--sha256sum.txt` release asset. # # The alias exists on every platform so the link lines in cmake/PublicProducts.cmake stay # platform-independent, but it is only populated where network_ssl.cpp actually compiles the mbed @@ -128,20 +127,20 @@ endif() add_library(mkw_mbedtls INTERFACE) add_library(mkw::mbedtls ALIAS mkw_mbedtls) if(NOT MKW_PLATFORM_WINDOWS) - include(FetchContent) - set(MKW_MBEDTLS_VERSION "3.6.7") - set(MKW_MBEDTLS_SHA256 "a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6") - FetchContent_Declare(mkw_mbedtls_upstream - URL "https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-${MKW_MBEDTLS_VERSION}/mbedtls-${MKW_MBEDTLS_VERSION}.tar.bz2" - URL_HASH SHA256=${MKW_MBEDTLS_SHA256}) - # Subproject mode already defaults ENABLE_TESTING off and skips codegen (GEN_FILES), but - # ENABLE_PROGRAMS defaults on and installation/package-config isn't wanted for a linked-in copy. - set(ENABLE_PROGRAMS OFF CACHE BOOL "" FORCE) - set(ENABLE_TESTING OFF CACHE BOOL "" FORCE) - set(MBEDTLS_FATAL_WARNINGS OFF CACHE BOOL "" FORCE) - set(DISABLE_PACKAGE_CONFIG_AND_INSTALL ON CACHE BOOL "" FORCE) - FetchContent_MakeAvailable(mkw_mbedtls_upstream) - target_link_libraries(mkw_mbedtls INTERFACE MbedTLS::mbedtls MbedTLS::mbedx509 MbedTLS::mbedcrypto) + include("${CMAKE_CURRENT_LIST_DIR}/cmake/MbedTLSPin.cmake") + if(NOT MKW_NATIVE_PREBUILT_DIR) + include(FetchContent) + FetchContent_Declare(mkw_mbedtls_upstream + URL "https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-${MKW_MBEDTLS_VERSION}/mbedtls-${MKW_MBEDTLS_VERSION}.tar.bz2" + URL_HASH SHA256=${MKW_MBEDTLS_SHA256}) + # Subproject mode already disables testing and codegen; it still enables programs. + set(ENABLE_PROGRAMS OFF CACHE BOOL "" FORCE) + set(ENABLE_TESTING OFF CACHE BOOL "" FORCE) + set(MBEDTLS_FATAL_WARNINGS OFF CACHE BOOL "" FORCE) + set(DISABLE_PACKAGE_CONFIG_AND_INSTALL ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(mkw_mbedtls_upstream) + target_link_libraries(mkw_mbedtls INTERFACE MbedTLS::mbedtls MbedTLS::mbedx509 MbedTLS::mbedcrypto) + endif() endif() set(MKW_TRANSLATED_COMPILE_JOBS 0 CACHE STRING diff --git a/runtime/cmake/MbedTLSPin.cmake b/runtime/cmake/MbedTLSPin.cmake new file mode 100644 index 0000000..a10771c --- /dev/null +++ b/runtime/cmake/MbedTLSPin.cmake @@ -0,0 +1,4 @@ +# Keep the release and verified archive hash together. The Linux native prebuilt +# fingerprint includes this file, so changing either value forces a new harvest. +set(MKW_MBEDTLS_VERSION "3.6.7") +set(MKW_MBEDTLS_SHA256 "a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6") diff --git a/runtime/cmake/NativePrebuilt.cmake b/runtime/cmake/NativePrebuilt.cmake index 2208a11..9cdce89 100644 --- a/runtime/cmake/NativePrebuilt.cmake +++ b/runtime/cmake/NativePrebuilt.cmake @@ -42,6 +42,28 @@ endfunction() mkw_np_resolve(_mkw_np_includes ${MKW_NP_INCLUDE_DIRECTORIES}) mkw_np_resolve(_mkw_np_links ${MKW_NP_LINK_LIBRARIES}) mkw_np_resolve(_mkw_np_dawn_config ${MKW_NP_DAWN_CONFIG_DIR}) +if(NOT MKW_PLATFORM_WINDOWS) + if(NOT MKW_NP_MBEDTLS_LIBRARIES OR NOT MKW_NP_MBEDTLS_INCLUDE_DIR) + message(FATAL_ERROR + "The Linux native prebuilt package has no Mbed TLS archives; regenerate it with Prepare-NativePrebuilt.sh") + endif() + file(SHA256 "${CMAKE_CURRENT_LIST_DIR}/MbedTLSPin.cmake" _mkw_np_current_mbedtls_fingerprint) + if(NOT MKW_NP_MBEDTLS_FINGERPRINT STREQUAL _mkw_np_current_mbedtls_fingerprint) + message(FATAL_ERROR "The native prebuilt Mbed TLS version differs from this workspace; regenerate the package") + endif() + mkw_np_resolve(_mkw_np_mbedtls_links ${MKW_NP_MBEDTLS_LIBRARIES}) + mkw_np_resolve(_mkw_np_mbedtls_include ${MKW_NP_MBEDTLS_INCLUDE_DIR}) + foreach(_archive IN LISTS _mkw_np_mbedtls_links) + if(NOT EXISTS "${_archive}") + message(FATAL_ERROR "The native prebuilt package is missing Mbed TLS archive: ${_archive}") + endif() + endforeach() + if(NOT IS_DIRECTORY "${_mkw_np_mbedtls_include}") + message(FATAL_ERROR "The native prebuilt package is missing Mbed TLS headers: ${_mkw_np_mbedtls_include}") + endif() + target_include_directories(mkw_mbedtls SYSTEM INTERFACE "${_mkw_np_mbedtls_include}") + target_link_libraries(mkw_mbedtls INTERFACE ${_mkw_np_mbedtls_links}) +endif() foreach(_dir IN LISTS _mkw_np_includes) if(NOT IS_DIRECTORY "${_dir}") diff --git a/runtime/cmake/NativePrebuiltExport.cmake b/runtime/cmake/NativePrebuiltExport.cmake index 89ffa9b..25904ec 100644 --- a/runtime/cmake/NativePrebuiltExport.cmake +++ b/runtime/cmake/NativePrebuiltExport.cmake @@ -77,6 +77,9 @@ target_compile_features(mkw_np_probe PRIVATE cxx_std_20) target_link_libraries(mkw_np_probe PRIVATE aurora::gx aurora::pad aurora::si aurora::vi aurora::mtx mkw::cryptopp) +if(NOT MKW_PLATFORM_WINDOWS) + target_link_libraries(mkw_np_probe PRIVATE mkw::mbedtls) +endif() get_filename_component(_mkw_np_aurora_dir "${MKW_AURORA_DIR}" ABSOLUTE) mkw_collect_buildsystem_targets("${_mkw_np_aurora_dir}" _mkw_np_all_targets) @@ -84,6 +87,16 @@ mkw_collect_buildsystem_targets("${_mkw_np_aurora_dir}" _mkw_np_all_targets) # the scan above cannot see it; it is appended explicitly. The type and closure # checks below still apply to it. list(APPEND _mkw_np_all_targets "mkw_cryptopp") +if(NOT MKW_PLATFORM_WINDOWS) + list(APPEND _mkw_np_all_targets mbedtls mbedx509 mbedcrypto) + # Keep the TLS archives separate from aurora's aggregate link interface. + string(CONCAT _mkw_np_mbedtls_lines + "mbedtls|$\n" + "mbedx509|$\n" + "mbedcrypto|$\n") + file(GENERATE OUTPUT "${MKW_NATIVE_PREBUILT_EXPORT_DIR}/mbedtls.txt" + CONTENT "${_mkw_np_mbedtls_lines}") +endif() if(NOT _mkw_np_all_targets) message(FATAL_ERROR "No buildsystem targets were found under ${_mkw_np_aurora_dir}") endif() @@ -136,6 +149,7 @@ string(REPLACE ";" "," _mkw_np_lib_targets_csv "${_mkw_np_lib_targets}") file(WRITE "${MKW_NATIVE_PREBUILT_EXPORT_DIR}/meta.txt" "aurora_dir=${_mkw_np_aurora_dir}\n" "runtime_dir=${CMAKE_CURRENT_SOURCE_DIR}\n" + "mbedtls_source_dir=${mkw_mbedtls_upstream_SOURCE_DIR}\n" "binary_dir=${CMAKE_BINARY_DIR}\n" "dawn_config_dir=${_mkw_np_dawn_config_dir}\n" "dawn_prebuilt_source_dir=${dawn_prebuilt_SOURCE_DIR}\n"