Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ log = "0.4.6"
libgit2-sys = "0.7.9"
num_cpus = "1.0"
opener = "0.3.0"
pathdiff = "0.1"
rustfix = "0.4.4"
same-file = "1"
semver = { version = "0.9.0", features = ["serde"] }
Expand Down
17 changes: 12 additions & 5 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ pub enum FileFlavor {
DebugInfo,
}

/// A description about the type of file generated by a Unit.
pub struct FileType {
/// The type of the file.
pub flavor: FileFlavor,
/// The suffix of the filename, such as ".dll", ".rlib", ".exe", etc.
/// This is an empty string for executables on Unix-like platforms.
suffix: String,
/// The prefix of the filename, such as "lib".
/// This is an empty string for things like executables.
prefix: String,
// 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".
/// Flag to convert hyphen to underscore.
///
/// wasm bin targets will generate two files in deps such as
/// "web-stuff.js" and "web_stuff.wasm". Note the different usages of "-"
/// and "_". This flag indicates that the stem "web-stuff" should be
/// converted to "web_stuff".
should_replace_hyphens: bool,
}

Expand Down
1 change: 1 addition & 0 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct Doctest {
/// A structure returning the result of a compilation.
pub struct Compilation<'cfg> {
/// An array of all tests created during this compilation.
/// (package, target_kind, test_name, path_to_test_exe)
pub tests: Vec<(Package, TargetKind, String, PathBuf)>,

/// An array of all binaries created.
Expand Down
157 changes: 76 additions & 81 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use lazycell::LazyCell;
use log::info;

use super::{BuildContext, Context, FileFlavor, Kind, Layout, Unit};
use crate::core::{TargetKind, Workspace};
use crate::core::{compiler::CompileMode, TargetKind, Workspace};
use crate::util::{self, CargoResult};

/// The `Metadata` is a hash used to make unique file names for each unit in a build.
Expand Down Expand Up @@ -144,11 +144,13 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
/// target.
pub fn out_dir(&self, unit: &Unit<'a>) -> PathBuf {
if unit.mode.is_doc() {
self.layout(unit.kind).root().parent().unwrap().join("doc")
self.layout(unit.kind).doc().to_path_buf()
} else if unit.target.is_custom_build() {
self.build_script_dir(unit)
} else if unit.target.is_example() {
self.layout(unit.kind).examples().to_path_buf()
} else if unit.mode == CompileMode::Test || unit.mode == CompileMode::Bench {
self.layout(unit.kind).legacy_deps().to_path_buf()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that tests & benches should be treated as "public" outputs: it's not uncommon to launch test executable manually, to attach gdb. Should we use the following layout?

target/release
  examples/
  tests/
  benches/
  bins & libs

?

} else {
self.deps_dir(unit).to_path_buf()
}
Expand All @@ -168,7 +170,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {

/// Return the root of the build output tree
pub fn target_root(&self) -> &Path {
self.host.dest()
self.host.root()
}

pub fn host_deps(&self) -> &Path {
Expand Down Expand Up @@ -239,8 +241,8 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
/// (eg a dependent lib)
fn link_stem(&self, unit: &Unit<'a>) -> Option<(PathBuf, String)> {
let out_dir = self.out_dir(unit);
let bin_stem = self.bin_stem(unit);
let file_stem = self.file_stem(unit);
let bin_stem = self.bin_stem(unit); // Stem without metadata.
let file_stem = self.file_stem(unit); // Stem with metadata.

// We currently only lift files up from the `deps` directory. If
// it was compiled into something like `example/` or `doc/` then
Expand All @@ -249,7 +251,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
// Don't lift up library dependencies
if unit.target.is_bin() || self.roots.contains(unit) {
Some((
out_dir.parent().unwrap().to_owned(),
self.layout(unit.kind).dest().to_path_buf(),
if unit.mode.is_any_test() {
file_stem
} else {
Expand Down Expand Up @@ -284,85 +286,78 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {

let mut ret = Vec::new();
let mut unsupported = Vec::new();
{
if unit.mode.is_check() {
// This may be confusing. rustc outputs a file named `lib*.rmeta`
// for both libraries and binaries.
let path = out_dir.join(format!("lib{}.rmeta", file_stem));
ret.push(OutputFile {
path,
hardlink: None,
export_path: None,
flavor: FileFlavor::Linkable,
});
} else {
let mut add = |crate_type: &str, flavor: FileFlavor| -> CargoResult<()> {
let crate_type = if crate_type == "lib" {
"rlib"
} else {
crate_type
};
let file_types = info.file_types(
crate_type,
flavor,
unit.target.kind(),
bcx.target_triple(),
)?;

match file_types {
Some(types) => {
for file_type in types {
let path = out_dir.join(file_type.filename(&file_stem));
let hardlink = link_stem
.as_ref()
.map(|&(ref ld, ref ls)| ld.join(file_type.filename(ls)));
let export_path = if unit.target.is_custom_build() {
None
} else {
self.export_dir.as_ref().and_then(|export_dir| {
hardlink.as_ref().and_then(|hardlink| {
Some(export_dir.join(hardlink.file_name().unwrap()))
})
if unit.mode.is_check() {
// This may be confusing. rustc outputs a file named `lib*.rmeta`
// for both libraries and binaries.
let path = out_dir.join(format!("lib{}.rmeta", file_stem));
ret.push(OutputFile {
path,
hardlink: None,
export_path: None,
flavor: FileFlavor::Linkable,
});
} else {
let mut add = |crate_type: &str, flavor: FileFlavor| -> CargoResult<()> {
let crate_type = if crate_type == "lib" {
"rlib"
} else {
crate_type
};
let file_types =
info.file_types(crate_type, flavor, unit.target.kind(), bcx.target_triple())?;

match file_types {
Some(types) => {
for file_type in types {
let path = out_dir.join(file_type.filename(&file_stem));
let hardlink = link_stem
.as_ref()
.map(|&(ref ld, ref ls)| ld.join(file_type.filename(ls)));
let export_path = if unit.target.is_custom_build() {
None
} else {
self.export_dir.as_ref().and_then(|export_dir| {
hardlink.as_ref().and_then(|hardlink| {
Some(export_dir.join(hardlink.file_name().unwrap()))
})
};
ret.push(OutputFile {
path,
hardlink,
export_path,
flavor: file_type.flavor,
});
}
}
// not supported, don't worry about it
None => {
unsupported.push(crate_type.to_string());
})
};
ret.push(OutputFile {
path,
hardlink,
export_path,
flavor: file_type.flavor,
});
}
}
Ok(())
};
//info!("{:?}", unit);
match *unit.target.kind() {
TargetKind::Bin
| TargetKind::CustomBuild
| TargetKind::ExampleBin
| TargetKind::Bench
| TargetKind::Test => {
add("bin", FileFlavor::Normal)?;
}
TargetKind::Lib(..) | TargetKind::ExampleLib(..) if unit.mode.is_any_test() => {
add("bin", FileFlavor::Normal)?;
// not supported, don't worry about it
None => {
unsupported.push(crate_type.to_string());
}
TargetKind::ExampleLib(ref kinds) | TargetKind::Lib(ref kinds) => {
for kind in kinds {
add(
kind.crate_type(),
if kind.linkable() {
FileFlavor::Linkable
} else {
FileFlavor::Normal
},
)?;
}
}
Ok(())
};
match *unit.target.kind() {
TargetKind::Bin
| TargetKind::CustomBuild
| TargetKind::ExampleBin
| TargetKind::Bench
| TargetKind::Test => {
add("bin", FileFlavor::Normal)?;
}
TargetKind::Lib(..) | TargetKind::ExampleLib(..) if unit.mode.is_any_test() => {
add("bin", FileFlavor::Normal)?;
}
TargetKind::ExampleLib(ref kinds) | TargetKind::Lib(ref kinds) => {
for kind in kinds {
add(
kind.crate_type(),
if kind.linkable() {
FileFlavor::Linkable
} else {
FileFlavor::Normal
},
)?;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {

let files = self.files.as_ref().unwrap();
let layout = files.target.as_ref().unwrap_or(&files.host);
self.compilation.root_output = layout.dest().to_path_buf();
self.compilation.root_output = layout.root().to_path_buf();
self.compilation.deps_output = layout.deps().to_path_buf();
Ok(())
}
Expand Down
Loading