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
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# ################################################################
|
||||
# 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}")
|
||||
Reference in New Issue
Block a user