Files
zstd-rs/build/cmake/lib/merge_rust_archive.cmake
T
ddidderr 22ec52d5ec build(cmake): link migrated Rust code into native libraries
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
2026-07-10 21:55:40 +02:00

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}")