Files
zstd-rs/build/meson/lib/cargo_staticlib.py
ddidderr 3d679116d8 build(meson): link migrated Rust code into native libraries
Build a configuration-matched Cargo archive from Meson and flatten its object
members into static libzstd.  This gives C consumers one archive even though
the migrated Rust objects and remaining C code refer to each other.

Shared libraries whole-archive the Cargo output to retain Rust-only ABI
exports.  The implementation supports Meson 0.50's generated-archive linking
rules, matching HUF mode and 32-bit configuration, and documents cross-build
target and archiver selection.

Test Plan:
- fresh Meson both-build smoke consumers and invalidDictionaries
- modern static/shared/both, forced-HUF, i686, install, and fuzzer paths
- real Meson 0.50 static and shared smoke builds
- cargo clippy, cargo clippy --benches, cargo clippy --tests, and nightly fmt

Refs: build/meson/README.md archive and cross-build documentation
2026-07-10 22:08:55 +02:00

78 lines
2.3 KiB
Python

#!/usr/bin/env python3
# ################################################################
# 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).
# You may select, at your option, one of the above-listed licenses.
# ################################################################
"""Build Cargo's staticlib and publish it at a Meson custom-target output."""
from __future__ import print_function
import argparse
import filecmp
import os
from pathlib import Path
import shutil
import subprocess
import sys
def copy_if_changed(source, destination):
if destination.exists() and filecmp.cmp(str(source), str(destination), shallow=False):
return
temporary = destination.with_name(destination.name + '.tmp')
shutil.copyfile(str(source), str(temporary))
os.replace(str(temporary), str(destination))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--cargo', required=True)
parser.add_argument('--manifest-path', required=True)
parser.add_argument('--target-dir', required=True)
parser.add_argument('--staticlib-name', required=True)
parser.add_argument('--output', required=True)
parser.add_argument('--features', default='')
parser.add_argument('--target', default='')
args = parser.parse_args()
command = [
args.cargo,
'build',
'--manifest-path',
args.manifest_path,
'--release',
'--target-dir',
args.target_dir,
'--no-default-features',
]
if args.features:
command.extend(['--features', args.features])
if args.target:
command.extend(['--target', args.target])
subprocess.check_call(command)
artifact = Path(args.target_dir)
if args.target:
artifact /= args.target
artifact /= 'release'
artifact /= args.staticlib_name
if not artifact.is_file():
print('Cargo did not produce {}'.format(artifact), file=sys.stderr)
return 1
output = Path(args.output)
output.parent.mkdir(parents=True, exist_ok=True)
copy_if_changed(artifact, output)
return 0
if __name__ == '__main__':
sys.exit(main())