mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
Expose build.target .cargo/config setting as packages.target in Cargo.toml
This commit is contained in:
parent
0ed318d182
commit
5e11afc1ab
@ -5,6 +5,8 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
|
6
crates/cargo-test-support/build.rs
Normal file
6
crates/cargo-test-support/build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
println!(
|
||||
"cargo:rustc-env=NATIVE_ARCH={}",
|
||||
std::env::var("TARGET").unwrap()
|
||||
);
|
||||
}
|
@ -179,6 +179,23 @@ rustup does not appear to be installed. Make sure that the appropriate
|
||||
panic!("{}", message);
|
||||
}
|
||||
|
||||
/// The arch triple of the test-running host.
|
||||
pub fn native() -> &'static str {
|
||||
env!("NATIVE_ARCH")
|
||||
}
|
||||
|
||||
pub fn native_arch() -> &'static str {
|
||||
match native()
|
||||
.split("-")
|
||||
.next()
|
||||
.expect("Target triple has unexpected format")
|
||||
{
|
||||
"x86_64" => "x86_64",
|
||||
"i686" => "x86",
|
||||
_ => panic!("This test should be gated on cross_compile::disabled."),
|
||||
}
|
||||
}
|
||||
|
||||
/// The alternate target-triple to build with.
|
||||
///
|
||||
/// Only use this function on tests that check `cross_compile::disabled`.
|
||||
@ -204,6 +221,15 @@ pub fn alternate_arch() -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
/// A target-triple that is neither the host nor the target.
|
||||
///
|
||||
/// Rustc may not work with it and it's alright, apart from being a
|
||||
/// valid target triple it is supposed to be used only as a
|
||||
/// placeholder for targets that should not be considered.
|
||||
pub fn unused() -> &'static str {
|
||||
"wasm32-unknown-unknown"
|
||||
}
|
||||
|
||||
/// Whether or not the host can run cross-compiled executables.
|
||||
pub fn can_run_on_host() -> bool {
|
||||
if disabled() {
|
||||
|
@ -39,7 +39,7 @@ pub struct BuildContext<'a, 'cfg> {
|
||||
pub packages: PackageSet<'cfg>,
|
||||
|
||||
/// Information about rustc and the target platform.
|
||||
pub target_data: RustcTargetData,
|
||||
pub target_data: RustcTargetData<'cfg>,
|
||||
|
||||
/// The root units of `unit_graph` (units requested on the command-line).
|
||||
pub roots: Vec<Unit>,
|
||||
@ -58,7 +58,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
|
||||
build_config: &'a BuildConfig,
|
||||
profiles: Profiles,
|
||||
extra_compiler_args: HashMap<Unit, Vec<String>>,
|
||||
target_data: RustcTargetData,
|
||||
target_data: RustcTargetData<'cfg>,
|
||||
roots: Vec<Unit>,
|
||||
unit_graph: UnitGraph,
|
||||
) -> CargoResult<BuildContext<'a, 'cfg>> {
|
||||
|
@ -655,9 +655,14 @@ fn env_args(
|
||||
}
|
||||
|
||||
/// Collection of information about `rustc` and the host and target.
|
||||
pub struct RustcTargetData {
|
||||
pub struct RustcTargetData<'cfg> {
|
||||
/// Information about `rustc` itself.
|
||||
pub rustc: Rustc,
|
||||
|
||||
/// Config
|
||||
config: &'cfg Config,
|
||||
requested_kinds: Vec<CompileKind>,
|
||||
|
||||
/// Build information for the "host", which is information about when
|
||||
/// `rustc` is invoked without a `--target` flag. This is used for
|
||||
/// procedural macros, build scripts, etc.
|
||||
@ -670,27 +675,17 @@ pub struct RustcTargetData {
|
||||
target_info: HashMap<CompileTarget, TargetInfo>,
|
||||
}
|
||||
|
||||
impl RustcTargetData {
|
||||
impl<'cfg> RustcTargetData<'cfg> {
|
||||
pub fn new(
|
||||
ws: &Workspace<'_>,
|
||||
ws: &Workspace<'cfg>,
|
||||
requested_kinds: &[CompileKind],
|
||||
) -> CargoResult<RustcTargetData> {
|
||||
) -> CargoResult<RustcTargetData<'cfg>> {
|
||||
let config = ws.config();
|
||||
let rustc = config.load_global_rustc(Some(ws))?;
|
||||
let host_config = config.target_cfg_triple(&rustc.host)?;
|
||||
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
|
||||
let mut target_config = HashMap::new();
|
||||
let mut target_info = HashMap::new();
|
||||
for kind in requested_kinds {
|
||||
if let CompileKind::Target(target) = *kind {
|
||||
let tcfg = config.target_cfg_triple(target.short_name())?;
|
||||
target_config.insert(target, tcfg);
|
||||
target_info.insert(
|
||||
target,
|
||||
TargetInfo::new(config, requested_kinds, &rustc, *kind)?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// This is a hack. The unit_dependency graph builder "pretends" that
|
||||
// `CompileKind::Host` is `CompileKind::Target(host)` if the
|
||||
@ -703,13 +698,56 @@ impl RustcTargetData {
|
||||
target_config.insert(ct, host_config.clone());
|
||||
}
|
||||
|
||||
Ok(RustcTargetData {
|
||||
let mut res = RustcTargetData {
|
||||
rustc,
|
||||
config,
|
||||
requested_kinds: requested_kinds.into(),
|
||||
host_config,
|
||||
host_info,
|
||||
target_config,
|
||||
target_info,
|
||||
})
|
||||
};
|
||||
|
||||
// Get all kinds we currently know about.
|
||||
//
|
||||
// For now, targets can only ever come from the root workspace
|
||||
// units as artifact dependencies are not a thing yet, so this
|
||||
// correctly represents all the kinds that can happen. When we
|
||||
// have artifact dependencies or other ways for targets to
|
||||
// appear at places that are not the root units, we may have
|
||||
// to revisit this.
|
||||
let all_kinds = requested_kinds
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(ws.members().flat_map(|p| {
|
||||
p.manifest()
|
||||
.default_kind()
|
||||
.into_iter()
|
||||
.chain(p.manifest().forced_kind())
|
||||
}));
|
||||
for kind in all_kinds {
|
||||
if let CompileKind::Target(target) = kind {
|
||||
match res.target_config.entry(target) {
|
||||
std::collections::hash_map::Entry::Occupied(_) => (),
|
||||
std::collections::hash_map::Entry::Vacant(place) => {
|
||||
place.insert(res.config.target_cfg_triple(target.short_name())?);
|
||||
}
|
||||
}
|
||||
match res.target_info.entry(target) {
|
||||
std::collections::hash_map::Entry::Occupied(_) => (),
|
||||
std::collections::hash_map::Entry::Vacant(place) => {
|
||||
place.insert(TargetInfo::new(
|
||||
res.config,
|
||||
&res.requested_kinds,
|
||||
&res.rustc,
|
||||
kind,
|
||||
)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Returns a "short" name for the given kind, suitable for keying off
|
||||
|
@ -127,10 +127,10 @@ impl<'cfg> Compilation<'cfg> {
|
||||
sysroot_target_libdir: bcx
|
||||
.all_kinds
|
||||
.iter()
|
||||
.map(|kind| {
|
||||
.map(|&kind| {
|
||||
(
|
||||
*kind,
|
||||
bcx.target_data.info(*kind).sysroot_target_libdir.clone(),
|
||||
kind,
|
||||
bcx.target_data.info(kind).sysroot_target_libdir.clone(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
|
@ -33,7 +33,7 @@ pub fn parse_unstable_flag(value: Option<&str>) -> Vec<String> {
|
||||
/// Resolve the standard library dependencies.
|
||||
pub fn resolve_std<'cfg>(
|
||||
ws: &Workspace<'cfg>,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'cfg>,
|
||||
requested_targets: &[CompileKind],
|
||||
crates: &[String],
|
||||
) -> CargoResult<(PackageSet<'cfg>, Resolve, ResolvedFeatures)> {
|
||||
@ -185,7 +185,7 @@ pub fn generate_std_roots(
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn detect_sysroot_src_path(target_data: &RustcTargetData) -> CargoResult<PathBuf> {
|
||||
fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<PathBuf> {
|
||||
if let Some(s) = env::var_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
|
||||
return Ok(s.into());
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ struct State<'a, 'cfg> {
|
||||
/// library.
|
||||
is_std: bool,
|
||||
global_mode: CompileMode,
|
||||
target_data: &'a RustcTargetData,
|
||||
target_data: &'a RustcTargetData<'cfg>,
|
||||
profiles: &'a Profiles,
|
||||
interner: &'a UnitInterner,
|
||||
|
||||
@ -63,7 +63,7 @@ pub fn build_unit_dependencies<'a, 'cfg>(
|
||||
roots: &[Unit],
|
||||
std_roots: &HashMap<CompileKind, Vec<Unit>>,
|
||||
global_mode: CompileMode,
|
||||
target_data: &'a RustcTargetData,
|
||||
target_data: &'a RustcTargetData<'cfg>,
|
||||
profiles: &'a Profiles,
|
||||
interner: &'a UnitInterner,
|
||||
) -> CargoResult<UnitGraph> {
|
||||
|
@ -390,6 +390,9 @@ features! {
|
||||
|
||||
// Support for 2021 edition.
|
||||
(unstable, edition2021, "", "reference/unstable.html#edition-2021"),
|
||||
|
||||
// Allow to specify per-package targets (compile kinds)
|
||||
(unstable, per_package_target, "", "reference/unstable.html#per-package-target"),
|
||||
}
|
||||
|
||||
const PUBLISH_LOCKFILE_REMOVED: &str = "The publish-lockfile key in Cargo.toml \
|
||||
|
@ -11,7 +11,7 @@ use serde::ser;
|
||||
use serde::Serialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::core::compiler::CrateType;
|
||||
use crate::core::compiler::{CompileKind, CrateType};
|
||||
use crate::core::resolver::ResolveBehavior;
|
||||
use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
|
||||
use crate::core::{Edition, Feature, Features, WorkspaceConfig};
|
||||
@ -32,6 +32,8 @@ pub enum EitherManifest {
|
||||
pub struct Manifest {
|
||||
summary: Summary,
|
||||
targets: Vec<Target>,
|
||||
default_kind: Option<CompileKind>,
|
||||
forced_kind: Option<CompileKind>,
|
||||
links: Option<String>,
|
||||
warnings: Warnings,
|
||||
exclude: Vec<String>,
|
||||
@ -366,6 +368,8 @@ compact_debug! {
|
||||
impl Manifest {
|
||||
pub fn new(
|
||||
summary: Summary,
|
||||
default_kind: Option<CompileKind>,
|
||||
forced_kind: Option<CompileKind>,
|
||||
targets: Vec<Target>,
|
||||
exclude: Vec<String>,
|
||||
include: Vec<String>,
|
||||
@ -388,6 +392,8 @@ impl Manifest {
|
||||
) -> Manifest {
|
||||
Manifest {
|
||||
summary,
|
||||
default_kind,
|
||||
forced_kind,
|
||||
targets,
|
||||
warnings: Warnings::new(),
|
||||
exclude,
|
||||
@ -414,6 +420,12 @@ impl Manifest {
|
||||
pub fn dependencies(&self) -> &[Dependency] {
|
||||
self.summary.dependencies()
|
||||
}
|
||||
pub fn default_kind(&self) -> Option<CompileKind> {
|
||||
self.default_kind
|
||||
}
|
||||
pub fn forced_kind(&self) -> Option<CompileKind> {
|
||||
self.forced_kind
|
||||
}
|
||||
pub fn exclude(&self) -> &[String] {
|
||||
&self.exclude
|
||||
}
|
||||
@ -503,6 +515,17 @@ impl Manifest {
|
||||
})?;
|
||||
}
|
||||
|
||||
if self.default_kind.is_some() || self.forced_kind.is_some() {
|
||||
self.unstable_features
|
||||
.require(Feature::per_package_target())
|
||||
.chain_err(|| {
|
||||
anyhow::format_err!(
|
||||
"the `package.default-kind` and `package.forced-kind` \
|
||||
manifest keys are unstable and may not work properly"
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -500,7 +500,7 @@ impl<'cfg> PackageSet<'cfg> {
|
||||
root_ids: &[PackageId],
|
||||
has_dev_units: HasDevUnits,
|
||||
requested_kinds: &[CompileKind],
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'cfg>,
|
||||
force_all_targets: ForceAllTargets,
|
||||
) -> CargoResult<()> {
|
||||
fn collect_used_deps(
|
||||
@ -509,7 +509,7 @@ impl<'cfg> PackageSet<'cfg> {
|
||||
pkg_id: PackageId,
|
||||
has_dev_units: HasDevUnits,
|
||||
requested_kinds: &[CompileKind],
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'_>,
|
||||
force_all_targets: ForceAllTargets,
|
||||
) -> CargoResult<()> {
|
||||
if !used.insert(pkg_id) {
|
||||
|
@ -414,7 +414,7 @@ pub struct FeatureDifferences {
|
||||
|
||||
pub struct FeatureResolver<'a, 'cfg> {
|
||||
ws: &'a Workspace<'cfg>,
|
||||
target_data: &'a RustcTargetData,
|
||||
target_data: &'a RustcTargetData<'cfg>,
|
||||
/// The platforms to build for, requested by the user.
|
||||
requested_targets: &'a [CompileKind],
|
||||
resolve: &'a Resolve,
|
||||
@ -452,7 +452,7 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {
|
||||
/// with the result.
|
||||
pub fn resolve(
|
||||
ws: &Workspace<'cfg>,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'cfg>,
|
||||
resolve: &Resolve,
|
||||
package_set: &'a PackageSet<'cfg>,
|
||||
cli_features: &CliFeatures,
|
||||
|
@ -467,11 +467,17 @@ pub fn create_bcx<'a, 'cfg>(
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Passing `build_config.requested_kinds` instead of
|
||||
// `explicit_host_kinds` here so that `generate_targets` can do
|
||||
// its own special handling of `CompileKind::Host`. It will
|
||||
// internally replace the host kind by the `explicit_host_kind`
|
||||
// before setting as a unit.
|
||||
let mut units = generate_targets(
|
||||
ws,
|
||||
&to_builds,
|
||||
filter,
|
||||
&explicit_host_kinds,
|
||||
&build_config.requested_kinds,
|
||||
explicit_host_kind,
|
||||
build_config.mode,
|
||||
&resolve,
|
||||
&workspace_resolve,
|
||||
@ -842,6 +848,7 @@ fn generate_targets(
|
||||
packages: &[&Package],
|
||||
filter: &CompileFilter,
|
||||
requested_kinds: &[CompileKind],
|
||||
explicit_host_kind: CompileKind,
|
||||
mode: CompileMode,
|
||||
resolve: &Resolve,
|
||||
workspace_resolve: &Option<Resolve>,
|
||||
@ -915,7 +922,27 @@ fn generate_targets(
|
||||
let features_for = FeaturesFor::from_for_host(target.proc_macro());
|
||||
let features = resolved_features.activated_features(pkg.package_id(), features_for);
|
||||
|
||||
for kind in requested_kinds {
|
||||
// If `--target` has not been specified, then the unit
|
||||
// graph is built almost like if `--target $HOST` was
|
||||
// specified. See `rebuild_unit_graph_shared` for more on
|
||||
// why this is done. However, if the package has its own
|
||||
// `package.target` key, then this gets used instead of
|
||||
// `$HOST`
|
||||
let explicit_kinds = if let Some(k) = pkg.manifest().forced_kind() {
|
||||
vec![k]
|
||||
} else {
|
||||
requested_kinds
|
||||
.iter()
|
||||
.map(|kind| match kind {
|
||||
CompileKind::Host => {
|
||||
pkg.manifest().default_kind().unwrap_or(explicit_host_kind)
|
||||
}
|
||||
CompileKind::Target(t) => CompileKind::Target(*t),
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
for kind in explicit_kinds.iter() {
|
||||
let profile = profiles.get_profile(
|
||||
pkg.package_id(),
|
||||
ws.is_member(pkg),
|
||||
|
@ -171,7 +171,7 @@ fn build_resolve_graph_r(
|
||||
pkg_id: PackageId,
|
||||
resolve: &Resolve,
|
||||
package_map: &BTreeMap<PackageId, Package>,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'_>,
|
||||
requested_kinds: &[CompileKind],
|
||||
) {
|
||||
if node_map.contains_key(&pkg_id) {
|
||||
|
@ -79,7 +79,7 @@ pub fn resolve_ws<'a>(ws: &Workspace<'a>) -> CargoResult<(PackageSet<'a>, Resolv
|
||||
/// members. In this case, `opts.all_features` must be `true`.
|
||||
pub fn resolve_ws_with_opts<'cfg>(
|
||||
ws: &Workspace<'cfg>,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'cfg>,
|
||||
requested_targets: &[CompileKind],
|
||||
cli_features: &CliFeatures,
|
||||
specs: &[PackageIdSpec],
|
||||
|
@ -249,7 +249,7 @@ pub fn build<'a>(
|
||||
resolved_features: &ResolvedFeatures,
|
||||
specs: &[PackageIdSpec],
|
||||
cli_features: &CliFeatures,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'_>,
|
||||
requested_kinds: &[CompileKind],
|
||||
package_map: HashMap<PackageId, &'a Package>,
|
||||
opts: &TreeOptions,
|
||||
@ -294,7 +294,7 @@ fn add_pkg(
|
||||
resolved_features: &ResolvedFeatures,
|
||||
package_id: PackageId,
|
||||
features_for: FeaturesFor,
|
||||
target_data: &RustcTargetData,
|
||||
target_data: &RustcTargetData<'_>,
|
||||
requested_kind: CompileKind,
|
||||
opts: &TreeOptions,
|
||||
) -> usize {
|
||||
|
@ -15,6 +15,7 @@ use serde::ser;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::core::compiler::{CompileKind, CompileTarget};
|
||||
use crate::core::dependency::DepKind;
|
||||
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
|
||||
use crate::core::resolver::ResolveBehavior;
|
||||
@ -793,6 +794,10 @@ pub struct TomlProject {
|
||||
authors: Option<Vec<String>>,
|
||||
build: Option<StringOrBool>,
|
||||
metabuild: Option<StringOrVec>,
|
||||
#[serde(rename = "default-target")]
|
||||
default_target: Option<String>,
|
||||
#[serde(rename = "forced-target")]
|
||||
forced_target: Option<String>,
|
||||
links: Option<String>,
|
||||
exclude: Option<Vec<String>>,
|
||||
include: Option<Vec<String>>,
|
||||
@ -1313,9 +1318,24 @@ impl TomlManifest {
|
||||
}
|
||||
}
|
||||
|
||||
let default_kind = project
|
||||
.default_target
|
||||
.as_ref()
|
||||
.map(|t| CompileTarget::new(&*t))
|
||||
.transpose()? // TODO: anyhow::Context isn't imported yet so I guess .context() isn't the right way to do it?
|
||||
.map(CompileKind::Target);
|
||||
let forced_kind = project
|
||||
.forced_target
|
||||
.as_ref()
|
||||
.map(|t| CompileTarget::new(&*t))
|
||||
.transpose()?
|
||||
.map(CompileKind::Target);
|
||||
|
||||
let custom_metadata = project.metadata.clone();
|
||||
let mut manifest = Manifest::new(
|
||||
summary,
|
||||
default_kind,
|
||||
forced_kind,
|
||||
targets,
|
||||
exclude,
|
||||
include,
|
||||
|
@ -895,6 +895,26 @@ In this example, the `std` feature enables the `std` feature on the `serde`
|
||||
dependency. However, unlike the normal `serde/std` syntax, it will not enable
|
||||
the optional dependency `serde` unless something else has included it.
|
||||
|
||||
### per-package-target
|
||||
|
||||
The `per-package-target` feature adds two keys to the manifest:
|
||||
`package.default-target` and `package.forced-target`. The first makes
|
||||
the package be compiled by default (ie. when no `--target` argument is
|
||||
passed) for some target. The second one makes the package always be
|
||||
compiled for the target.
|
||||
|
||||
Example:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
forced-target = "wasm32-unknown-unknown"
|
||||
```
|
||||
|
||||
In this example, the crate is always built for
|
||||
`wasm32-unknown-unknown`, for instance because it is going to be used
|
||||
as a plugin for a main program that runs on the host (or provided on
|
||||
the command line) target.
|
||||
|
||||
### credential-process
|
||||
* Tracking Issue: [#8933](https://github.com/rust-lang/cargo/issues/8933)
|
||||
* RFC: [#2730](https://github.com/rust-lang/rfcs/pull/2730)
|
||||
|
@ -153,6 +153,209 @@ fn simple_deps() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Always take care of setting these so that
|
||||
/// `cross_compile::alternate()` is the actually-picked target
|
||||
fn per_crate_target_test(
|
||||
default_target: Option<&'static str>,
|
||||
forced_target: Option<&'static str>,
|
||||
arg_target: Option<&'static str>,
|
||||
) {
|
||||
if cross_compile::disabled() {
|
||||
return;
|
||||
}
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
&format!(
|
||||
r#"
|
||||
cargo-features = ["per-package-target"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.0"
|
||||
authors = []
|
||||
build = "build.rs"
|
||||
{}
|
||||
{}
|
||||
"#,
|
||||
default_target
|
||||
.map(|t| format!(r#"default-target = "{}""#, t))
|
||||
.unwrap_or(String::new()),
|
||||
forced_target
|
||||
.map(|t| format!(r#"forced-target = "{}""#, t))
|
||||
.unwrap_or(String::new()),
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"build.rs",
|
||||
&format!(
|
||||
r#"
|
||||
fn main() {{
|
||||
assert_eq!(std::env::var("TARGET").unwrap(), "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::alternate()
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"src/main.rs",
|
||||
&format!(
|
||||
r#"
|
||||
use std::env;
|
||||
fn main() {{
|
||||
assert_eq!(env::consts::ARCH, "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::alternate_arch()
|
||||
),
|
||||
)
|
||||
.build();
|
||||
|
||||
let mut cmd = p.cargo("build -v");
|
||||
if let Some(t) = arg_target {
|
||||
cmd.arg("--target").arg(&t);
|
||||
}
|
||||
cmd.masquerade_as_nightly_cargo().run();
|
||||
assert!(p.target_bin(cross_compile::alternate(), "foo").is_file());
|
||||
|
||||
if cross_compile::can_run_on_host() {
|
||||
p.process(&p.target_bin(cross_compile::alternate(), "foo"))
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn per_crate_default_target_is_default() {
|
||||
per_crate_target_test(Some(cross_compile::alternate()), None, None);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn per_crate_default_target_gets_overridden() {
|
||||
per_crate_target_test(
|
||||
Some(cross_compile::unused()),
|
||||
None,
|
||||
Some(cross_compile::alternate()),
|
||||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn per_crate_forced_target_is_default() {
|
||||
per_crate_target_test(None, Some(cross_compile::alternate()), None);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn per_crate_forced_target_does_not_get_overridden() {
|
||||
per_crate_target_test(
|
||||
None,
|
||||
Some(cross_compile::alternate()),
|
||||
Some(cross_compile::unused()),
|
||||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn workspace_with_multiple_targets() {
|
||||
if cross_compile::disabled() {
|
||||
return;
|
||||
}
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["native", "cross"]
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"native/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["per-package-target"]
|
||||
|
||||
[package]
|
||||
name = "native"
|
||||
version = "0.0.0"
|
||||
authors = []
|
||||
build = "build.rs"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"native/build.rs",
|
||||
&format!(
|
||||
r#"
|
||||
fn main() {{
|
||||
assert_eq!(std::env::var("TARGET").unwrap(), "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::native()
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"native/src/main.rs",
|
||||
&format!(
|
||||
r#"
|
||||
use std::env;
|
||||
fn main() {{
|
||||
assert_eq!(env::consts::ARCH, "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::native_arch()
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"cross/Cargo.toml",
|
||||
&format!(
|
||||
r#"
|
||||
cargo-features = ["per-package-target"]
|
||||
|
||||
[package]
|
||||
name = "cross"
|
||||
version = "0.0.0"
|
||||
authors = []
|
||||
build = "build.rs"
|
||||
default-target = "{}"
|
||||
"#,
|
||||
cross_compile::alternate(),
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"cross/build.rs",
|
||||
&format!(
|
||||
r#"
|
||||
fn main() {{
|
||||
assert_eq!(std::env::var("TARGET").unwrap(), "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::alternate()
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"cross/src/main.rs",
|
||||
&format!(
|
||||
r#"
|
||||
use std::env;
|
||||
fn main() {{
|
||||
assert_eq!(env::consts::ARCH, "{}");
|
||||
}}
|
||||
"#,
|
||||
cross_compile::alternate_arch()
|
||||
),
|
||||
)
|
||||
.build();
|
||||
|
||||
let mut cmd = p.cargo("build -v");
|
||||
cmd.masquerade_as_nightly_cargo().run();
|
||||
|
||||
assert!(p.bin("native").is_file());
|
||||
assert!(p.target_bin(cross_compile::alternate(), "cross").is_file());
|
||||
|
||||
p.process(&p.bin("native")).run();
|
||||
if cross_compile::can_run_on_host() {
|
||||
p.process(&p.target_bin(cross_compile::alternate(), "cross"))
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn linker() {
|
||||
if cross_compile::disabled() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user