Skip to content

Generated rust-project.json files now include sysroot paths #1641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/flatten.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ A rule defining an incompatible flag.
## rust_analyzer_toolchain

<pre>
rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-proc_macro_srv">proc_macro_srv</a>, <a href="#rust_analyzer_toolchain-rustc">rustc</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
</pre>

A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
Expand All @@ -215,6 +215,8 @@ A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="rust_analyzer_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="rust_analyzer_toolchain-proc_macro_srv"></a>proc_macro_srv | The path to a <code>rust_analyzer_proc_macro_srv</code> binary. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_analyzer_toolchain-rustc"></a>rustc | The path to a <code>rustc</code> binary. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="rust_analyzer_toolchain-rustc_srcs"></a>rustc_srcs | The source code of rustc. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |


Expand Down Expand Up @@ -1264,7 +1266,7 @@ A given instance of this rule should be accompanied by a toolchain_repository_pr
| <a id="rust_toolchain_tools_repository-repo_mapping"></a>repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.&lt;p&gt;For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>). | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required | |
| <a id="rust_toolchain_tools_repository-rustfmt_version"></a>rustfmt_version | The version of the tool among "nightly", "beta", or an exact version. | String | optional | "" |
| <a id="rust_toolchain_tools_repository-sha256s"></a>sha256s | A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_toolchain_tools_repository-target_triple"></a>target_triple | The Rust-style target that this compiler builds for | String | required | |
| <a id="rust_toolchain_tools_repository-target_triple"></a>target_triple | The Rust-style target that this compiler builds for. | String | required | |
| <a id="rust_toolchain_tools_repository-urls"></a>urls | A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format). | List of strings | optional | ["https://static.rust-lang.org/dist/{}.tar.gz"] |
| <a id="rust_toolchain_tools_repository-version"></a>version | The version of the tool among "nightly", "beta", or an exact version. | String | required | |

Expand Down
4 changes: 3 additions & 1 deletion docs/rust_analyzer.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ to ensure a `rust-project.json` file is created and up to date when the editor i
## rust_analyzer_toolchain

<pre>
rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
rust_analyzer_toolchain(<a href="#rust_analyzer_toolchain-name">name</a>, <a href="#rust_analyzer_toolchain-proc_macro_srv">proc_macro_srv</a>, <a href="#rust_analyzer_toolchain-rustc">rustc</a>, <a href="#rust_analyzer_toolchain-rustc_srcs">rustc_srcs</a>)
</pre>

A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
Expand All @@ -95,6 +95,8 @@ A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="rust_analyzer_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="rust_analyzer_toolchain-proc_macro_srv"></a>proc_macro_srv | The path to a <code>rust_analyzer_proc_macro_srv</code> binary. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | optional | None |
| <a id="rust_analyzer_toolchain-rustc"></a>rustc | The path to a <code>rustc</code> binary. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="rust_analyzer_toolchain-rustc_srcs"></a>rustc_srcs | The source code of rustc. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |


Expand Down
2 changes: 1 addition & 1 deletion docs/rust_repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ A given instance of this rule should be accompanied by a toolchain_repository_pr
| <a id="rust_toolchain_tools_repository-repo_mapping"></a>repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.&lt;p&gt;For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>). | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required | |
| <a id="rust_toolchain_tools_repository-rustfmt_version"></a>rustfmt_version | The version of the tool among "nightly", "beta", or an exact version. | String | optional | "" |
| <a id="rust_toolchain_tools_repository-sha256s"></a>sha256s | A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="rust_toolchain_tools_repository-target_triple"></a>target_triple | The Rust-style target that this compiler builds for | String | required | |
| <a id="rust_toolchain_tools_repository-target_triple"></a>target_triple | The Rust-style target that this compiler builds for. | String | required | |
| <a id="rust_toolchain_tools_repository-urls"></a>urls | A list of mirror urls containing the tools from the Rust-lang static file server. These must contain the '{}' used to substitute the tool being fetched (using .format). | List of strings | optional | ["https://static.rust-lang.org/dist/{}.tar.gz"] |
| <a id="rust_toolchain_tools_repository-version"></a>version | The version of the tool among "nightly", "beta", or an exact version. | String | required | |

Expand Down
59 changes: 53 additions & 6 deletions rust/private/repository_utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,27 @@ filegroup(
)
"""

_build_file_for_rust_analyzer_proc_macro_srv = """\
filegroup(
name = "rust_analyzer_proc_macro_srv",
srcs = ["libexec/rust-analyzer-proc-macro-srv{binary_ext}"],
visibility = ["//visibility:public"],
)
"""

def BUILD_for_rust_analyzer_proc_macro_srv(exec_triple):
"""Emits a BUILD file the rust_analyzer_proc_macro_srv archive.

Args:
exec_triple (str): The triple of the exec platform
Returns:
str: The contents of a BUILD file
"""
system = triple_to_system(exec_triple)
return _build_file_for_rust_analyzer_proc_macro_srv.format(
binary_ext = system_to_binary_ext(system),
)

def BUILD_for_clippy(target_triple):
"""Emits a BUILD file the clippy archive.

Expand Down Expand Up @@ -342,24 +363,26 @@ def load_rustfmt(ctx):

return BUILD_for_rustfmt(target_triple)

def load_rust_compiler(ctx):
def load_rust_compiler(ctx, iso_date, target_triple, version):
"""Loads a rust compiler and yields corresponding BUILD for it

Args:
ctx (repository_ctx): A repository_ctx.
iso_date (str): The date of the tool (or None, if the version is a specific version).
target_triple (str): The Rust-style target that this compiler runs on.
version (str): The version of the tool among \"nightly\", \"beta\", or an exact version.

Returns:
str: The BUILD file contents for this compiler and compiler library
"""

target_triple = ctx.attr.exec_triple
load_arbitrary_tool(
ctx,
iso_date = ctx.attr.iso_date,
iso_date = iso_date,
target_triple = target_triple,
tool_name = "rustc",
tool_subdirectories = ["rustc"],
version = ctx.attr.version,
version = version,
)

return BUILD_for_compiler(target_triple)
Expand Down Expand Up @@ -408,8 +431,28 @@ def load_cargo(ctx):

return BUILD_for_cargo(target_triple)

def includes_rust_analyzer_proc_macro_srv(version, iso_date):
"""Determine whether or not the rust_analyzer_proc_macro_srv binary in available in the given version of Rust.

Args:
version (str): The version of the tool among \"nightly\", \"beta\", or an exact version.
iso_date (str): The date of the tool (or None, if the version is a specific version).

Returns:
bool: Whether or not the binary is expected to be included
"""

if version == "nightly":
return iso_date >= "2022-09-21"
elif version == "beta":
return False
elif version >= "1.64.0":
return True

return False

def should_include_rustc_srcs(repository_ctx):
"""Determing whether or not to include rustc sources in the toolchain.
"""Determine whether or not to include rustc sources in the toolchain.

Args:
repository_ctx (repository_ctx): The repository rule's context object
Expand Down Expand Up @@ -460,14 +503,18 @@ load("@rules_rust//rust:toolchain.bzl", "rust_analyzer_toolchain")

rust_analyzer_toolchain(
name = "{name}",
proc_macro_srv = {proc_macro_srv},
rustc = "{rustc}",
rustc_srcs = "//lib/rustlib/src:rustc_srcs",
visibility = ["//visibility:public"],
)
"""

def BUILD_for_rust_analyzer_toolchain(name):
def BUILD_for_rust_analyzer_toolchain(name, rustc, proc_macro_srv):
return _build_file_for_rust_analyzer_toolchain_template.format(
name = name,
rustc = rustc,
proc_macro_srv = repr(proc_macro_srv),
)

def load_rust_stdlib(ctx, target_triple):
Expand Down
40 changes: 36 additions & 4 deletions rust/private/rust_analyzer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ def _create_single_crate(ctx, info):

def _rust_analyzer_toolchain_impl(ctx):
toolchain = platform_common.ToolchainInfo(
proc_macro_srv = ctx.executable.proc_macro_srv,
rustc = ctx.executable.rustc,
rustc_srcs = ctx.attr.rustc_srcs,
)

Expand All @@ -222,6 +224,19 @@ rust_analyzer_toolchain = rule(
implementation = _rust_analyzer_toolchain_impl,
doc = "A toolchain for [rust-analyzer](https://rust-analyzer.github.io/).",
attrs = {
"proc_macro_srv": attr.label(
doc = "The path to a `rust_analyzer_proc_macro_srv` binary.",
cfg = "exec",
executable = True,
allow_single_file = True,
),
"rustc": attr.label(
doc = "The path to a `rustc` binary.",
cfg = "exec",
executable = True,
allow_single_file = True,
mandatory = True,
),
"rustc_srcs": attr.label(
doc = "The source code of rustc.",
mandatory = True,
Expand All @@ -245,13 +260,30 @@ def _rust_analyzer_detect_sysroot_impl(ctx):
if rustc_srcs.label.workspace_root:
sysroot_src = _OUTPUT_BASE_TEMPLATE + rustc_srcs.label.workspace_root + "/" + sysroot_src

sysroot_src_file = ctx.actions.declare_file(ctx.label.name + ".rust_analyzer_sysroot_src")
rustc = rust_analyzer_toolchain.rustc
sysroot_dir, _, bin_dir = rustc.dirname.rpartition("/")
if bin_dir != "bin":
fail("The rustc path is expected to be relative to the sysroot as `bin/rustc`. Instead got: {}".format(
rustc.path,
))

sysroot = "{}/{}".format(
_OUTPUT_BASE_TEMPLATE,
sysroot_dir,
)

toolchain_info = {
"sysroot": sysroot,
"sysroot_src": sysroot_src,
}

output = ctx.actions.declare_file(ctx.label.name + ".rust_analyzer_toolchain.json")
ctx.actions.write(
output = sysroot_src_file,
content = sysroot_src,
output = output,
content = json.encode_indent(toolchain_info, indent = " " * 4),
)

return [DefaultInfo(files = depset([sysroot_src_file]))]
return [DefaultInfo(files = depset([output]))]

rust_analyzer_detect_sysroot = rule(
implementation = _rust_analyzer_detect_sysroot_impl,
Expand Down
49 changes: 40 additions & 9 deletions rust/repositories.bzl
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
# buildifier: disable=module-docstring
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("//rust/platform:triple.bzl", "get_host_triple")
load(
"//rust/platform:triple_mappings.bzl",
"triple_to_constraint_set",
)
load("//rust/private:common.bzl", "rust_common")
load(
"//rust/private:repository_utils.bzl",
"BUILD_for_rust_analyzer_proc_macro_srv",
"BUILD_for_rust_analyzer_toolchain",
"BUILD_for_rust_toolchain",
"BUILD_for_toolchain",
"DEFAULT_STATIC_RUST_URL_TEMPLATES",
"check_version_valid",
"includes_rust_analyzer_proc_macro_srv",
"load_cargo",
"load_clippy",
"load_llvm_tools",
Expand Down Expand Up @@ -199,7 +202,12 @@ def _rust_toolchain_tools_repository_impl(ctx):
load_rust_src(ctx)

build_components = [
load_rust_compiler(ctx),
load_rust_compiler(
ctx = ctx,
iso_date = ctx.attr.iso_date,
target_triple = ctx.attr.exec_triple,
version = ctx.attr.version,
),
load_clippy(ctx),
load_cargo(ctx),
]
Expand Down Expand Up @@ -291,7 +299,7 @@ rust_toolchain_tools_repository = repository_rule(
doc = "A dict associating tool subdirectories to sha256 hashes. See [rust_repositories](#rust_repositories) for more details.",
),
"target_triple": attr.string(
doc = "The Rust-style target that this compiler builds for",
doc = "The Rust-style target that this compiler builds for.",
mandatory = True,
),
"urls": attr.string_list(
Expand Down Expand Up @@ -428,18 +436,41 @@ def rust_toolchain_repository(
name = name,
)

def _rust_analyzer_toolchain_srcs_repository_impl(repository_ctx):
def _rust_analyzer_toolchain_tools_repository_impl(repository_ctx):
load_rust_src(repository_ctx)

repository_ctx.file("WORKSPACE.bazel", """workspace(name = "{}")""".format(
repository_ctx.name,
))

repository_ctx.file("BUILD.bazel", BUILD_for_rust_analyzer_toolchain(
host_triple = get_host_triple(repository_ctx)
build_contents = [
load_rust_compiler(
ctx = repository_ctx,
iso_date = repository_ctx.attr.iso_date,
target_triple = host_triple.str,
version = repository_ctx.attr.version,
),
]
rustc = "//:rustc"

proc_macro_srv = None
if includes_rust_analyzer_proc_macro_srv(repository_ctx.attr.version, repository_ctx.attr.iso_date):
build_contents.append(BUILD_for_rust_analyzer_proc_macro_srv(host_triple.str))
proc_macro_srv = "//:rust_analyzer_proc_macro_srv"

build_contents.append(BUILD_for_rust_analyzer_toolchain(
name = "rust_analyzer_toolchain",
rustc = rustc,
proc_macro_srv = proc_macro_srv,
))

rust_analyzer_toolchain_srcs_repository = repository_rule(
repository_ctx.file("BUILD.bazel", "\n".join(build_contents))
repository_ctx.file("WORKSPACE.bazel", """workspace(name = "{}")""".format(
repository_ctx.name,
))

rust_analyzer_toolchain_tools_repository = repository_rule(
doc = "A repository rule for defining a rust_analyzer_toolchain with a `rust-src` artifact.",
attrs = {
"auth": attr.string_dict(
Expand All @@ -463,7 +494,7 @@ rust_analyzer_toolchain_srcs_repository = repository_rule(
mandatory = True,
),
},
implementation = _rust_analyzer_toolchain_srcs_repository_impl,
implementation = _rust_analyzer_toolchain_tools_repository_impl,
)

def rust_analyzer_toolchain_repository(
Expand Down Expand Up @@ -492,8 +523,8 @@ def rust_analyzer_toolchain_repository(
Returns:
str: The name of a registerable rust_analyzer_toolchain.
"""
rust_analyzer_toolchain_srcs_repository(
name = name + "_srcs",
rust_analyzer_toolchain_tools_repository(
name = name + "_tools",
version = version,
iso_date = iso_date,
sha256s = sha256s,
Expand All @@ -503,7 +534,7 @@ def rust_analyzer_toolchain_repository(

toolchain_repository_proxy(
name = name,
toolchain = "@{}//:{}".format(name + "_srcs", "rust_analyzer_toolchain"),
toolchain = "@{}//:{}".format(name + "_tools", "rust_analyzer_toolchain"),
toolchain_type = "@rules_rust//rust/rust_analyzer:toolchain_type",
exec_compatible_with = exec_compatible_with,
target_compatible_with = target_compatible_with,
Expand Down
15 changes: 10 additions & 5 deletions tools/rust_analyzer/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::path::Path;
use std::process::Command;

Expand Down Expand Up @@ -60,15 +61,19 @@ pub fn write_rust_project(
"" => SYSROOT_SRC_FILE_RUNFILES_PREFIX,
s => s,
};
let sysroot_path = format!(
"{}/rust/private/rust_analyzer_detect_sysroot.rust_analyzer_sysroot_src",
let toolchain_info_path = format!(
"{}/rust/private/rust_analyzer_detect_sysroot.rust_analyzer_toolchain.json",
workspace_name
);
let r = Runfiles::create()?;
let path = r.rlocation(sysroot_path);
let sysroot_src = std::fs::read_to_string(&path)?;
let path = r.rlocation(toolchain_info_path);
let toolchain_info: HashMap<String, String> =
serde_json::from_str(&std::fs::read_to_string(&path)?)?;

let rust_project = rust_project::generate_rust_project(&sysroot_src, &crate_specs)?;
let sysroot_src = &toolchain_info["sysroot_src"];
let sysroot = &toolchain_info["sysroot"];

let rust_project = rust_project::generate_rust_project(sysroot, sysroot_src, &crate_specs)?;

rust_project::write_rust_project(
rust_project_path.as_ref(),
Expand Down
Loading