Backed out changeset f53842753805 (bug 1804872) for causing reftest failures on 15535...
[gecko.git] / build / cargo-linker
blob94b05f821394e9cd8f00330f87464ddb30b6ba7c
1 #!/usr/bin/env python3
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
7 # was difficult.
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
14 #   itself.
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).
27 import os
28 import sys
30 SANITIZERS = {
31     "asan": "address",
32     "hwasan": "hwaddress",
33     "lsan": "leak",
34     "msan": "memory",
35     "tsan": "thread",
38 use_clang_sanitizer = os.environ.get("MOZ_CLANG_NEWER_THAN_RUSTC_LLVM")
39 wrap_ld = os.environ["MOZ_CARGO_WRAP_LD"]
40 args = os.environ["MOZ_CARGO_WRAP_LDFLAGS"].split()
41 for arg in sys.argv[1:]:
42     if arg in ["-lc++", "-lstdc++"]:
43         wrap_ld = os.environ["MOZ_CARGO_WRAP_LD_CXX"]
44     elif use_clang_sanitizer and arg.endswith("san.a"):
45         # When clang is newer than rustc's LLVM, we replace rust's sanitizer
46         # runtimes with clang's.
47         filename = os.path.basename(arg)
48         prefix, dot, suffix = filename[:-2].rpartition(".")
49         if (
50             prefix.startswith("librustc-")
51             and prefix.endswith("_rt") and dot == "."
52         ):
53             args.append(f"-fsanitize={SANITIZERS[suffix]}")
54             continue
55     args.append(arg)
57 wrap_ld = wrap_ld.split()
58 os.execvp(wrap_ld[0], wrap_ld + args)