Skip to content

Commit 2b63c4f

Browse files
committed
Auto merge of rust-lang#3609 - jmatraszek:build_proper_binary, r=alexcrichton
Fix building multiple binaries that do not have path spacified in Cargo.toml When multiple binaries are specified in Cargo.toml, the binaries that do not have `path` specified are build from `src/main.rs`. Discovered here: rust-lang-nursery/thanks#40 (comment). This was caused by setting for a binary a main layout here https://github.com/rust-lang/cargo/blob/master/src/cargo/util/toml.rs#L478, which caused `normalize` to not fallback to default binary path here https://github.com/rust-lang/cargo/blob/master/src/cargo/util/toml.rs#L1149 (as `bin.path` was always `Some("/path/to/main.rs")`. Added a test and fixed this by not using `layout.main()`, so right now for bins without `path` specified we fallback to default path inferred from bin's name (e.g. `src/bin/foo.rs`), test if the file exists and only if it doesn't -- fallback to `src/main.rs`. I do not have any knowledge about Cargo's design, so I am not sure if this is the proper place to test for file existence.
2 parents 0ee14de + d95983f commit 2b63c4f

File tree

3 files changed

+36
-24
lines changed

3 files changed

+36
-24
lines changed

src/cargo/util/toml.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,6 @@ impl Layout {
6464
benches: benches,
6565
}
6666
}
67-
68-
fn main(&self) -> Option<&PathBuf> {
69-
self.bins.iter().find(|p| {
70-
match p.file_name().and_then(|s| s.to_str()) {
71-
Some(s) => s == "main.rs",
72-
None => false
73-
}
74-
})
75-
}
7667
}
7768

7869
fn try_add_file(files: &mut Vec<PathBuf>, file: PathBuf) {
@@ -475,22 +466,10 @@ impl TomlManifest {
475466

476467
let bins = match self.bin {
477468
Some(ref bins) => {
478-
let bin = layout.main();
479-
480469
for target in bins {
481470
target.validate_binary_name()?;
482-
}
483-
484-
bins.iter().map(|t| {
485-
if bin.is_some() && t.path.is_none() {
486-
TomlTarget {
487-
path: bin.as_ref().map(|&p| PathValue::Path(p.clone())),
488-
.. t.clone()
489-
}
490-
} else {
491-
t.clone()
492-
}
493-
}).collect()
471+
};
472+
bins.clone()
494473
}
495474
None => inferred_bin_targets(&project.name, layout)
496475
};
@@ -1147,7 +1126,11 @@ fn normalize(package_root: &Path,
11471126
default: &mut FnMut(&TomlBinTarget) -> PathBuf| {
11481127
for bin in bins.iter() {
11491128
let path = bin.path.clone().unwrap_or_else(|| {
1150-
PathValue::Path(default(bin))
1129+
let default_bin_path = PathValue::Path(default(bin));
1130+
match package_root.join(default_bin_path.to_path()).exists() {
1131+
true => default_bin_path, // inferred from bin's name
1132+
false => PathValue::Path(Path::new("src").join("main.rs"))
1133+
}
11511134
});
11521135
let mut target = Target::bin_target(&bin.name(), package_root.join(path.to_path()));
11531136
configure(bin, &mut target);

tests/build.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,3 +2769,30 @@ fn build_all_member_dependency_same_name() {
27692769
[..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n"));
27702770
}
27712771

2772+
#[test]
2773+
fn run_proper_binary() {
2774+
let p = project("foo")
2775+
.file("Cargo.toml", r#"
2776+
[package]
2777+
name = "foo"
2778+
authors = []
2779+
version = "0.0.0"
2780+
[[bin]]
2781+
name = "main"
2782+
[[bin]]
2783+
name = "other"
2784+
"#)
2785+
.file("src/lib.rs", "")
2786+
.file("src/bin/main.rs", r#"
2787+
fn main() {
2788+
panic!("This should never be run.");
2789+
}
2790+
"#)
2791+
.file("src/bin/other.rs", r#"
2792+
fn main() {
2793+
}
2794+
"#);
2795+
2796+
assert_that(p.cargo_process("run").arg("--bin").arg("other"),
2797+
execs().with_status(0));
2798+
}

tests/metadata.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest,
88
#[test]
99
fn cargo_metadata_simple() {
1010
let p = project("foo")
11+
.file("src/foo.rs", "")
1112
.file("Cargo.toml", &basic_bin_manifest("foo"));
1213

1314
assert_that(p.cargo_process("metadata"), execs().with_json(r#"
@@ -52,6 +53,7 @@ fn cargo_metadata_simple() {
5253
#[test]
5354
fn cargo_metadata_with_deps_and_version() {
5455
let p = project("foo")
56+
.file("src/foo.rs", "")
5557
.file("Cargo.toml", r#"
5658
[project]
5759
name = "foo"

0 commit comments

Comments
 (0)