wasm-builder: Improve workspace handling (#10700)

When building a wasm binary from a different repo inside a local workspace, we did not used the
correct `Cargo.toml` to find the correct patches and features. The solution to this is to just walk
up from the target directory until we find the workspace we are currently compiling. If this
heuristic isn't working, we print a warning and let the user set an env variable
`WASM_BUILD_WORKSPACE_HINT` to tell the `wasm-builder` where the actual workspace is.
This commit is contained in:
Bastian Köcher
2022-01-21 17:43:21 +01:00
committed by GitHub
parent e1cc9c2d5b
commit f41ef340e5
2 changed files with 33 additions and 6 deletions
+7
View File
@@ -83,6 +83,10 @@
//! needs to be absolute.
//! - `WASM_BUILD_TOOLCHAIN` - The toolchain that should be used to build the Wasm binaries. The
//! format needs to be the same as used by cargo, e.g. `nightly-2020-02-20`.
//! - `WASM_BUILD_WORKSPACE_HINT` - Hint the workspace that is being built. This is normally not
//! required as we walk up from the target directory until we find a `Cargo.toml`. If the target
//! directory is changed for the build, this environment variable can be used to point to the
//! actual workspace.
//!
//! Each project can be skipped individually by using the environment variable
//! `SKIP_PROJECT_NAME_WASM_BUILD`. Where `PROJECT_NAME` needs to be replaced by the name of the
@@ -138,6 +142,9 @@ const WASM_BUILD_TOOLCHAIN: &str = "WASM_BUILD_TOOLCHAIN";
/// Environment variable that makes sure the WASM build is triggered.
const FORCE_WASM_BUILD_ENV: &str = "FORCE_WASM_BUILD";
/// Environment variable that hints the workspace we are building.
const WASM_BUILD_WORKSPACE_HINT: &str = "WASM_BUILD_WORKSPACE_HINT";
/// Write to the given `file` if the `content` is different.
fn write_file_if_changed(file: impl AsRef<Path>, content: impl AsRef<str>) {
if fs::read_to_string(file.as_ref()).ok().as_deref() != Some(content.as_ref()) {
@@ -77,6 +77,15 @@ fn crate_metadata(cargo_manifest: &Path) -> Metadata {
let cargo_lock_existed = cargo_lock.exists();
// If we can find a `Cargo.lock`, we assume that this is the workspace root and there exists a
// `Cargo.toml` that we can use for getting the metadata.
let cargo_manifest = if let Some(mut cargo_lock) = find_cargo_lock(cargo_manifest) {
cargo_lock.set_file_name("Cargo.toml");
cargo_lock
} else {
cargo_manifest.to_path_buf()
};
let crate_metadata = MetadataCommand::new()
.manifest_path(cargo_manifest)
.exec()
@@ -151,18 +160,29 @@ fn find_cargo_lock(cargo_manifest: &Path) -> Option<PathBuf> {
}
}
if let Ok(workspace) = env::var(crate::WASM_BUILD_WORKSPACE_HINT) {
let path = PathBuf::from(workspace);
if path.join("Cargo.lock").exists() {
return Some(path.join("Cargo.lock"))
} else {
build_helper::warning!(
"`{}` env variable doesn't point to a directory that contains a `Cargo.lock`.",
crate::WASM_BUILD_WORKSPACE_HINT,
);
}
}
if let Some(path) = find_impl(build_helper::out_dir()) {
return Some(path)
}
if let Some(path) = find_impl(cargo_manifest.to_path_buf()) {
return Some(path)
}
build_helper::warning!(
"Could not find `Cargo.lock` for `{}`, while searching from `{}`.",
"Could not find `Cargo.lock` for `{}`, while searching from `{}`. \
To fix this, point the `{}` env variable to the directory of the workspace being compiled.",
cargo_manifest.display(),
build_helper::out_dir().display()
build_helper::out_dir().display(),
crate::WASM_BUILD_WORKSPACE_HINT,
);
None