mirror of
https://github.com/denoland/deno.git
synced 2024-11-29 16:30:56 -05:00
build: fix compatibility with rustc 1.30.0
Additionally: * Rebuild rust crates when the rustc version changes. * Fetch all rust ldflags in one exec_script() call instead of two.
This commit is contained in:
parent
243a3ba2d0
commit
00e4f7cf83
4 changed files with 49 additions and 31 deletions
|
@ -25,28 +25,21 @@
|
|||
# this script then reads the linker arguments from that temporary file, and
|
||||
# then filters it to remove flags that are irrelevant or undesirable.
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
from os import path
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
def capture_args(argsfile_path):
|
||||
def capture_linker_args(argsfile_path):
|
||||
with open(argsfile_path, "wb") as argsfile:
|
||||
argsfile.write("\n".join(sys.argv[1:]))
|
||||
|
||||
|
||||
def main():
|
||||
# If ARGSFILE_PATH is set this script is being invoked by rustc, which
|
||||
# thinks we are a linker. All we do now is write our argv to the specified
|
||||
# file and exit. Further processing is done by our grandparent process,
|
||||
# also this script but invoked by gn.
|
||||
argsfile_path = os.getenv("ARGSFILE_PATH")
|
||||
if argsfile_path is not None:
|
||||
return capture_args(argsfile_path)
|
||||
|
||||
def get_ldflags(rustc_args):
|
||||
# Prepare the environment for rustc.
|
||||
rustc_env = os.environ.copy()
|
||||
|
||||
|
@ -80,12 +73,13 @@ def main():
|
|||
# Build the rustc command line.
|
||||
# * `-Clinker=` tells rustc to use our fake linker.
|
||||
# * `-Csave-temps` prevents rustc from deleting object files after
|
||||
# linking. We need to preserve the file `xx.crate.allocator.rcgu.o`.
|
||||
# linking. We need to preserve the extra object file with allocator
|
||||
# symbols (`_rust_alloc` etc.) in it that rustc produces.
|
||||
rustc_cmd = [
|
||||
"rustc",
|
||||
"-Clinker=" + rustc_linker,
|
||||
"-Csave-temps",
|
||||
] + sys.argv[1:]
|
||||
] + rustc_args
|
||||
|
||||
# Spawn the rust compiler.
|
||||
rustc_proc = subprocess.Popen(
|
||||
|
@ -143,13 +137,16 @@ def main():
|
|||
elif arg.endswith(".rlib"):
|
||||
# Built-in Rust library, e.g. `libstd-8524caae8408aac2.rlib`.
|
||||
pass
|
||||
elif arg.endswith(".crate.allocator.rcgu.o"):
|
||||
elif re.match(r"^empty_crate\.[a-z0-9]+\.rcgu.o$", arg):
|
||||
# This file is needed because it contains certain allocator
|
||||
# related symbols (e.g. `__rust_alloc`, `__rust_oom`).
|
||||
# The Rust compiler normally generates this file just before
|
||||
# linking an executable. We pass `-Csave-temps` to rustc so it
|
||||
# doesn't delete the file when it's done linking.
|
||||
pass
|
||||
elif arg.endswith(".crate.allocator.rcgu.o"):
|
||||
# Same as above, but for rustc version 1.29.0 and older.
|
||||
pass
|
||||
elif arg.endswith(".lib") and not arg.startswith("msvcrt"):
|
||||
# Include most Windows static/import libraries (e.g. `ws2_32.lib`).
|
||||
# However we ignore Rusts choice of C runtime (`mvcrt*.lib`).
|
||||
|
@ -172,8 +169,34 @@ def main():
|
|||
|
||||
ldflags += [arg]
|
||||
|
||||
# Write the filtered ldflags to stdout, separated by newline characters.
|
||||
sys.stdout.write("\n".join(ldflags))
|
||||
return ldflags
|
||||
|
||||
|
||||
def get_version():
|
||||
version = subprocess.check_output(["rustc", "--version"])
|
||||
version = version.strip() # Remove trailing newline.
|
||||
return version
|
||||
|
||||
|
||||
def main():
|
||||
# If ARGSFILE_PATH is set this script is being invoked by rustc, which
|
||||
# thinks we are a linker. All we do now is write our argv to the specified
|
||||
# file and exit. Further processing is done by our grandparent process,
|
||||
# also this script but invoked by gn.
|
||||
argsfile_path = os.getenv("ARGSFILE_PATH")
|
||||
if argsfile_path is not None:
|
||||
return capture_linker_args(argsfile_path)
|
||||
|
||||
empty_crate_source = path.join(path.dirname(__file__), "empty_crate.rs")
|
||||
|
||||
info = {
|
||||
"version": get_version(),
|
||||
"ldflags_bin": get_ldflags([empty_crate_source]),
|
||||
"ldflags_test": get_ldflags([empty_crate_source, "--test"])
|
||||
}
|
||||
|
||||
# Write the information dict as a json object.
|
||||
json.dump(info, sys.stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
|
@ -29,23 +29,15 @@ out_dir = "$root_out_dir/rust_crates"
|
|||
# * To sidestep rustc weirdness (e.g. on Windows, it always links with the
|
||||
# release C runtime library, even for debug builds).
|
||||
#
|
||||
# The `get_rust_ldflags` tool outputs the linker flags that are needed to
|
||||
# The `get_rustc_info` tool outputs the linker flags that are needed to
|
||||
# successfully link rustc object code into an executable.
|
||||
# We generate two sets of ldflags:
|
||||
# `rust_bin_ldflags`: Used for rust_executable targets.
|
||||
# `rust_test_ldflags`: Used for rust_test targets; includes the test harness.
|
||||
# `ldflags_bin` : Used for rust_executable targets.
|
||||
# `ldflags_test`: Used for rust_test targets; includes the test harness.
|
||||
#
|
||||
# The tool works by compiling and linking something with rustc, and analyzing
|
||||
# the arguments it passes to the system linker. That's what dummy.rs is for.
|
||||
dummy_rs_path = rebase_path("dummy.rs", root_build_dir)
|
||||
rust_bin_ldflags =
|
||||
exec_script("get_rust_ldflags.py", [ dummy_rs_path ], "list lines")
|
||||
rust_test_ldflags = exec_script("get_rust_ldflags.py",
|
||||
[
|
||||
dummy_rs_path,
|
||||
"--test",
|
||||
],
|
||||
"list lines")
|
||||
_rustc_info = exec_script("get_rustc_info.py", [], "json")
|
||||
|
||||
template("rust_crate") {
|
||||
config_name = "${target_name}_config"
|
||||
|
@ -184,7 +176,10 @@ template("rust_crate") {
|
|||
|
||||
# This is to disambiguate multiple versions of the same crate.
|
||||
"-Cextra-filename=$crate_suffix",
|
||||
"-Cmetadata=$crate_suffix",
|
||||
|
||||
# Appending the rustc version to the crate metadata ensures that they are
|
||||
# rebuilt when rustc is upgraded, by changing the command line.
|
||||
"-Cmetadata=\"${crate_suffix}_${_rustc_info.version}\"",
|
||||
|
||||
# This is needed for transitive dependencies.
|
||||
"-L",
|
||||
|
@ -244,9 +239,9 @@ template("rust_executable") {
|
|||
forward_variables_from(invoker, "*")
|
||||
|
||||
if (defined(is_test) && is_test) {
|
||||
ldflags = rust_test_ldflags
|
||||
ldflags = _rustc_info.ldflags_test
|
||||
} else {
|
||||
ldflags = rust_bin_ldflags
|
||||
ldflags = _rustc_info.ldflags_bin
|
||||
}
|
||||
|
||||
if (!defined(deps)) {
|
||||
|
|
Loading…
Reference in a new issue