import argparse
import os
import stat
import sys
import shutil
import subprocess
import re
REMOVE_METADATA_SUFFIX_RE = re.compile(b"-[0-9a-f]*", re.I)
def expand_name(concise_name):
return "lib%s.rlib" % concise_name
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("--stdlibs",
help="Expected list of standard library libraries")
parser.add_argument("--skip-stdlibs",
help="Standard library files to skip",
default="")
parser.add_argument("--expected-rustc-version",
help="The string we expect to be reported by 'rustc -V'")
args = parser.parse_args()
if args.stdlibs:
rlibs_expected = [expand_name(x) for x in args.stdlibs.split(',')]
else:
rlibs_expected = None
rlibs_to_skip = [expand_name(x) for x in args.skip_stdlibs.split(',')]
rustc = os.path.join(args.rust_bin_dir, "rustc")
if args.expected_rustc_version:
proc = subprocess.run([rustc, "-V"], capture_output=True, text=True)
proc.check_returncode()
rustc_version = proc.stdout.rstrip()
if rustc_version != args.expected_rustc_version:
raise Exception("gn arguments state that the rustc_version is %s "
"but it was actually %s. Please adjust your "
"gn arguments to match." %
(args.expected_rustc_version, rustc_version))
rustc_args = [rustc, "--print", "target-libdir"]
if args.target:
rustc_args.extend(["--target", args.target])
rustlib_dir = subprocess.check_output(rustc_args).rstrip()
with open(args.depfile, 'w') as depfile:
depfile.write("%s:" %
(os.path.join(args.output, expand_name(args.depfile_target))))
for f in os.listdir(rustlib_dir):
if f.endswith(b'.rlib'):
(concise_name, count) = REMOVE_METADATA_SUFFIX_RE.subn(b"", f)
if count == 0:
raise Exception("Unable to remove suffix from %s" % f)
if concise_name.decode() in rlibs_to_skip:
continue
if rlibs_expected is not None:
if concise_name.decode() not in rlibs_expected:
raise Exception("Found stdlib rlib that wasn't expected: %s" %
concise_name)
rlibs_expected.remove(concise_name.decode())
infile = os.path.join(rustlib_dir, f)
outfile = os.path.join(str.encode(args.output), concise_name)
depfile.write(" %s" % (infile.decode()))
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)
depfile.write("\n")
if rlibs_expected:
raise Exception("We failed to find all expected stdlib rlibs: %s" %
','.join(rlibs_expected))
if __name__ == '__main__':
sys.exit(main())