From 9247e150ca0f50841a60a213ad8b15efdbd616fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 21 Jan 2022 17:43:21 +0100 Subject: [PATCH] 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. --- utils/wasm-builder/src/lib.rs | 7 ++++++ utils/wasm-builder/src/wasm_project.rs | 30 +++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 899903d96d169..f5e04dd7d774b 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -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, content: impl AsRef) { if fs::read_to_string(file.as_ref()).ok().as_deref() != Some(content.as_ref()) { diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index cf437ee7f0e6c..809a940c74068 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -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 { } } - if let Some(path) = find_impl(build_helper::out_dir()) { - return Some(path) + 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(cargo_manifest.to_path_buf()) { + if let Some(path) = find_impl(build_helper::out_dir()) { 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