From f9a541b5f93e66bc5e02c67ecd585d87fb1185cb Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Thu, 5 Oct 2017 09:37:04 +0800 Subject: [PATCH] Handle target specific outputs such as .wasm Fixes #4535 - Do not add metadata to wasm32 bin target because generated .js will refer corresponding .wasm. - Handle different usages of "-" and "_" in .js and .wasm file names. (e.g "foo-bar.js" vs. "foo_bar.wasm") - Change file mode of cargo_rustc/context.rs (100755 -> 100644) --- src/cargo/ops/cargo_rustc/context.rs | 42 ++++++++++++++++++++-------- tests/build.rs | 16 +++++------ 2 files changed, 39 insertions(+), 19 deletions(-) mode change 100755 => 100644 src/cargo/ops/cargo_rustc/context.rs diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs old mode 100755 new mode 100644 index 0ee0614a7..a502d70b9 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -463,6 +463,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // - OSX encodes the dylib name in the executable // - Windows rustc multiple files of which we can't easily link all of them // + // No metadata for bin because of an issue + // - wasm32 rustc/emcc encodes the .wasm name in the .js (rust-lang/cargo#4535) + // // Two exceptions // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict) // 2) __CARGO_DEFAULT_LIB_METADATA env var @@ -478,9 +481,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // doing this eventually. let __cargo_default_lib_metadata = env::var("__CARGO_DEFAULT_LIB_METADATA"); if !unit.profile.test && - (unit.target.is_dylib() || unit.target.is_cdylib()) && + (unit.target.is_dylib() || unit.target.is_cdylib() || + (unit.target.is_bin() && self.target_triple().starts_with("wasm32-"))) && unit.pkg.package_id().source_id().is_path() && - !__cargo_default_lib_metadata.is_ok() { + !__cargo_default_lib_metadata.is_ok() + { return None; } @@ -652,11 +657,21 @@ impl<'a, 'cfg> Context<'a, 'cfg> { suffix, linkable, ); - for (suffix, linkable) in suffixes { + for (suffix, linkable, should_replace_hyphens) in suffixes { + // wasm bin target will generate two files in deps such as + // "web-stuff.js" and "web_stuff.wasm". Note the different usages of + // "-" and "_". should_replace_hyphens is a flag to indicate that + // we need to convert the stem "web-stuff" to "web_stuff", so we + // won't miss "web_stuff.wasm". + let conv = |s: String| if should_replace_hyphens { + s.replace("-", "_") + } else { + s + }; let filename = - out_dir.join(format!("{}{}{}", prefix, stem, suffix)); + out_dir.join(format!("{}{}{}", prefix, conv(stem.clone()), suffix)); let link_dst = link_stem.clone().map(|(ld, ls)| { - ld.join(format!("{}{}{}", prefix, ls, suffix)) + ld.join(format!("{}{}{}", prefix, conv(ls), suffix)) }); ret.push((filename, link_dst, linkable)); } @@ -1174,27 +1189,32 @@ fn parse_crate_type( Ok(Some((prefix.to_string(), suffix.to_string()))) } +// (not a rustdoc) +// Return a list of 3-tuples (suffix, linkable, should_replace_hyphens). +// +// should_replace_hyphens will be used by the caller to replace "-" with "_" +// in a bin_stem. See the caller side (calc_target_filenames()) for details. fn add_target_specific_suffixes( target_triple: &str, crate_type: &str, suffix: &str, linkable: bool, -) -> Vec<(String, bool)> { - let mut suffixes = vec![(suffix.to_string(), linkable)]; +) -> Vec<(String, bool, bool)> { + let mut ret = vec![(suffix.to_string(), linkable, false)]; // rust-lang/cargo#4500 if target_triple.ends_with("pc-windows-msvc") && crate_type.ends_with("dylib") && suffix == ".dll" { - suffixes.push((format!("{}.lib", suffix), false)); + ret.push((".dll.lib".to_string(), false, false)); } // rust-lang/cargo#4535 - if target_triple == "wasm32-unknown-emscripten" && crate_type == "bin" && + if target_triple.starts_with("wasm32-") && crate_type == "bin" && suffix == ".js" { - suffixes.push((".wasm".to_string(), false)); + ret.push((".wasm".to_string(), false, true)); } - suffixes + ret } diff --git a/tests/build.rs b/tests/build.rs index 8105b913b..843795f72 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -3371,7 +3371,7 @@ fn cdylib_final_outputs() { let p = project("foo") .file("Cargo.toml", r#" [project] - name = "foo" + name = "foo-bar" authors = [] version = "0.1.0" @@ -3383,11 +3383,11 @@ fn cdylib_final_outputs() { assert_that(p.cargo_process("build"), execs().with_status(0)); let files = if cfg!(windows) { - vec!["foo.dll.lib", "foo.dll"] + vec!["foo_bar.dll.lib", "foo_bar.dll"] } else if cfg!(target_os = "macos") { - vec!["libfoo.dylib"] + vec!["libfoo_bar.dylib"] } else { - vec!["libfoo.so"] + vec!["libfoo_bar.so"] }; for file in files { @@ -3408,7 +3408,7 @@ fn wasm32_final_outputs() { let p = project("foo") .file("Cargo.toml", r#" [project] - name = "foo" + name = "foo-bar" authors = [] version = "0.1.0" "#) @@ -3449,11 +3449,11 @@ fn wasm32_final_outputs() { let pkgid = packages .package_ids() - .filter(|id| id.name() == "foo") + .filter(|id| id.name() == "foo-bar") .collect::>(); let pkg = packages.get(pkgid[0]).expect("Can't get package"); - let target = Target::bin_target("foo", p.root().join("src/main.rs"), None); + let target = Target::bin_target("foo-bar", p.root().join("src/main.rs"), None); let unit = Unit { pkg: &pkg, @@ -3478,7 +3478,7 @@ fn wasm32_final_outputs() { let target_filenames = ctx.target_filenames(&unit).expect("Can't get target file names"); // Verify the result. - let mut expected = vec!["debug/foo.js", "debug/foo.wasm"]; + let mut expected = vec!["debug/foo-bar.js", "debug/foo_bar.wasm"]; assert_eq!(target_filenames.len(), expected.len()); -- 2.30.2