import argparse
import os
import stat
import sys
import shutil
import subprocess
import re
from collections import defaultdict
EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")
def main():
parser = argparse.ArgumentParser("find_std_rlibs.py")
parser.add_argument("--rust-bin-dir",
help="Path to Rust binaries",
required=True),
parser.add_argument("--target", help="Rust target triple", required=False),
parser.add_argument("--output",
help="Path to rlibs without suffixes",
required=True)
parser.add_argument("--depfile", help="Path to write depfile", required=True)
parser.add_argument("--depfile-target",
help="Target to key depfile around",
required=True)
parser.add_argument("--extra-libs",
help="List of extra non-libstd sysroot libraries")
parser.add_argument("--rustc-revision",
help="Not used, just passed from GN to add a dependency"
" on the rustc version.")
args = parser.parse_args()
extra_libs = set()
if args.extra_libs:
for lib in args.extra_libs.split(','):
extra_libs.add(lib)
rustc = os.path.join(args.rust_bin_dir, "rustc")
rustc_args = [rustc, "--print", "target-libdir"]
if args.target:
rustc_args.extend(["--target", args.target])
rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
rustlib_dir = os.path.relpath(rustlib_dir, os.path.realpath(os.curdir))
with open(args.depfile, 'w') as depfile:
depfile.write(
"%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
def copy_file(infile, outfile):
depfile.write(f" {infile}")
if (not os.path.exists(outfile)
or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
if os.path.exists(outfile):
st = os.stat(outfile)
os.chmod(outfile, st.st_mode | stat.S_IWUSR)
shutil.copy(infile, outfile)
rlibs_present = [
name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
]
rlibs_present.sort()
rlibs_seen = defaultdict(lambda: 0)
for f in rlibs_present:
(crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)
rlibs_seen[crate_name] += 1
if rlibs_seen[crate_name] == 1:
concise_name = crate_name
else:
concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])
output_filename = f"lib{concise_name}.rlib"
infile = os.path.join(rustlib_dir, f)
outfile = os.path.join(args.output, output_filename)
copy_file(infile, outfile)
for f in extra_libs:
infile = os.path.join(rustlib_dir, f)
outfile = os.path.join(args.output, f)
copy_file(infile, outfile)
depfile.write("\n")
if __name__ == '__main__':
sys.exit(main())