3 # If you want to use a custom linker with Cargo, Cargo requires that you
4 # specify it in Cargo.toml or via the matching environment variable.
5 # Passing extra options to the linker is possible with Cargo via
6 # RUSTFLAGS='-C link-args', but testing showed that doing this reliably
9 # Our solution to these problems is to use this wrapper script. We pass
10 # in the LD and the LDFLAGS to use via environment variables.
12 # * MOZ_CARGO_WRAP_LD is equivalent to CC on Unix-y platforms, and CC
13 # frequently has additional arguments in addition to the compiler
16 # * MOZ_CARGO_WRAP_LDFLAGS contains space-separated arguments to pass,
17 # and not quoting it ensures that each of those arguments is passed
18 # as a separate argument to the actual LD.
20 # * In rare cases, we also need MOZ_CARGO_WRAP_LD_CXX, which is the
21 # equivalent of CXX, when linking C++ code. Usually, this should
22 # simply work by the use of CC and -lstdc++ (added by cc-rs).
23 # However, in the case of sanitizer runtimes, there is a separate
24 # runtime for C and C++ and linking C++ code with the C runtime can
25 # fail if the requested feature is in the C++ runtime only (bug 1747298).
30 # This is not necessarily run with a virtualenv python, so add
31 # the necessary directory for the shellutil module.
32 base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
33 sys.path.insert(0, os.path.join(base_dir, "python", "mozbuild"))
34 from mozbuild.shellutil import split
39 "hwasan": "hwaddress",
45 use_clang_sanitizer = os.environ.get("MOZ_CLANG_NEWER_THAN_RUSTC_LLVM")
46 wrap_ld = os.environ["MOZ_CARGO_WRAP_LD"]
47 args = split(os.environ["MOZ_CARGO_WRAP_LDFLAGS"])
48 for arg in sys.argv[1:]:
49 if arg in ["-lc++", "-lstdc++"]:
50 wrap_ld = os.environ["MOZ_CARGO_WRAP_LD_CXX"]
51 elif use_clang_sanitizer and arg.endswith("san.a"):
52 # When clang is newer than rustc's LLVM, we replace rust's sanitizer
53 # runtimes with clang's.
54 filename = os.path.basename(arg)
55 prefix, dot, suffix = filename[:-2].rpartition(".")
57 prefix.startswith("librustc-")
58 and prefix.endswith("_rt") and dot == "."
60 args.append(f"-fsanitize={SANITIZERS[suffix]}")
64 wrap_ld = split(wrap_ld)
65 os.execvp(wrap_ld[0], wrap_ld + args)