mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -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
|
# this script then reads the linker arguments from that temporary file, and
|
||||||
# then filters it to remove flags that are irrelevant or undesirable.
|
# then filters it to remove flags that are irrelevant or undesirable.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
import re
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
def capture_args(argsfile_path):
|
def capture_linker_args(argsfile_path):
|
||||||
with open(argsfile_path, "wb") as argsfile:
|
with open(argsfile_path, "wb") as argsfile:
|
||||||
argsfile.write("\n".join(sys.argv[1:]))
|
argsfile.write("\n".join(sys.argv[1:]))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def get_ldflags(rustc_args):
|
||||||
# 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)
|
|
||||||
|
|
||||||
# Prepare the environment for rustc.
|
# Prepare the environment for rustc.
|
||||||
rustc_env = os.environ.copy()
|
rustc_env = os.environ.copy()
|
||||||
|
|
||||||
|
@ -80,12 +73,13 @@ def main():
|
||||||
# Build the rustc command line.
|
# Build the rustc command line.
|
||||||
# * `-Clinker=` tells rustc to use our fake linker.
|
# * `-Clinker=` tells rustc to use our fake linker.
|
||||||
# * `-Csave-temps` prevents rustc from deleting object files after
|
# * `-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_cmd = [
|
||||||
"rustc",
|
"rustc",
|
||||||
"-Clinker=" + rustc_linker,
|
"-Clinker=" + rustc_linker,
|
||||||
"-Csave-temps",
|
"-Csave-temps",
|
||||||
] + sys.argv[1:]
|
] + rustc_args
|
||||||
|
|
||||||
# Spawn the rust compiler.
|
# Spawn the rust compiler.
|
||||||
rustc_proc = subprocess.Popen(
|
rustc_proc = subprocess.Popen(
|
||||||
|
@ -143,13 +137,16 @@ def main():
|
||||||
elif arg.endswith(".rlib"):
|
elif arg.endswith(".rlib"):
|
||||||
# Built-in Rust library, e.g. `libstd-8524caae8408aac2.rlib`.
|
# Built-in Rust library, e.g. `libstd-8524caae8408aac2.rlib`.
|
||||||
pass
|
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
|
# This file is needed because it contains certain allocator
|
||||||
# related symbols (e.g. `__rust_alloc`, `__rust_oom`).
|
# related symbols (e.g. `__rust_alloc`, `__rust_oom`).
|
||||||
# The Rust compiler normally generates this file just before
|
# The Rust compiler normally generates this file just before
|
||||||
# linking an executable. We pass `-Csave-temps` to rustc so it
|
# linking an executable. We pass `-Csave-temps` to rustc so it
|
||||||
# doesn't delete the file when it's done linking.
|
# doesn't delete the file when it's done linking.
|
||||||
pass
|
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"):
|
elif arg.endswith(".lib") and not arg.startswith("msvcrt"):
|
||||||
# Include most Windows static/import libraries (e.g. `ws2_32.lib`).
|
# Include most Windows static/import libraries (e.g. `ws2_32.lib`).
|
||||||
# However we ignore Rusts choice of C runtime (`mvcrt*.lib`).
|
# However we ignore Rusts choice of C runtime (`mvcrt*.lib`).
|
||||||
|
@ -172,8 +169,34 @@ def main():
|
||||||
|
|
||||||
ldflags += [arg]
|
ldflags += [arg]
|
||||||
|
|
||||||
# Write the filtered ldflags to stdout, separated by newline characters.
|
return ldflags
|
||||||
sys.stdout.write("\n".join(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__':
|
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
|
# * To sidestep rustc weirdness (e.g. on Windows, it always links with the
|
||||||
# release C runtime library, even for debug builds).
|
# 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.
|
# successfully link rustc object code into an executable.
|
||||||
# We generate two sets of ldflags:
|
# We generate two sets of ldflags:
|
||||||
# `rust_bin_ldflags`: Used for rust_executable targets.
|
# `ldflags_bin` : Used for rust_executable targets.
|
||||||
# `rust_test_ldflags`: Used for rust_test targets; includes the test harness.
|
# `ldflags_test`: Used for rust_test targets; includes the test harness.
|
||||||
#
|
#
|
||||||
# The tool works by compiling and linking something with rustc, and analyzing
|
# 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.
|
# 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)
|
_rustc_info = exec_script("get_rustc_info.py", [], "json")
|
||||||
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")
|
|
||||||
|
|
||||||
template("rust_crate") {
|
template("rust_crate") {
|
||||||
config_name = "${target_name}_config"
|
config_name = "${target_name}_config"
|
||||||
|
@ -184,7 +176,10 @@ template("rust_crate") {
|
||||||
|
|
||||||
# This is to disambiguate multiple versions of the same crate.
|
# This is to disambiguate multiple versions of the same crate.
|
||||||
"-Cextra-filename=$crate_suffix",
|
"-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.
|
# This is needed for transitive dependencies.
|
||||||
"-L",
|
"-L",
|
||||||
|
@ -244,9 +239,9 @@ template("rust_executable") {
|
||||||
forward_variables_from(invoker, "*")
|
forward_variables_from(invoker, "*")
|
||||||
|
|
||||||
if (defined(is_test) && is_test) {
|
if (defined(is_test) && is_test) {
|
||||||
ldflags = rust_test_ldflags
|
ldflags = _rustc_info.ldflags_test
|
||||||
} else {
|
} else {
|
||||||
ldflags = rust_bin_ldflags
|
ldflags = _rustc_info.ldflags_bin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defined(deps)) {
|
if (!defined(deps)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue