Skip to content

Commit 21540a6

Browse files
committed
Auto merge of #1443 - alexcrichton:hyphens-to-underscores, r=brson
This change allows *packages* to have hyphens in them, but they are always translated to underscores when translated to a crate name. This means that all crates are compiled with a `--crate-name` that has no hyphens (as well as `--extern` directives having no hyphens). Binaries and examples, however, are allowed to contain hyphens in their name. The "crate name" will still have an underscore, but the output will be in the same dasherized name. Explicitly named targets are not allowed to have hyphens in them as well.
2 parents 8f5cb1d + b2acc24 commit 21540a6

File tree

7 files changed

+106
-24
lines changed

7 files changed

+106
-24
lines changed

src/cargo/core/manifest.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ impl Target {
322322
}
323323

324324
pub fn name(&self) -> &str { &self.name }
325+
pub fn crate_name(&self) -> String { self.name.replace("-", "_") }
325326
pub fn src_path(&self) -> &Path { &self.src_path }
326327
pub fn metadata(&self) -> Option<&Metadata> { self.metadata.as_ref() }
327328
pub fn kind(&self) -> &TargetKind { &self.kind }
@@ -332,6 +333,10 @@ impl Target {
332333
pub fn for_host(&self) -> bool { self.for_host }
333334
pub fn benched(&self) -> bool { self.benched }
334335

336+
pub fn allows_underscores(&self) -> bool {
337+
self.is_bin() || self.is_example() || self.is_custom_build()
338+
}
339+
335340
pub fn is_lib(&self) -> bool {
336341
match self.kind {
337342
TargetKind::Lib(_) => true,

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,10 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
282282
/// Returns the file stem for a given target/profile combo
283283
pub fn file_stem(&self, target: &Target, profile: &Profile) -> String {
284284
match self.target_metadata(target, profile) {
285-
Some(ref metadata) => format!("{}{}", target.name(),
285+
Some(ref metadata) => format!("{}{}", target.crate_name(),
286286
metadata.extra_filename),
287-
None => target.name().to_string(),
287+
None if target.allows_underscores() => target.name().to_string(),
288+
None => target.crate_name().to_string(),
288289
}
289290
}
290291

src/cargo/ops/cargo_rustc/custom_build.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform,
4646
};
4747

4848
// Building the command to execute
49-
let profile = cx.build_script_profile(pkg.package_id());
50-
let to_exec = try!(cx.target_filenames(target, profile))[0].clone();
51-
let to_exec = script_output.join(&to_exec);
49+
let to_exec = script_output.join(target.name());
5250

5351
// Start preparing the process to execute, starting out with some
5452
// environment variables. Note that the profile-related environment

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,15 @@ fn rustc(package: &Package, target: &Target, profile: &Profile,
328328
let pass_l_flag = target.is_lib() || !package.targets().iter().any(|t| {
329329
t.is_lib()
330330
});
331+
let do_rename = target.allows_underscores() && !profile.test;
332+
let real_name = target.name().to_string();
333+
let crate_name = target.crate_name();
331334

332-
let rustc_dep_info_loc = root.join(&cx.file_stem(target, profile))
333-
.with_extension("d");
335+
let rustc_dep_info_loc = if do_rename {
336+
root.join(&crate_name)
337+
} else {
338+
root.join(&cx.file_stem(target, profile))
339+
}.with_extension("d");
334340
let dep_info_loc = fingerprint::dep_info_loc(cx, package, target,
335341
profile, kind);
336342
let cwd = cx.config.cwd().to_path_buf();
@@ -363,7 +369,20 @@ fn rustc(package: &Package, target: &Target, profile: &Profile,
363369
human(format!("Could not compile `{}`.", name))
364370
}));
365371

366-
try!(fs::rename(&rustc_dep_info_loc, &dep_info_loc));
372+
if do_rename && real_name != crate_name {
373+
let dst = root.join(&filenames[0]);
374+
let src = dst.with_file_name(dst.file_name().unwrap()
375+
.to_str().unwrap()
376+
.replace(&real_name, &crate_name));
377+
try!(fs::rename(&src, &dst).chain_error(|| {
378+
human(format!("could not rename crate {:?}", src))
379+
}));
380+
}
381+
382+
try!(fs::rename(&rustc_dep_info_loc, &dep_info_loc).chain_error(|| {
383+
human(format!("could not rename dep info: {:?}",
384+
rustc_dep_info_loc))
385+
}));
367386
try!(fingerprint::append_current_dir(&dep_info_loc, &cwd));
368387

369388
Ok(())
@@ -482,7 +501,7 @@ fn rustdoc(package: &Package, target: &Target, profile: &Profile,
482501
rustdoc.arg(&root_path(cx, package, target))
483502
.cwd(cx.config.cwd())
484503
.arg("-o").arg(&cx_root)
485-
.arg("--crate-name").arg(target.name());
504+
.arg("--crate-name").arg(&target.crate_name());
486505

487506
match cx.resolve.features(package.package_id()) {
488507
Some(features) => {
@@ -565,7 +584,7 @@ fn build_base_args(cx: &Context,
565584
// TODO: Handle errors in converting paths into args
566585
cmd.arg(&root_path(cx, pkg, target));
567586

568-
cmd.arg("--crate-name").arg(target.name());
587+
cmd.arg("--crate-name").arg(&target.crate_name());
569588

570589
for crate_type in crate_types.iter() {
571590
cmd.arg("--crate-type").arg(crate_type);
@@ -696,7 +715,7 @@ fn build_deps_args(cmd: &mut CommandPrototype,
696715
for filename in try!(cx.target_filenames(target, profile)).iter() {
697716
if filename.ends_with(".a") { continue }
698717
let mut v = OsString::new();
699-
v.push(target.name());
718+
v.push(&target.crate_name());
700719
v.push("=");
701720
v.push(layout.root());
702721
v.push(&path::MAIN_SEPARATOR.to_string());

src/cargo/util/toml.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -395,16 +395,17 @@ impl TomlManifest {
395395
ManyOrOne::Many(..) => used_deprecated_lib = true,
396396
_ => {}
397397
}
398-
libs.as_slice().iter().map(|t| {
399-
if layout.lib.is_some() && t.path.is_none() {
398+
try!(libs.as_slice().iter().map(|t| {
399+
try!(validate_target_name(t));
400+
Ok(if layout.lib.is_some() && t.path.is_none() {
400401
TomlTarget {
401402
path: layout.lib.as_ref().map(|p| PathValue::Path(p.clone())),
402403
.. t.clone()
403404
}
404405
} else {
405406
t.clone()
406-
}
407-
}).collect()
407+
})
408+
}).collect::<CargoResult<Vec<_>>>())
408409
}
409410
None => inferred_lib_target(&project.name, layout),
410411
};
@@ -413,34 +414,48 @@ impl TomlManifest {
413414
Some(ref bins) => {
414415
let bin = layout.main();
415416

416-
bins.iter().map(|t| {
417-
if bin.is_some() && t.path.is_none() {
417+
try!(bins.iter().map(|t| {
418+
try!(validate_target_name(t));
419+
Ok(if bin.is_some() && t.path.is_none() {
418420
TomlTarget {
419421
path: bin.as_ref().map(|&p| PathValue::Path(p.clone())),
420422
.. t.clone()
421423
}
422424
} else {
423425
t.clone()
424-
}
425-
}).collect()
426+
})
427+
}).collect::<CargoResult<Vec<_>>>())
426428
}
427429
None => inferred_bin_targets(&project.name, layout)
428430
};
429431

430432
let examples = match self.example {
431-
Some(ref examples) => examples.clone(),
433+
Some(ref examples) => {
434+
for example in examples {
435+
try!(validate_target_name(example));
436+
}
437+
examples.clone()
438+
}
432439
None => inferred_example_targets(layout),
433440
};
434441

435442
let tests = match self.test {
436-
Some(ref tests) => tests.clone(),
443+
Some(ref tests) => {
444+
for test in tests {
445+
try!(validate_target_name(test));
446+
}
447+
tests.clone()
448+
}
437449
None => inferred_test_targets(layout),
438450
};
439451

440452
let benches = if self.bench.is_none() || self.bench.as_ref().unwrap().is_empty() {
441453
inferred_bench_targets(layout)
442454
} else {
443-
self.bench.as_ref().unwrap().iter().map(|t| t.clone()).collect()
455+
try!(self.bench.as_ref().unwrap().iter().map(|t| {
456+
try!(validate_target_name(t));
457+
Ok(t.clone())
458+
}).collect::<CargoResult<Vec<_>>>())
444459
};
445460

446461
// processing the custom build script
@@ -529,6 +544,15 @@ impl TomlManifest {
529544
}
530545
}
531546

547+
fn validate_target_name(target: &TomlTarget) -> CargoResult<()> {
548+
if target.name.contains("-") {
549+
Err(human(format!("target names cannot contain hyphens: {}",
550+
target.name)))
551+
} else {
552+
Ok(())
553+
}
554+
}
555+
532556
fn process_dependencies<F>(cx: &mut Context,
533557
new_deps: Option<&HashMap<String, TomlDependency>>,
534558
mut f: F) -> CargoResult<()>

tests/test_cargo_compile.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,3 +1653,38 @@ test!(cyclic_deps_rejected {
16531653
cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
16541654
"));
16551655
});
1656+
1657+
test!(dashes_to_underscores {
1658+
let p = project("foo")
1659+
.file("Cargo.toml", r#"
1660+
[package]
1661+
name = "foo-bar"
1662+
version = "0.0.1"
1663+
authors = []
1664+
"#)
1665+
.file("src/lib.rs", "")
1666+
.file("src/main.rs", "extern crate foo_bar; fn main() {}");
1667+
1668+
assert_that(p.cargo_process("build").arg("-v"),
1669+
execs().with_status(0));
1670+
assert_that(&p.root().join("target/debug/foo-bar"),
1671+
existing_file());
1672+
});
1673+
1674+
test!(dashes_in_crate_name_bad {
1675+
let p = project("foo")
1676+
.file("Cargo.toml", r#"
1677+
[package]
1678+
name = "foo"
1679+
version = "0.0.1"
1680+
authors = []
1681+
1682+
[lib]
1683+
name = "foo-bar"
1684+
"#)
1685+
.file("src/lib.rs", "")
1686+
.file("src/main.rs", "extern crate foo_bar; fn main() {}");
1687+
1688+
assert_that(p.cargo_process("build").arg("-v"),
1689+
execs().with_status(101));
1690+
});

tests/test_cargo_compile_custom_build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test!(custom_build_script_failed {
3333
execs().with_status(101)
3434
.with_stdout(format!("\
3535
{compiling} foo v0.5.0 ({url})
36-
{running} `rustc build.rs --crate-name build-script-build --crate-type bin [..]`
36+
{running} `rustc build.rs --crate-name build_script_build --crate-type bin [..]`
3737
{running} `[..]build-script-build[..]`
3838
",
3939
url = p.url(), compiling = COMPILING, running = RUNNING))
@@ -760,7 +760,7 @@ test!(build_cmd_with_a_build_cmd {
760760
--out-dir [..]target[..]deps --emit=dep-info,link \
761761
-L [..]target[..]deps -L [..]target[..]deps`
762762
{compiling} foo v0.5.0 (file://[..])
763-
{running} `rustc build.rs --crate-name build-script-build --crate-type bin \
763+
{running} `rustc build.rs --crate-name build_script_build --crate-type bin \
764764
-C prefer-dynamic -g \
765765
--out-dir [..]build[..]foo-[..] --emit=dep-info,link \
766766
-L [..]target[..]debug -L [..]target[..]deps \

0 commit comments

Comments
 (0)