Build a configuration-matched Cargo static library during CMake builds and join its object members into the generated static libzstd archive. A single flattened archive avoids C-to-Rust and Rust-to-C archive-order failures for external consumers. Shared builds whole-archive the Cargo output so Rust-only public ABI exports remain visible. The configuration also follows partial compression and decompression builds, forced HUF modes, and supported 32-bit Linux targets. Dedicated CTest smoke consumers cover both linkage forms. Test Plan: - configure and build fresh static and shared CMake smoke targets - ctest -R 'rustLibSmoke(Static|Shared)' --output-on-failure - cargo clippy, cargo clippy --benches, cargo clippy --tests, and nightly fmt - validate partial, forced-HUF, i686, install, and incremental build paths Refs: build/cmake/lib/merge_rust_archive.cmake
83 lines
3.3 KiB
CMake
83 lines
3.3 KiB
CMake
# ################################################################
|
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
# All rights reserved.
|
|
#
|
|
# This source code is licensed under both the BSD-style license (found in the
|
|
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
# in the COPYING file in the root directory of this source tree).
|
|
# ################################################################
|
|
|
|
# Merge the Cargo static library into CMake's libzstd static archive. Keeping
|
|
# the object members in one archive matters: C objects call migrated Rust
|
|
# functions and Rust objects call C helpers, so two separate archives are
|
|
# sensitive to the consumer linker's archive scan order.
|
|
|
|
foreach(_zstd_required ARCHIVER RUST_ARCHIVE TARGET_ARCHIVE WORK_DIR)
|
|
if(NOT DEFINED ${_zstd_required})
|
|
message(FATAL_ERROR "${_zstd_required} is required")
|
|
endif()
|
|
endforeach()
|
|
|
|
file(REMOVE_RECURSE "${WORK_DIR}")
|
|
file(MAKE_DIRECTORY "${WORK_DIR}")
|
|
|
|
if(ARCHIVER_STYLE STREQUAL "MSVC")
|
|
# lib.exe accepts libraries as inputs and writes their object members to a
|
|
# new archive. Keep the original C archive separate while it is read,
|
|
# because /OUT must not overwrite an input archive.
|
|
set(_zstd_c_archive "${WORK_DIR}/libzstd-c.lib")
|
|
execute_process(
|
|
COMMAND "${CMAKE_COMMAND}" -E copy "${TARGET_ARCHIVE}" "${_zstd_c_archive}"
|
|
RESULT_VARIABLE _zstd_copy_result)
|
|
if(NOT _zstd_copy_result EQUAL 0)
|
|
message(FATAL_ERROR "could not copy ${TARGET_ARCHIVE} for Rust archive merge")
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND "${ARCHIVER}" "/OUT:${TARGET_ARCHIVE}" "${_zstd_c_archive}" "${RUST_ARCHIVE}"
|
|
RESULT_VARIABLE _zstd_merge_result
|
|
OUTPUT_VARIABLE _zstd_merge_output
|
|
ERROR_VARIABLE _zstd_merge_error)
|
|
else()
|
|
execute_process(
|
|
COMMAND "${ARCHIVER}" x "${RUST_ARCHIVE}"
|
|
WORKING_DIRECTORY "${WORK_DIR}"
|
|
RESULT_VARIABLE _zstd_extract_result
|
|
OUTPUT_VARIABLE _zstd_extract_output
|
|
ERROR_VARIABLE _zstd_extract_error)
|
|
if(NOT _zstd_extract_result EQUAL 0)
|
|
message(FATAL_ERROR
|
|
"could not extract Rust archive ${RUST_ARCHIVE}: ${_zstd_extract_output}${_zstd_extract_error}")
|
|
endif()
|
|
|
|
file(GLOB _zstd_rust_objects "${WORK_DIR}/*.o" "${WORK_DIR}/*.obj")
|
|
if(NOT _zstd_rust_objects)
|
|
message(FATAL_ERROR "Rust archive ${RUST_ARCHIVE} did not contain object files")
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND "${ARCHIVER}" q "${TARGET_ARCHIVE}" ${_zstd_rust_objects}
|
|
RESULT_VARIABLE _zstd_merge_result
|
|
OUTPUT_VARIABLE _zstd_merge_output
|
|
ERROR_VARIABLE _zstd_merge_error)
|
|
endif()
|
|
|
|
if(NOT _zstd_merge_result EQUAL 0)
|
|
message(FATAL_ERROR
|
|
"could not merge Rust archive ${RUST_ARCHIVE}: ${_zstd_merge_output}${_zstd_merge_error}")
|
|
endif()
|
|
|
|
if(DEFINED RANLIB AND NOT "${RANLIB}" STREQUAL "" AND NOT ARCHIVER_STYLE STREQUAL "MSVC")
|
|
execute_process(
|
|
COMMAND "${RANLIB}" "${TARGET_ARCHIVE}"
|
|
RESULT_VARIABLE _zstd_ranlib_result
|
|
OUTPUT_VARIABLE _zstd_ranlib_output
|
|
ERROR_VARIABLE _zstd_ranlib_error)
|
|
if(NOT _zstd_ranlib_result EQUAL 0)
|
|
message(FATAL_ERROR
|
|
"could not index ${TARGET_ARCHIVE}: ${_zstd_ranlib_output}${_zstd_ranlib_error}")
|
|
endif()
|
|
endif()
|
|
|
|
file(REMOVE_RECURSE "${WORK_DIR}")
|