Bug 1838354 - Change how the rust workspace hack is added. r=firefox-build-system-reviewers,webdriver-reviewers,ahochheiden,whimboo

First, instead of using a path, use a version, which is more convenient
(via a patch in the top-level Cargo.toml).

Second, we make the build system itself enforce its presence for any
crate that is hooked to the build system as a program or library.

Finally, for each crate depending on the workspace hack, we add a
feature named after it, and make the build system enforce that the
feature is set. For now, this remains unused, but the end goal is to
have each of those features enable the dependencies each of these
crates need, so that if crate A and B need dependency D, but crate C
doesn't, building crate C doesn't build D.

Differential Revision: https://phabricator.services.mozilla.com/D180910
This commit is contained in:
Mike Hommey 2023-06-21 07:31:44 +00:00
Родитель 880f30b1d8
Коммит 39ed3add07
40 изменённых файлов: 202 добавлений и 23 удалений

7
Cargo.lock сгенерированный
Просмотреть файл

@ -558,6 +558,7 @@ name = "builtins-static"
version = "0.1.0"
dependencies = [
"bindgen 0.64.0",
"mozilla-central-workspace-hack",
"nom",
"pkcs11-bindings",
"smallvec",
@ -1972,6 +1973,7 @@ dependencies = [
"log",
"marionette",
"mozdevice",
"mozilla-central-workspace-hack",
"mozprofile",
"mozrunner",
"mozversion",
@ -2059,6 +2061,7 @@ dependencies = [
"lmdb-rkv-sys",
"moz_task-gtest",
"mozglue-static",
"mozilla-central-workspace-hack",
"mp4parse-gtest",
"nsstring-gtest",
"swgl",
@ -2481,6 +2484,7 @@ dependencies = [
"log",
"mio 0.6.23",
"mio-extras",
"mozilla-central-workspace-hack",
"neqo-common",
"neqo-crypto",
"neqo-http3",
@ -2639,6 +2643,7 @@ name = "ipcclientcerts-static"
version = "0.1.0"
dependencies = [
"byteorder",
"mozilla-central-workspace-hack",
"pkcs11-bindings",
"rsclientcerts",
"sha2",
@ -2773,6 +2778,7 @@ version = "0.1.0"
dependencies = [
"jsrust_shared",
"mozglue-static",
"mozilla-central-workspace-hack",
"wast",
]
@ -2784,7 +2790,6 @@ dependencies = [
"encoding_c_mem",
"gluesmith",
"mozglue-static",
"mozilla-central-workspace-hack",
"smoosh",
]

Просмотреть файл

@ -96,6 +96,9 @@ vcpkg = { path = "build/rust/vcpkg" }
# Helper crate for integration in the gecko build system.
mozbuild = { path = "build/rust/mozbuild" }
# Workspace hack
mozilla-central-workspace-hack = { path = "build/workspace-hack" }
# Dummy oslog replacement. It's only used by glean in code that is not actually used.
oslog = { path = "build/rust/oslog" }

Просмотреть файл

@ -116,3 +116,15 @@ features = [
"wtypes",
"wtypesbase",
]
[features]
builtins-static = []
defaultagent-static = []
geckodriver = []
gkrust = []
gkrust-gtest = []
http3server = []
ipcclientcerts-static = []
jsrust = []
mozwer_s = []
osclientcerts-static = []

Просмотреть файл

@ -420,9 +420,7 @@ endif
ifdef RUST_LIBRARY_FILE
ifdef RUST_LIBRARY_FEATURES
rust_features_flag := --features '$(RUST_LIBRARY_FEATURES)'
endif
rust_features_flag := --features '$(if $(RUST_LIBRARY_FEATURES),$(RUST_LIBRARY_FEATURES) )mozilla-central-workspace-hack'
ifeq (WASI,$(OS_ARCH))
# The rust wasi target defaults to statically link the wasi crt, but when we
@ -488,9 +486,7 @@ ifdef RUST_TESTS
rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
ifdef RUST_TEST_FEATURES
rust_test_features_flag := --features '$(RUST_TEST_FEATURES)'
endif
rust_test_features_flag := --features '$(if $(RUST_TEST_FEATURES),$(RUST_TEST_FEATURES) )mozilla-central-workspace-hack'
# Don't stop at the first failure. We want to list all failures together.
rust_test_flag := --no-fail-fast
@ -502,9 +498,7 @@ endif # RUST_TESTS
ifdef HOST_RUST_LIBRARY_FILE
ifdef HOST_RUST_LIBRARY_FEATURES
host_rust_features_flag := --features '$(HOST_RUST_LIBRARY_FEATURES)'
endif
host_rust_features_flag := --features '$(if $(HOST_RUST_LIBRARY_FEATURES),$(HOST_RUST_LIBRARY_FEATURES) )mozilla-central-workspace-hack'
force-cargo-host-library-build:
$(REPORT_BUILD)
@ -527,9 +521,11 @@ endif # HOST_RUST_LIBRARY_FILE
ifdef RUST_PROGRAMS
program_features_flag := --features mozilla-central-workspace-hack
force-cargo-program-build: $(call resfile,module)
$(REPORT_BUILD)
$(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) -- $(addprefix -C link-arg=$(CURDIR)/,$(call resfile,module)) $(CARGO_RUSTCFLAGS)
$(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) $(program_features_flag) -- $(addprefix -C link-arg=$(CURDIR)/,$(call resfile,module)) $(CARGO_RUSTCFLAGS)
# RUST_PROGRAM_DEPENDENCIES(RUST_PROGRAM)
# Generates a rule suitable to rebuild RUST_PROGRAM only if its dependencies are
@ -556,7 +552,7 @@ $(foreach RUST_PROGRAM,$(RUST_PROGRAMS), $(eval $(call RUST_PROGRAM_DEPENDENCIES
ifndef CARGO_NO_AUTO_ARG
force-cargo-program-%:
$(call RUN_CARGO,$*) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
$(call RUN_CARGO,$*) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) $(program_features_flag)
else
force-cargo-program-%:
$(call RUN_CARGO,$*)
@ -568,16 +564,18 @@ force-cargo-program-%:
endif # RUST_PROGRAMS
ifdef HOST_RUST_PROGRAMS
host_program_features_flag := --features mozilla-central-workspace-hack
force-cargo-host-program-build:
$(REPORT_BUILD)
$(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
$(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) $(host_program_features_flag)
$(HOST_RUST_PROGRAMS): force-cargo-host-program-build ;
ifndef CARGO_NO_AUTO_ARG
force-cargo-host-program-%:
$(REPORT_BUILD)
$(call RUN_CARGO,$*) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
$(call RUN_CARGO,$*) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag) $(host_program_features_flag)
else
force-cargo-host-program-%:
$(call RUN_CARGO,$*) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(filter-out --release $(cargo_target_flag))

Просмотреть файл

@ -16,6 +16,7 @@ smoosh = ['jsrust_shared/smoosh']
gluesmith = ['jsrust_shared/gluesmith']
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["jsrust"], optional = true }
jsrust_shared = { path = "./shared" }
# Workaround for https://github.com/rust-lang/rust/issues/58393
mozglue-static = { path = "../../../mozglue/static/rust" }

Просмотреть файл

@ -13,7 +13,6 @@ path = "lib.rs"
encoding_c = "0.9.5"
encoding_c_mem = "0.2.4"
smoosh = { path = "../../frontend/smoosh", optional = true }
mozilla-central-workspace-hack = { path = "../../../../build/workspace-hack" }
mozglue-static = { path = "../../../../mozglue/static/rust" }
gluesmith = { path = "../../fuzz-tests/gluesmith", optional = true }

Просмотреть файл

@ -18,6 +18,7 @@ cfg-if = "1.0"
http = "0.2.8"
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["rt-multi-thread"] }
mozilla-central-workspace-hack = { version = "0.1", features = ["http3server"], optional = true }
[dependencies.neqo-crypto]
tag = "v0.6.4"

Просмотреть файл

@ -507,7 +507,7 @@ class TreeMetadataEmitter(LoggingMixin):
else:
return ExternalSharedLibrary(context, name)
def _parse_cargo_file(self, context):
def _parse_and_check_cargo_file(self, context):
"""Parse the Cargo.toml file in context and return a Python object
representation of it. Raise a SandboxValidationError if the Cargo.toml
file does not exist. Return a tuple of (config, cargo_file)."""
@ -517,7 +517,38 @@ class TreeMetadataEmitter(LoggingMixin):
"No Cargo.toml file found in %s" % cargo_file, context
)
with open(cargo_file, "r") as f:
return toml.load(f), cargo_file
content = toml.load(f)
crate_name = content.get("package", {}).get("name")
if not crate_name:
raise SandboxValidationError(
f"{cargo_file} doesn't contain a crate name?!?", context
)
hack_name = "mozilla-central-workspace-hack"
dep = f'{hack_name} = {{ version = "0.1", features = ["{crate_name}"], optional = true }}'
dep_dict = toml.loads(dep)[hack_name]
hint = (
"\n\nYou may also need to adjust the build/workspace-hack/Cargo.toml"
f" file to add the {crate_name} feature."
)
workspace_hack = content.get("dependencies", {}).get(hack_name)
if not workspace_hack:
raise SandboxValidationError(
f"{cargo_file} doesn't contain the workspace hack.\n\n"
f"Add the following to dependencies:\n{dep}{hint}",
context,
)
if workspace_hack != dep_dict:
raise SandboxValidationError(
f"{cargo_file} needs an update to its {hack_name} dependency.\n\n"
f"Adjust the dependency to:\n{dep}{hint}",
context,
)
return content, cargo_file
def _verify_deps(
self, context, crate_dir, crate_name, dependencies, description="Dependency"
@ -562,7 +593,7 @@ class TreeMetadataEmitter(LoggingMixin):
self, context, libname, static_args, is_gkrust=False, cls=RustLibrary
):
# We need to note any Rust library for linking purposes.
config, cargo_file = self._parse_cargo_file(context)
config, cargo_file = self._parse_and_check_cargo_file(context)
crate_name = config["package"]["name"]
if crate_name != libname:
@ -660,7 +691,7 @@ class TreeMetadataEmitter(LoggingMixin):
# Verify Rust program definitions.
if all_rust_programs:
config, cargo_file = self._parse_cargo_file(context)
config, cargo_file = self._parse_and_check_cargo_file(context)
bin_section = config.get("bin", None)
if not bin_section:
raise SandboxValidationError(

Просмотреть файл

@ -11,3 +11,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["hostrusttool"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["hostrusttool"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["feature-library"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["test-library"], optional = true }

Просмотреть файл

@ -8,3 +8,6 @@ name = "target"
[[bin]]
name = "host"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["testing"], optional = true }

Просмотреть файл

@ -10,6 +10,7 @@ crate-type = ["staticlib"]
[dependencies]
deep-crate = { version = "0.1.0", path = "the/depths" }
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }
[profile.dev]
panic = "abort"

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["host-lib"], optional = true }

Просмотреть файл

@ -5,3 +5,6 @@ version = "0.0.1"
[[bin]]
name = "some"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["testing"], optional = true }

Просмотреть файл

@ -5,3 +5,6 @@ version = "0.0.1"
[[bin]]
name = "some"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["testing"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["rust1"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["rust2"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }

Просмотреть файл

@ -13,3 +13,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }

Просмотреть файл

@ -10,3 +10,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["deterministic-crate"], optional = true }

Просмотреть файл

@ -10,3 +10,6 @@ panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["random-crate"], optional = true }

Просмотреть файл

@ -0,0 +1,15 @@
[package]
name = "random-crate"
version = "0.1.0"
authors = [
"The Mozilla Project Developers",
]
[lib]
crate-type = ["staticlib"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

Просмотреть файл

@ -0,0 +1,9 @@
@template
def RustLibrary(name):
"""Template for Rust libraries."""
LIBRARY_NAME = name
IS_RUST_LIBRARY = True
RustLibrary("random-crate")

Просмотреть файл

@ -0,0 +1,18 @@
[package]
name = "random-crate"
version = "0.1.0"
authors = [
"The Mozilla Project Developers",
]
[lib]
crate-type = ["staticlib"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
[dependencies]
mozilla-central-workspace-hack = { path = "../../../../../../../build/workspace-hack" }

Просмотреть файл

@ -0,0 +1,9 @@
@template
def RustLibrary(name):
"""Template for Rust libraries."""
LIBRARY_NAME = name
IS_RUST_LIBRARY = True
RustLibrary("random-crate")

Просмотреть файл

@ -5,3 +5,6 @@ version = "0.0.1"
[[bin]]
name = "some"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["testing"], optional = true }

Просмотреть файл

@ -5,3 +5,6 @@ version = "0.0.1"
[[bin]]
name = "some"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["testing"], optional = true }

Просмотреть файл

@ -1803,6 +1803,24 @@ class TestEmitterBasic(unittest.TestCase):
self.assertIsInstance(host_cflags, ComputedFlags)
self.assertIsInstance(lib, RustLibrary)
def test_missing_workspace_hack(self):
"""Test detection of a missing workspace hack."""
reader = self.reader("rust-no-workspace-hack")
with six.assertRaisesRegex(
self, SandboxValidationError, "doesn't contain the workspace hack"
):
self.read_topsrcdir(reader)
def test_old_workspace_hack(self):
"""Test detection of an old workspace hack."""
reader = self.reader("rust-old-workspace-hack")
with six.assertRaisesRegex(
self,
SandboxValidationError,
"needs an update to its mozilla-central-workspace-hack dependency",
):
self.read_topsrcdir(reader)
def test_install_shared_lib(self):
"""Test that we can install a shared library with TEST_HARNESS_FILES"""
reader = self.reader("test-install-shared-lib")

Просмотреть файл

@ -8,6 +8,7 @@ license = "MPL-2.0"
[dependencies]
pkcs11-bindings = "0.1.1"
smallvec = { version = "1.9.0", features = ["const_new"] }
mozilla-central-workspace-hack = { version = "0.1", features = ["builtins-static"], optional = true }
[build-dependencies]
bindgen = { default-features = false, features = ["runtime"], version = "0.64" }

Просмотреть файл

@ -10,6 +10,7 @@ byteorder = "1.3"
pkcs11-bindings = "0.1"
rsclientcerts = { path = "../rsclientcerts" }
sha2 = "0.10.2"
mozilla-central-workspace-hack = { version = "0.1", features = ["ipcclientcerts-static"], optional = true }
[lib]
crate-type = ["staticlib"]

Просмотреть файл

@ -12,7 +12,8 @@ byteorder = "1.3"
env_logger = {version = "0.10", default-features = false } # disable `regex` to reduce code size
lazy_static = "1"
log = "0.4"
mozilla-central-workspace-hack = { path = "../../../../build/workspace-hack" }
mozilla-central-workspace-hack = { version = "0.1", features = ["osclientcerts-static"], optional = true }
pkcs11-bindings = "0.1"
rsclientcerts = { path = "../rsclientcerts" }
sha2 = "0.10.2"

Просмотреть файл

@ -43,6 +43,7 @@ url = "2.0"
uuid = { version = "1.0", features = ["v4"] }
webdriver = { path = "../webdriver", version="0.48.0" }
zip = { version = "0.6", default-features = false, features = ["deflate"] }
mozilla-central-workspace-hack = { version = "0.1", features = ["geckodriver"], optional = true }
[dev-dependencies]
tempfile = "3"

Просмотреть файл

@ -7,7 +7,7 @@ license = "MPL-2.0"
[dependencies]
libc = "0.2.0"
mozilla-central-workspace-hack = { path = "../../../build/workspace-hack" }
mozilla-central-workspace-hack = { version = "0.1", features = ["mozwer_s"], optional = true }
rust-ini = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }

Просмотреть файл

@ -6,6 +6,7 @@ license = "MPL-2.0"
description = "Testing code for libgkrust"
[dependencies]
mozilla-central-workspace-hack = { version = "0.1", features = ["gkrust-gtest"], optional = true }
bench-collections-gtest = { path = "../../../../xpcom/rust/gtest/bench-collections" }
l10nregistry-ffi-gtest = { path = "../../../../intl/l10n/rust/gtest" }
moz_task-gtest = { path = "../../../../xpcom/rust/gtest/moz_task" }

Просмотреть файл

@ -7,7 +7,7 @@ description = "Rust code for libxul"
[dependencies]
gkrust-shared = { path = "shared" }
mozilla-central-workspace-hack = { path = "../../../build/workspace-hack" }
mozilla-central-workspace-hack = { version = "0.1", features = ["gkrust"], optional = true }
# Workarounds for https://github.com/rust-lang/rust/issues/58393
mozglue-static = { path = "../../../mozglue/static/rust" }

Просмотреть файл

@ -9,7 +9,7 @@ license = "MPL-2.0"
[dependencies]
log = { version = "0.4", features = ["std"] }
mozilla-central-workspace-hack = { path = "../../../../build/workspace-hack" }
mozilla-central-workspace-hack = { version = "0.1", features = ["defaultagent-static"], optional = true }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"