Skip to content

Commit

Permalink
Add support for passing a custom target specification. (#836)
Browse files Browse the repository at this point in the history
* Add support for passing a custom target specification.

* Pass the target spec ias a dependency.

* Created a target_flag_value toolchain info field to avoid recalculating the value.

* Prevent passing both target_triple and target_json simultaneously.

* Streamline checks for None.

* Added unit tests for rust_toolchain rules.

* Rename test target spec to avoid collisions with the builtin.

* Regenerate documentation

* Rename the triple used in unit tests.

Co-authored-by: UebelAndre <github@uebelandre.com>
Co-authored-by: Marcel Hlopko <hlopko@google.com>
  • Loading branch information
3 people committed Jul 22, 2021
1 parent 4da6858 commit 37982c5
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 5 deletions.
4 changes: 2 additions & 2 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def _build_script_impl(ctx):
# This isn't exactly right, but Bazel doesn't have exact views of "debug" and "release", so...
"PROFILE": {"dbg": "debug", "fastbuild": "debug", "opt": "release"}.get(ctx.var["COMPILATION_MODE"], "unknown"),
"RUSTC": toolchain.rustc.path,
"TARGET": toolchain.target_triple,
"TARGET": toolchain.target_flag_value,
# OUT_DIR is set by the runner itself, rather than on the action.
})

Expand Down Expand Up @@ -129,7 +129,7 @@ def _build_script_impl(ctx):
script,
ctx.executable._cargo_build_script_runner,
toolchain.rustc,
] + ctx.files.data,
] + ctx.files.data + ([toolchain.target_json] if toolchain.target_json else []),
transitive = toolchain_tools,
)

Expand Down
4 changes: 3 additions & 1 deletion docs/flatten.md
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,8 @@ Run the test with `bazel build //hello_lib:hello_lib_test`.
<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>, <a href="#rust_toolchain-rustc">rustc</a>,
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -1153,6 +1154,7 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-rustfmt"></a>rustfmt | The location of the <code>rustfmt</code> binary. Can be a direct source or a filegroup containing one item. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_toolchain-staticlib_ext"></a>staticlib_ext | The extension for static libraries created from rustc. | String | required | |
| <a id="rust_toolchain-stdlib_linkflags"></a>stdlib_linkflags | Additional linker libs used when std lib is linked, see https://github.com/rust-lang/rust/blob/master/src/libstd/build.rs | List of strings | required | |
| <a id="rust_toolchain-target_json"></a>target_json | Override the target_triple with a custom target specification. For more details see: https://doc.rust-lang.org/rustc/targets/custom.html | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_toolchain-target_triple"></a>target_triple | The platform triple for the toolchains target environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | optional | "" |


Expand Down
4 changes: 3 additions & 1 deletion docs/rust_repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ A dedicated filegroup-like rule for Rust stdlib artifacts.
<pre>
rust_toolchain(<a href="#rust_toolchain-name">name</a>, <a href="#rust_toolchain-allocator_library">allocator_library</a>, <a href="#rust_toolchain-binary_ext">binary_ext</a>, <a href="#rust_toolchain-cargo">cargo</a>, <a href="#rust_toolchain-clippy_driver">clippy_driver</a>, <a href="#rust_toolchain-debug_info">debug_info</a>,
<a href="#rust_toolchain-default_edition">default_edition</a>, <a href="#rust_toolchain-dylib_ext">dylib_ext</a>, <a href="#rust_toolchain-exec_triple">exec_triple</a>, <a href="#rust_toolchain-opt_level">opt_level</a>, <a href="#rust_toolchain-os">os</a>, <a href="#rust_toolchain-rust_doc">rust_doc</a>, <a href="#rust_toolchain-rust_lib">rust_lib</a>, <a href="#rust_toolchain-rustc">rustc</a>,
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_triple">target_triple</a>)
<a href="#rust_toolchain-rustc_lib">rustc_lib</a>, <a href="#rust_toolchain-rustc_srcs">rustc_srcs</a>, <a href="#rust_toolchain-rustfmt">rustfmt</a>, <a href="#rust_toolchain-staticlib_ext">staticlib_ext</a>, <a href="#rust_toolchain-stdlib_linkflags">stdlib_linkflags</a>, <a href="#rust_toolchain-target_json">target_json</a>,
<a href="#rust_toolchain-target_triple">target_triple</a>)
</pre>

Declares a Rust toolchain for use.
Expand Down Expand Up @@ -102,6 +103,7 @@ See @rules_rust//rust:repositories.bzl for examples of defining the @rust_cpuX r
| <a id="rust_toolchain-rustfmt"></a>rustfmt | The location of the <code>rustfmt</code> binary. Can be a direct source or a filegroup containing one item. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_toolchain-staticlib_ext"></a>staticlib_ext | The extension for static libraries created from rustc. | String | required | |
| <a id="rust_toolchain-stdlib_linkflags"></a>stdlib_linkflags | Additional linker libs used when std lib is linked, see https://github.com/rust-lang/rust/blob/master/src/libstd/build.rs | List of strings | required | |
| <a id="rust_toolchain-target_json"></a>target_json | Override the target_triple with a custom target specification. For more details see: https://doc.rust-lang.org/rustc/targets/custom.html | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_toolchain-target_triple"></a>target_triple | The platform triple for the toolchains target environment. For more details see: https://docs.bazel.build/versions/master/skylark/rules.html#configurations | String | optional | "" |


Expand Down
3 changes: 2 additions & 1 deletion rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def collect_inputs(
[toolchain.rustc] +
toolchain.crosstool_files +
([build_info.rustc_env, build_info.flags] if build_info else []) +
([toolchain.target_json] if toolchain.target_json else []) +
([] if linker_script == None else [linker_script]),
transitive = [
toolchain.rustc_lib.files,
Expand Down Expand Up @@ -430,7 +431,7 @@ def construct_arguments(

args.add("--emit=" + ",".join(emit_with_paths))
args.add("--color=always")
args.add("--target=" + toolchain.target_triple)
args.add("--target=" + toolchain.target_flag_value)
if hasattr(attr, "crate_features"):
args.add_all(getattr(attr, "crate_features"), before_each = "--cfg", format_each = 'feature="%s"')
if linker_script:
Expand Down
10 changes: 10 additions & 0 deletions rust/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,17 @@ def _rust_toolchain_impl(ctx):
if not k in ctx.attr.opt_level:
fail("Compilation mode {} is not defined in opt_level but is defined debug_info".format(k))

if ctx.attr.target_triple and ctx.file.target_json:
fail("Do not specify both target_triple and target_json, either use a builtin triple or provide a custom specification file.")

toolchain = platform_common.ToolchainInfo(
rustc = ctx.file.rustc,
rust_doc = ctx.file.rust_doc,
rustfmt = ctx.file.rustfmt,
cargo = ctx.file.cargo,
clippy_driver = ctx.file.clippy_driver,
target_json = ctx.file.target_json,
target_flag_value = ctx.file.target_json.path if ctx.file.target_json else ctx.attr.target_triple,
rustc_lib = ctx.attr.rustc_lib,
rustc_srcs = ctx.attr.rustc_srcs,
rust_lib = ctx.attr.rust_lib,
Expand Down Expand Up @@ -305,6 +310,11 @@ rust_toolchain = rule(
),
mandatory = True,
),
"target_json": attr.label(
doc = ("Override the target_triple with a custom target specification. " +
"For more details see: https://doc.rust-lang.org/rustc/targets/custom.html"),
allow_single_file = True,
),
"target_triple": attr.string(
doc = (
"The platform triple for the toolchains target environment. " +
Expand Down
3 changes: 3 additions & 0 deletions test/unit/toolchain/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load(":toolchain_test.bzl", "toolchain_test_suite")

toolchain_test_suite(name = "toolchain_test_suite")
34 changes: 34 additions & 0 deletions test/unit/toolchain/toolchain-test-triple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"arch": "x86_64",
"cpu": "x86-64",
"crt-static-respected": true,
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"env": "gnu",
"executables": true,
"has-elf-tls": true,
"has-rpath": true,
"llvm-target": "x86_64-unknown-linux-gnu",
"max-atomic-width": 64,
"os": "linux",
"position-independent-executables": true,
"pre-link-args": {
"gcc": [
"-m64"
]
},
"relro-level": "full",
"stack-probes": {
"kind": "call"
},
"supported-sanitizers": [
"address",
"leak",
"memory",
"thread"
],
"target-family": [
"unix"
],
"target-pointer-width": "64"
}
80 changes: 80 additions & 0 deletions test/unit/toolchain/toolchain_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""Unit tests for rust toolchains."""

load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//rust:toolchain.bzl", "rust_stdlib_filegroup", "rust_toolchain")

def _toolchain_specifies_target_triple_test_impl(ctx):
env = analysistest.begin(ctx)
toolchain_info = analysistest.target_under_test(env)[platform_common.ToolchainInfo]

asserts.equals(env, None, toolchain_info.target_json)
asserts.equals(env, "toolchain-test-triple", toolchain_info.target_flag_value)
asserts.equals(env, "toolchain-test-triple", toolchain_info.target_triple)

return analysistest.end(env)

def _toolchain_specifies_target_json_test_impl(ctx):
env = analysistest.begin(ctx)
toolchain_info = analysistest.target_under_test(env)[platform_common.ToolchainInfo]

asserts.equals(env, "toolchain-test-triple.json", toolchain_info.target_json.basename)
asserts.equals(env, "test/unit/toolchain/toolchain-test-triple.json", toolchain_info.target_flag_value)
asserts.equals(env, "", toolchain_info.target_triple)

return analysistest.end(env)

toolchain_specifies_target_triple_test = analysistest.make(_toolchain_specifies_target_triple_test_impl)
toolchain_specifies_target_json_test = analysistest.make(_toolchain_specifies_target_json_test_impl)

def _toolchain_test():
rust_stdlib_filegroup(
name = "std_libs",
srcs = [],
)

native.filegroup(
name = "target_json",
srcs = ["toolchain-test-triple.json"],
)

rust_toolchain(
name = "rust_triple_toolchain",
binary_ext = "",
dylib_ext = ".so",
os = "linux",
rust_lib = ":std_libs",
staticlib_ext = ".a",
stdlib_linkflags = [],
target_triple = "toolchain-test-triple",
)

rust_toolchain(
name = "rust_json_toolchain",
binary_ext = "",
dylib_ext = ".so",
os = "linux",
rust_lib = ":std_libs",
staticlib_ext = ".a",
stdlib_linkflags = [],
target_json = ":target_json",
)

toolchain_specifies_target_triple_test(
name = "toolchain_specifies_target_triple_test",
target_under_test = ":rust_triple_toolchain",
)
toolchain_specifies_target_json_test(
name = "toolchain_specifies_target_json_test",
target_under_test = ":rust_json_toolchain",
)

def toolchain_test_suite(name):
_toolchain_test()

native.test_suite(
name = name,
tests = [
":toolchain_specifies_target_triple_test",
":toolchain_specifies_target_json_test",
],
)

0 comments on commit 37982c5

Please sign in to comment.