Set up to build Rust code with dependencies
cargo-raze is like gazelle, but for Rust code. It generates BUILD files
for external dependencies.
I'm putting this in a separate change from running it and setting up CI
to do that for ease of telling what's generated vs not.
Change-Id: I87a07255dca475514cae7bdbf9b0b62ce46e2512
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..4d31a6d
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,120 @@
+# A fake Cargo.toml for cargo-raze. This will not work well if you try actually
+# running cargo.
+#
+# cargo-raze generates BUILD files etc for all dependencies listed here and in the workspace
+# members. Hand-written BUILD files can then depend on the corresponding targets that they need.
+#
+# To generate BUILD files from this:
+# ```console
+# $ bazel run @cargo_raze//:raze -- --manifest-path=$(realpath Cargo.toml) --generate-lockfile
+# ```
+# To remove unnecessary redundant BUILD files afterwards:
+# ```console
+# $ bazel run //tools/rust:tweak_cargo_raze_output -- $(readlink -f .)
+# ```
+#
+# # Generated targets
+# //third_party/cargo has forwarding targets for the individual crates. Don't
+# reference the repositories by name, because those change when they're
+# upgraded. If you need to access another target, set `extra_aliased_targets`
+# for the crate.
+#
+# See here for what you can set in the package.metadata.raze sections:
+# https://github.com/google/cargo-raze/blob/main/impl/src/settings.rs
+[package]
+name = "compile_with_bazel"
+version = "0.0.0"
+
+# Mandatory (or Cargo tooling is unhappy)
+[lib]
+path = "fake_lib.rs"
+
+[workspace]
+members = [
+ "third_party/autocxx",
+ "third_party/autocxx/engine",
+ "third_party/autocxx/parser",
+ "third_party/autocxx/gen/cmd",
+ "third_party/autocxx/macro",
+ "third_party/autocxx/integration-tests",
+ "third_party/flatbuffers/rust/flatbuffers",
+]
+
+[dependencies]
+cxx = "1.0"
+cxxbridge-macro = "1.0"
+cxxbridge-cmd = "1.0"
+uuid = "1.0"
+toml = "0.5"
+anyhow = "1.0"
+
+# For bindgen.
+bindgen = "0.58.1"
+libloading = "=0.6.3"
+
+# Bazel toolchains take care of linking the C++ standard library, so don't add
+# an extra flag via Rust by enabling the `nothing` feature. I'm not even sure
+# it would end up on the link command line, but this crate's build.rs attempts
+# to find a C++ compiler itself otherwise which definitely doesn't work.
+link-cplusplus = { version = "1.0", features = ["nothing"] }
+
+[package.metadata.raze.binary_deps]
+# Needed if we want to generate BUILD files for autocxx-gen.
+#autocxx-gen = "0.16.0"
+
+[workspace.metadata.raze]
+# `cargo raze` will generate Bazel-compatible BUILD files into this path.
+workspace_path = "//third_party/cargo"
+
+# Put the aliases in the same package as the BUILD files.
+package_aliases_dir = "third_party/cargo"
+
+# The set of targets to generate BUILD rules for.
+targets = [
+ "x86_64-unknown-linux-gnu",
+ "arm-unknown-linux-gnueabi",
+ "armv7-unknown-linux-gnueabihf",
+ "aarch64-unknown-linux-gnueabi",
+]
+
+# Reference crates by URL, instead of vendoring them all.
+genmode = "Remote"
+
+# TODO(Brian): This isn't great for being hermetic or repeatable, but it is the
+# default. A lot of the problematic crates probably have pre-written versions
+# which avoid build.rs in cargo-raze itself or elsewhere. rules_rust is another
+# place to look.
+# https://github.com/bazelbuild/rules_rust/blob/main/bindgen/raze/Cargo.toml
+default_gen_buildrs = true
+
+[package.metadata.raze.crates.cxx.'*']
+gen_buildrs = false
+additional_build_file = "third_party/cargo/cxx/include.BUILD.bazel"
+extra_aliased_targets = ["cxx_cc"]
+
+[package.metadata.raze.crates.cxxbridge-cmd.'*']
+compile_data_attr = "[\"src/gen/include/cxx.h\"]"
+extra_aliased_targets = ["cargo_bin_cxxbridge"]
+
+[package.metadata.raze.crates.cxx-gen.'*']
+compile_data_attr = "[\"src/gen/include/cxx.h\"]"
+
+[package.metadata.raze.crates.supports-hyperlinks.'*']
+compile_data_attr = "[\"README.md\"]"
+
+[package.metadata.raze.crates.supports-unicode.'*']
+compile_data_attr = "[\"README.md\"]"
+
+[package.metadata.raze.crates.autocxx.'*']
+compile_data_attr = "[\"README.md\"]"
+
+[package.metadata.raze.crates.autocxx-gen.'*']
+extra_aliased_targets = ["cargo_bin_autocxx_gen"]
+
+[package.metadata.raze.crates.bindgen.'*']
+extra_aliased_targets = ["cargo_bin_bindgen"]
+
+[package.metadata.raze.crates.log.'*']
+additional_flags = [
+ "--cfg=atomic_cas",
+]
diff --git a/WORKSPACE b/WORKSPACE
index df7ed47..50aad8c 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1182,3 +1182,31 @@
sha256 = "cf4dfcf71e20a60406aaded03a165312c1ca535b509ead90eb1846fc598137d2",
urls = ["https://github.com/foxglove/mcap/releases/download/releases%2Fmcap-cli%2Fv0.0.5/mcap-linux-amd64"],
)
+
+http_archive(
+ name = "cargo_raze",
+ patches = ["@//third_party/cargo_raze:cargo_raze.patch"],
+ sha256 = "08bfc8859ff686ecb55005a3c4a9cf790115de0abdbcc69cf57b15be0745a859",
+ strip_prefix = "cargo-raze-0.14.2",
+ url = "https://github.com/google/cargo-raze/archive/v0.14.2.tar.gz",
+)
+
+http_archive(
+ name = "rules_foreign_cc",
+ patch_args = ["-p1"],
+ patches = ["@//third_party/rules_foreign_cc:backport_d93bd96dc719760c968b54730258ad0a5b10f8fb.patch"],
+ sha256 = "69023642d5781c68911beda769f91fcbc8ca48711db935a75da7f6536b65047f",
+ strip_prefix = "rules_foreign_cc-0.6.0",
+ url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.6.0.tar.gz",
+)
+
+load("@cargo_raze//:repositories.bzl", "cargo_raze_repositories")
+
+cargo_raze_repositories()
+
+# cargo_raze_transitive_deps wants to do `rust_repositories`, which we do
+# manually to get the right platforms. rules_foreign_cc is currently the only
+# other thing it has, so just do that manually.
+load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
+
+rules_foreign_cc_dependencies()
diff --git a/third_party/autocxx/Cargo.toml b/third_party/autocxx/Cargo.toml
index 5c24af8..7d34f78 100644
--- a/third_party/autocxx/Cargo.toml
+++ b/third_party/autocxx/Cargo.toml
@@ -30,10 +30,6 @@
aquamarine = "0.1" # docs
moveit = { version = "0.5", features = [ "cxx" ] }
-[workspace]
-members = ["parser", "engine", "gen/cmd", "gen/build", "macro", "demo", "tools/reduce", "tools/mdbook-preprocessor", "integration-tests"]
-exclude = ["examples/s2", "examples/steam-mini", "examples/subclass", "examples/chromium-fake-render-frame-host", "examples/pod", "examples/non-trivial-type-on-stack", "examples/llvm", "tools/stress-test"]
-
#[patch.crates-io]
#cxx = { path="../cxx" }
#cxx-gen = { path="../cxx/gen/lib" }
diff --git a/third_party/bazel-toolchain/toolchain/BUILD.llvm_repo b/third_party/bazel-toolchain/toolchain/BUILD.llvm_repo
index 9920705..c0dbadf 100644
--- a/third_party/bazel-toolchain/toolchain/BUILD.llvm_repo
+++ b/third_party/bazel-toolchain/toolchain/BUILD.llvm_repo
@@ -124,3 +124,8 @@
name = "strip",
srcs = ["bin/llvm-strip"],
)
+
+filegroup(
+ name = "libclang",
+ srcs = ["lib/libclang.so"],
+)
diff --git a/third_party/cargo/BUILD.bazel b/third_party/cargo/BUILD.bazel
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/cargo/BUILD.bazel
diff --git a/third_party/cargo/README.md b/third_party/cargo/README.md
new file mode 100644
index 0000000..b6e78f3
--- /dev/null
+++ b/third_party/cargo/README.md
@@ -0,0 +1,5 @@
+This folder is largely generated by cargo-raze, based on configuration in
+`//:Cargo.toml`. See there for details.
+
+Hand-written files referenced by `//:Cargo.toml` are stored in subfolders for
+each crate they are used with.
diff --git a/third_party/cargo/cxx/include.BUILD.bazel b/third_party/cargo/cxx/include.BUILD.bazel
new file mode 100644
index 0000000..f6b9f5a
--- /dev/null
+++ b/third_party/cargo/cxx/include.BUILD.bazel
@@ -0,0 +1,9 @@
+# This file is included in the BUILD for the cxx crate, to export its header
+# file for C++ code to depend on.
+cc_library(
+ name = "cxx_cc",
+ visibility = ["//visibility:public"],
+ hdrs = ["include/cxx.h"],
+ srcs = ["src/cxx.cc"],
+ includes = ["include"],
+)
diff --git a/third_party/cargo_raze/BUILD b/third_party/cargo_raze/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/cargo_raze/BUILD
diff --git a/third_party/cargo_raze/cargo_raze.patch b/third_party/cargo_raze/cargo_raze.patch
new file mode 100644
index 0000000..54cd9d5
--- /dev/null
+++ b/third_party/cargo_raze/cargo_raze.patch
@@ -0,0 +1,184 @@
+--- tools/BUILD.bazel 2022-02-03 01:20:57.060271436 -0800
++++ tools/BUILD.bazel 2022-02-03 01:21:14.321056806 -0800
+@@ -43,24 +43,12 @@ sh_binary(
+
+ alias(
+ name = "cargo",
+- actual = select({
+- "@rules_rust//rust/platform:aarch64-apple-darwin": "@rust_darwin_aarch64//:cargo",
+- "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": "@rust_linux_aarch64//:cargo",
+- "@rules_rust//rust/platform:x86_64-apple-darwin": "@rust_darwin_x86_64//:cargo",
+- "@rules_rust//rust/platform:x86_64-pc-windows-msvc": "@rust_windows_x86_64//:cargo",
+- "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": "@rust_linux_x86_64//:cargo",
+- }),
++ actual = "@rust//:cargo",
+ )
+
+ alias(
+ name = "rustc",
+- actual = select({
+- "@rules_rust//rust/platform:aarch64-apple-darwin": "@rust_darwin_aarch64//:rustc",
+- "@rules_rust//rust/platform:aarch64-unknown-linux-gnu": "@rust_linux_aarch64//:rustc",
+- "@rules_rust//rust/platform:x86_64-apple-darwin": "@rust_darwin_x86_64//:rustc",
+- "@rules_rust//rust/platform:x86_64-pc-windows-msvc": "@rust_windows_x86_64//:rustc",
+- "@rules_rust//rust/platform:x86_64-unknown-linux-gnu": "@rust_linux_x86_64//:rustc",
+- }),
++ actual = "@rust//:rustc",
+ )
+
+ sh_binary(
+
+--- third_party/zlib/BUILD.zlib.bazel 2022-02-03 01:26:46.756187851 -0800
++++ third_party/zlib/BUILD.zlib.bazel 2022-02-03 01:26:58.048702010 -0800
+@@ -58,6 +58,8 @@ cc_library(
+ "//conditions:default": [
+ "-Wno-unused-variable",
+ "-Wno-implicit-function-declaration",
++ "-Wno-cast-qual",
++ "-Wno-format-nonliteral",
+ ],
+ }),
+ includes = ["zlib/include/"],
+@@ -28,6 +28,7 @@ genrule(
+ srcs = _ZLIB_HEADERS,
+ outs = _ZLIB_PREFIXED_HEADERS,
+ cmd = "cp $(SRCS) $(@D)/zlib/include/",
++ visibility = ["//visibility:public"],
+ )
+
+ cc_library(
+
+--- third_party/pcre/BUILD.pcre.bazel 2022-02-03 01:29:12.830839568 -0800
++++ third_party/pcre/BUILD.pcre.bazel 2022-02-03 01:29:25.187402321 -0800
+@@ -10,7 +10,14 @@ filegroup(
+ cmake(
+ name = "pcre",
+ cache_entries = {
+- "CMAKE_C_FLAGS": "-fPIC",
++ "CMAKE_C_FLAGS": "-fPIC -DHAVE_STRERROR=1 -Wno-unused -Wno-unused-parameter -Wunused-command-line-argument -Wno-cast-qual -Wno-self-assign -Wno-cast-align -Wno-incompatible-pointer-types-discards-qualifiers",
++ "CMAKE_CXX_FLAGS": "-fPIC -DHAVE_STRERROR=1 -Wno-unused -Wno-unused-parameter -Wno-unused-command-line-argument",
++ "CMAKE_EXE_LINKER_FLAGS": "-Wno-unused-command-line-argument",
++ "PCRE_SUPPORT_LIBREADLINE": "off",
++ "PCRE_BUILD_TESTS": "off",
+ },
++ deps = [
++ "@cargo_raze__zlib//:zlib",
++ ],
+ lib_source = ":all",
+ out_static_libs = ["libpcre.a"],
+
+--- third_party/openssl/BUILD.openssl.bazel 2022-02-03 23:31:09.601309219 -0800
++++ third_party/openssl/BUILD.openssl.bazel 2022-02-03 23:33:16.123104901 -0800
+@@ -41,6 +41,14 @@ configure_make(
+ "libssl.a",
+ "libcrypto.a",
+ ],
++ copts = [
++ "-Wno-unused-parameter",
++ "-Wno-format-nonliteral",
++ "-Wno-incompatible-pointer-types-discards-qualifiers",
++ "-Wno-missing-field-initializers",
++ "-Wno-cast-qual",
++ "-Wno-cast-align",
++ ],
+ targets = [
+ "build_libs",
+ "install_dev",
+
+--- third_party/libssh2/BUILD.libssh2.bazel 2022-02-04 00:03:43.831120614 -0800
++++ third_party/libssh2/BUILD.libssh2.bazel 2022-02-04 00:04:19.100745883 -0800
+@@ -29,6 +29,14 @@ cmake(
+ "@rules_rust//rust/platform:windows": ["ssh2.lib"],
+ "//conditions:default": ["libssh2.a"],
+ }),
++ copts = [
++ "-Wno-cast-qual",
++ "-Wno-sizeof-array-div",
++ "-Wno-unused-parameter",
++ "-DHAVE_SNPRINTF=1",
++ "-DHAVE_SYS_UIO_H=1",
++ "-DHAVE_SYS_SOCKET_H=1",
++ ],
+ visibility = ["//visibility:public"],
+ deps = ["@cargo_raze__openssl//:openssl"],
+ )
+
+--- third_party/libgit2/BUILD.libgit2.bazel 2022-02-04 00:13:21.681725240 -0800
++++ third_party/libgit2/BUILD.libgit2.bazel 2022-02-04 00:13:58.599423312 -0800
+@@ -39,6 +39,13 @@ cmake(
+ "@rules_rust//rust/platform:windows": ["git2.lib"],
+ "//conditions:default": ["libgit2.a"],
+ }),
++ copts = [
++ "-Wno-unused-command-line-argument",
++ "-Wno-cast-qual",
++ "-Wno-cast-align",
++ "-Wno-incompatible-pointer-types-discards-qualifiers",
++ "-Wno-format-nonliteral",
++ ],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@cargo_raze__libssh2//:libssh2",
+
+--- impl/Cargo.toml 2022-02-04 00:44:15.679153957 -0800
++++ impl/Cargo.toml 2022-02-04 00:44:17.799251382 -0800
+@@ -113,6 +113,7 @@ additional_deps = ["@cargo_raze__libssh2
+ # build.rs file: https://github.com/rust-lang/libz-sys/blob/main/build.rs
+ gen_buildrs = false
+ additional_flags = ["--cfg=static"]
++additional_deps = ["@cargo_raze__zlib//:zlib"]
+
+ [package.metadata.raze.crates.openssl.'*']
+ additional_deps = ["@cargo_raze__openssl//:openssl"]
+@@ -106,6 +106,7 @@ additional_deps = ["@cargo_raze__libgit2
+ build_data_dependencies = [
+ "@cargo_raze__libssh2//:libssh2",
+ "@cargo_raze__openssl//:openssl",
++ "@cargo_raze__zlib//:copy_public_headers",
+ ]
+ additional_deps = ["@cargo_raze__libssh2//:libssh2"]
+
+
+--- third_party/cargo/remote/BUILD.libz-sys-1.1.2.bazel 2022-02-04 00:45:43.779201978 -0800
++++ third_party/cargo/remote/BUILD.libz-sys-1.1.2.bazel 2022-02-04 00:45:57.151816346 -0800
+@@ -57,6 +57,7 @@ rust_library(
+ # buildifier: leave-alone
+ deps = [
+ "@cargo_raze__libc__0_2_92//:libc",
++ "@cargo_raze__zlib//:zlib",
+ ] + selects.with_or({
+ # cfg(target_env = "msvc")
+ (
+
+--- third_party/cargo/remote/BUILD.libssh2-sys-0.2.21.bazel 2022-02-04 00:54:43.031966734 -0800
++++ third_party/cargo/remote/BUILD.libssh2-sys-0.2.21.bazel 2022-02-04 00:54:44.272023742 -0800
+@@ -41,6 +41,8 @@ cargo_build_script(
+ name = "libssh2_sys_build_script",
+ srcs = glob(["**/*.rs"]),
+ build_script_env = {
++ # TODO: Custom rule that does the copy and exports a Make variable with the folder?
++ "DEP_Z_INCLUDE": "${pwd}/bazel-out/k8-fastbuild/bin/external/cargo_raze__zlib/zlib/include",
+ },
+ crate_features = [
+ ],
+@@ -48,6 +48,7 @@ cargo_build_script(
+ data = glob(["**"]) + [
+ "@cargo_raze__libssh2//:libssh2",
+ "@cargo_raze__openssl//:openssl",
++ "@cargo_raze__zlib//:copy_public_headers",
+ ],
+ edition = "2015",
+ links = "ssh2",
+
+--- impl/src/util.rs 2022-02-06 17:53:29.535707368 -0800
++++ impl/src/util.rs 2022-02-06 17:55:22.513000536 -0800
+@@ -40,6 +40,8 @@ static SUPPORTED_PLATFORM_TRIPLES: &[&st
+ "aarch64-linux-android",
+ "aarch64-unknown-linux-gnu",
+ "arm-unknown-linux-gnueabi",
++ "armv7-unknown-linux-gnueabi",
++ "armv7-unknown-linux-gnueabihf",
+ "i686-linux-android",
+ "i686-unknown-freebsd",
+ "powerpc-unknown-linux-gnu",
+
diff --git a/third_party/rules_foreign_cc/BUILD b/third_party/rules_foreign_cc/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/third_party/rules_foreign_cc/BUILD
diff --git a/third_party/rules_foreign_cc/backport_d93bd96dc719760c968b54730258ad0a5b10f8fb.patch b/third_party/rules_foreign_cc/backport_d93bd96dc719760c968b54730258ad0a5b10f8fb.patch
new file mode 100644
index 0000000..7659456
--- /dev/null
+++ b/third_party/rules_foreign_cc/backport_d93bd96dc719760c968b54730258ad0a5b10f8fb.patch
@@ -0,0 +1,82 @@
+From d93bd96dc719760c968b54730258ad0a5b10f8fb Mon Sep 17 00:00:00 2001
+From: Fabian Meumertzheim <meumertzheim@code-intelligence.com>
+Date: Tue, 5 Oct 2021 16:07:10 +0200
+Subject: [PATCH] Add flags from copts and linkopts attributes (#796)
+
+---
+ foreign_cc/private/cc_toolchain_util.bzl | 6 +++---
+ test/standard_cxx_flags_test/BUILD.bazel | 6 +++++-
+ test/standard_cxx_flags_test/tests.bzl | 16 ++++++++++++++++
+ 3 files changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/foreign_cc/private/cc_toolchain_util.bzl b/foreign_cc/private/cc_toolchain_util.bzl
+index 9842d8c2c..6843750d7 100644
+--- a/foreign_cc/private/cc_toolchain_util.bzl
++++ b/foreign_cc/private/cc_toolchain_util.bzl
+@@ -301,9 +301,9 @@ def get_flags_info(ctx, link_output_file = None):
+ cc_toolchain = cc_toolchain_,
+ )
+
+- copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts) or []
+- cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts) or []
+- linkopts = ctx.fragments.cpp.linkopts or []
++ copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + ctx.attr.copts) or []
++ cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + ctx.attr.copts) or []
++ linkopts = (ctx.fragments.cpp.linkopts + ctx.attr.linkopts) or []
+ defines = _defines_from_deps(ctx)
+
+ flags = CxxFlagsInfo(
+diff --git a/test/standard_cxx_flags_test/BUILD.bazel b/test/standard_cxx_flags_test/BUILD.bazel
+index fa41a521f..799e73c5a 100644
+--- a/test/standard_cxx_flags_test/BUILD.bazel
++++ b/test/standard_cxx_flags_test/BUILD.bazel
+@@ -1,3 +1,7 @@
+ load(":tests.bzl", "flags_test")
+
+-flags_test(name = "flags_test")
++flags_test(
++ name = "flags_test",
++ copts = ["-fblah4"],
++ linkopts = ["-fblah5"],
++)
+diff --git a/test/standard_cxx_flags_test/tests.bzl b/test/standard_cxx_flags_test/tests.bzl
+index 7da3aedc3..11c2d67a9 100644
+--- a/test/standard_cxx_flags_test/tests.bzl
++++ b/test/standard_cxx_flags_test/tests.bzl
+@@ -10,12 +10,26 @@ def _impl(ctx):
+
+ assert_contains_once(flags.cc, "-fblah0")
+ assert_contains_once(flags.cc, "-fblah2")
++ assert_contains_once(flags.cc, "-fblah4")
++ if "-fblah5" in flags.cc:
++ fail("C flags should not contain '-fblah5'")
+
+ assert_contains_once(flags.cxx, "-fblah0")
+ assert_contains_once(flags.cxx, "-fblah1")
++ assert_contains_once(flags.cxx, "-fblah4")
++ if "-fblah5" in flags.cxx:
++ fail("C++ flags should not contain '-fblah5'")
+
+ assert_contains_once(flags.cxx_linker_executable, "-fblah3")
++ assert_contains_once(flags.cxx_linker_executable, "-fblah5")
++ if "-fblah4" in flags.cxx_linker_executable:
++ fail("Executable linker flags should not contain '-fblah4'")
++
+ assert_contains_once(flags.cxx_linker_shared, "-fblah3")
++ assert_contains_once(flags.cxx_linker_shared, "-fblah5")
++ if "-fblah4" in flags.cxx_linker_shared:
++ fail("Shared linker flags should not contain '-fblah4'")
++
+ if "-fblah3" in flags.cxx_linker_static:
+ fail("Static linker flags should not contain '-fblah3'")
+
+@@ -44,7 +58,9 @@ def assert_contains_once(arr, value):
+ _flags_test = rule(
+ implementation = _impl,
+ attrs = {
++ "copts": attr.string_list(),
+ "deps": attr.label_list(),
++ "linkopts": attr.string_list(),
+ "out": attr.output(),
+ "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
+ },
diff --git a/tools/rust/BUILD b/tools/rust/BUILD
index e58bb19..fccc3e4 100644
--- a/tools/rust/BUILD
+++ b/tools/rust/BUILD
@@ -119,3 +119,16 @@
toolchain = ":noop_rust_toolchain_impl",
toolchain_type = "@rules_rust//rust:toolchain",
)
+
+'''
+# TODO(Brian): Uncomment in the next change once dependencies exist.
+rust_binary(
+ name = "tweak_cargo_raze_output",
+ srcs = ["tweak_cargo_raze_output.rs"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//third_party/cargo:anyhow",
+ "//third_party/cargo:toml",
+ ],
+)
+'''
diff --git a/tools/rust/tweak_cargo_raze_output.rs b/tools/rust/tweak_cargo_raze_output.rs
new file mode 100644
index 0000000..88a9d0a
--- /dev/null
+++ b/tools/rust/tweak_cargo_raze_output.rs
@@ -0,0 +1,102 @@
+//! A tool that postprocesses cargo-raze output to do what we want.
+//!
+//! Currently this is limited to removing extraneous BUILD files which cargo-raze places in all the
+//! third_party packages we feed to it, which we don't want to use. We're hand-writing BUILD files
+//! for these dependencies, without intending them to be used as separate Bazel workspaces, so it's
+//! easiest for them to all reference the top-level //third_party/cargo package.
+use std::{
+ env, fs,
+ io::{self, ErrorKind},
+ path::Path,
+};
+
+use anyhow::Context;
+use toml::Value;
+
+fn filter_not_found(result: io::Result<()>) -> io::Result<()> {
+ match result {
+ Err(e) if matches!(e.kind(), ErrorKind::NotFound) => Ok(()),
+ r => r,
+ }
+}
+
+fn main() -> anyhow::Result<()> {
+ let argv: Vec<_> = env::args().collect();
+ let workspace_path = Path::new(&argv[1]);
+ let cargo_toml_path = workspace_path.join("Cargo.toml");
+ eprintln!("Loading Cargo.toml from {:?}", cargo_toml_path);
+ let cargo_toml_contents = fs::read(&cargo_toml_path)
+ .with_context(|| format!("Failed to read Cargo.toml: {:?}", cargo_toml_path))?;
+ let cargo_toml_contents = std::str::from_utf8(&cargo_toml_contents).with_context(|| {
+ format!(
+ "Failed to interpret Cargo.toml contents as UTF-8: {:?}",
+ cargo_toml_path
+ )
+ })?;
+ let cargo_toml: Value = cargo_toml_contents
+ .parse()
+ .with_context(|| format!("Failed to parse Cargo.toml contents: {:?}", cargo_toml_path))?;
+
+ let package_aliases_dir = cargo_toml["workspace"]["metadata"]["raze"]["package_aliases_dir"]
+ .as_str()
+ .with_context(|| {
+ format!(
+ "Found non-string package_aliases_dir in Cargo.toml: {:?}",
+ cargo_toml_path
+ )
+ })?;
+
+ let workspace_members = cargo_toml["workspace"]["members"]
+ .as_array()
+ .with_context(|| {
+ format!(
+ "Did not find workspace members in Cargo.toml: {:?}",
+ cargo_toml_path
+ )
+ })?;
+ for member in workspace_members.iter() {
+ let member = member.as_str().with_context(|| {
+ format!(
+ "Found non-string workspace member in Cargo.toml: {:?}",
+ cargo_toml_path
+ )
+ })?;
+
+ // First delete the BUILD file.
+ let member_build = workspace_path
+ .join(member)
+ .join(package_aliases_dir)
+ .join("BUILD.bazel");
+ filter_not_found(fs::remove_file(&member_build)).with_context(|| {
+ format!(
+ "Failed to remove workspace member BUILD.bazel: {:?}",
+ member_build
+ )
+ })?;
+
+ // Then go and delete each folder in reverse order, but only if it's now empty to avoid
+ // overeager deletion. The file we're deleting should be the only thing in these folders,
+ // but if somebody wrote something else for some reason then we don't want to silently
+ // delete it.
+ let mut folder_path = workspace_path.join(member);
+ for d in Path::new(package_aliases_dir)
+ .components()
+ .scan(&mut folder_path, |a, b| {
+ **a = a.join(b);
+ Some(a.clone())
+ })
+ .collect::<Vec<_>>()
+ .iter()
+ .rev()
+ {
+ filter_not_found(fs::remove_dir(d)).with_context(|| {
+ format!(
+ "Failed to remove workspace member package_aliases directory: {:?}",
+ d
+ )
+ })?;
+ }
+ }
+ eprintln!("All done");
+ Ok(())
+}