Skip to content

Commit e03fc6a

Browse files
committed
auto merge of #469 : alexcrichton/cargo/issue-442, r=brson
Discovering the prefix/suffix needs to understand that it's not actually available. Closes #442
2 parents 6d86dc8 + aa9ec52 commit e03fc6a

File tree

4 files changed

+81
-40
lines changed

4 files changed

+81
-40
lines changed

src/cargo/ops/cargo_rustc/context.rs

+33-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::str;
33

44
use core::{SourceMap, Package, PackageId, PackageSet, Resolve, Target};
55
use util::{mod, CargoResult, ChainError, internal, Config, profile, Require};
6+
use util::human;
67

78
use super::{Kind, KindPlugin, KindTarget, Compilation};
89
use super::layout::{Layout, LayoutProxy};
@@ -26,9 +27,10 @@ pub struct Context<'a, 'b> {
2627
host: Layout,
2728
target: Option<Layout>,
2829
target_triple: String,
29-
host_dylib: (String, String),
30+
host_triple: String,
31+
host_dylib: Option<(String, String)>,
3032
package_set: &'a PackageSet,
31-
target_dylib: (String, String),
33+
target_dylib: Option<(String, String)>,
3234
target_exe: String,
3335
requirements: HashMap<(&'a PackageId, &'a str), PlatformRequirement>,
3436
}
@@ -48,10 +50,11 @@ impl<'a, 'b> Context<'a, 'b> {
4850
};
4951
let (rustc_version, rustc_host) = try!(Context::rustc_version());
5052
let target_triple = config.target().map(|s| s.to_string());
51-
let target_triple = target_triple.unwrap_or(rustc_host);
53+
let target_triple = target_triple.unwrap_or(rustc_host.clone());
5254
Ok(Context {
5355
rustc_version: rustc_version,
5456
target_triple: target_triple,
57+
host_triple: rustc_host,
5558
env: env,
5659
host: host,
5760
target: target,
@@ -93,7 +96,7 @@ impl<'a, 'b> Context<'a, 'b> {
9396
/// Run `rustc` to discover the dylib prefix/suffix for the target
9497
/// specified as well as the exe suffix
9598
fn filename_parts(target: Option<&str>)
96-
-> CargoResult<((String, String), String)> {
99+
-> CargoResult<(Option<(String, String)>, String)> {
97100
let process = util::process("rustc")
98101
.arg("-")
99102
.arg("--crate-name").arg("-")
@@ -106,17 +109,22 @@ impl<'a, 'b> Context<'a, 'b> {
106109
};
107110
let output = try!(process.exec_with_output());
108111

112+
let error = str::from_utf8(output.error.as_slice()).unwrap();
109113
let output = str::from_utf8(output.output.as_slice()).unwrap();
110114
let mut lines = output.lines();
111-
let dylib_parts: Vec<&str> = lines.next().unwrap().trim()
112-
.split('-').collect();
113-
assert!(dylib_parts.len() == 2,
114-
"rustc --print-file-name output has changed");
115+
let dylib = if error.contains("dropping unsupported crate type `dylib`") {
116+
None
117+
} else {
118+
let dylib_parts: Vec<&str> = lines.next().unwrap().trim()
119+
.split('-').collect();
120+
assert!(dylib_parts.len() == 2,
121+
"rustc --print-file-name output has changed");
122+
Some((dylib_parts[0].to_string(), dylib_parts[1].to_string()))
123+
};
124+
115125
let exe_suffix = lines.next().unwrap().trim()
116126
.split('-').skip(1).next().unwrap().to_string();
117-
118-
Ok(((dylib_parts[0].to_string(), dylib_parts[1].to_string()),
119-
exe_suffix.to_string()))
127+
Ok((dylib, exe_suffix.to_string()))
120128
}
121129

122130
/// Prepare this context, ensuring that all filesystem directories are in
@@ -193,9 +201,17 @@ impl<'a, 'b> Context<'a, 'b> {
193201
///
194202
/// If `plugin` is true, the pair corresponds to the host platform,
195203
/// otherwise it corresponds to the target platform.
196-
fn dylib(&self, kind: Kind) -> (&str, &str) {
197-
let pair = if kind == KindPlugin {&self.host_dylib} else {&self.target_dylib};
198-
(pair.ref0().as_slice(), pair.ref1().as_slice())
204+
fn dylib(&self, kind: Kind) -> CargoResult<(&str, &str)> {
205+
let (triple, pair) = if kind == KindPlugin {
206+
(&self.host_triple, &self.host_dylib)
207+
} else {
208+
(&self.target_triple, &self.target_dylib)
209+
};
210+
match *pair {
211+
None => return Err(human(format!("dylib outputs are not supported \
212+
for {}", triple))),
213+
Some((ref s1, ref s2)) => Ok((s1.as_slice(), s2.as_slice())),
214+
}
199215
}
200216

201217
/// Return the target triple which this context is targeting.
@@ -204,7 +220,7 @@ impl<'a, 'b> Context<'a, 'b> {
204220
}
205221

206222
/// Return the exact filename of the target.
207-
pub fn target_filenames(&self, target: &Target) -> Vec<String> {
223+
pub fn target_filenames(&self, target: &Target) -> CargoResult<Vec<String>> {
208224
let stem = target.file_stem();
209225

210226
let mut ret = Vec::new();
@@ -214,7 +230,7 @@ impl<'a, 'b> Context<'a, 'b> {
214230
if target.is_dylib() {
215231
let plugin = target.get_profile().is_plugin();
216232
let kind = if plugin {KindPlugin} else {KindTarget};
217-
let (prefix, suffix) = self.dylib(kind);
233+
let (prefix, suffix) = try!(self.dylib(kind));
218234
ret.push(format!("{}{}{}", prefix, stem, suffix));
219235
}
220236
if target.is_rlib() {
@@ -225,7 +241,7 @@ impl<'a, 'b> Context<'a, 'b> {
225241
}
226242
}
227243
assert!(ret.len() > 0);
228-
return ret;
244+
return Ok(ret);
229245
}
230246

231247
/// For a package, return all targets which are registered as dependencies

src/cargo/ops/cargo_rustc/fingerprint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target,
7373
if !target.get_profile().is_doc() {
7474
pairs.push((old_dep_info, new_dep_info));
7575

76-
for filename in cx.target_filenames(target).iter() {
76+
for filename in try!(cx.target_filenames(target)).iter() {
7777
let filename = filename.as_slice();
7878
let dst = root.join(filename);
7979
pairs.push((old_root.join(filename), root.join(filename)));

src/cargo/ops/cargo_rustc/mod.rs

+28-22
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package,
135135
let (mut libs, mut bins) = (Vec::new(), Vec::new());
136136
for &target in targets.iter() {
137137
let work = if target.get_profile().is_doc() {
138-
vec![(rustdoc(pkg, target, cx), KindTarget)]
138+
vec![(try!(rustdoc(pkg, target, cx)), KindTarget)]
139139
} else {
140140
let req = cx.get_requirement(pkg, target);
141-
rustc(pkg, target, cx, req)
141+
try!(rustc(pkg, target, cx, req))
142142
};
143143

144144
let dst = if target.is_lib() {&mut libs} else {&mut bins};
@@ -188,15 +188,16 @@ fn compile_custom(pkg: &Package, cmd: &str,
188188
}
189189

190190
fn rustc(package: &Package, target: &Target,
191-
cx: &mut Context, req: PlatformRequirement) -> Vec<(Work, Kind)> {
191+
cx: &mut Context, req: PlatformRequirement)
192+
-> CargoResult<Vec<(Work, Kind)> >{
192193
let crate_types = target.rustc_crate_types();
193194
let root = package.get_root();
194195

195196
log!(5, "root={}; target={}; crate_types={}; verbose={}; req={}",
196197
root.display(), target, crate_types, cx.primary, req);
197198

198199
let primary = cx.primary;
199-
let rustcs = prepare_rustc(package, target, crate_types, cx, req);
200+
let rustcs = try!(prepare_rustc(package, target, crate_types, cx, req));
200201

201202
let _ = cx.config.shell().verbose(|shell| {
202203
for &(ref rustc, _) in rustcs.iter() {
@@ -205,7 +206,7 @@ fn rustc(package: &Package, target: &Target,
205206
Ok(())
206207
});
207208

208-
rustcs.move_iter().map(|(rustc, kind)| {
209+
Ok(rustcs.move_iter().map(|(rustc, kind)| {
209210
let name = package.get_name().to_string();
210211

211212
(proc() {
@@ -223,40 +224,43 @@ fn rustc(package: &Package, target: &Target,
223224
}
224225
Ok(())
225226
}, kind)
226-
}).collect()
227+
}).collect())
227228
}
228229

229230
fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>,
230231
cx: &Context, req: PlatformRequirement)
231-
-> Vec<(ProcessBuilder, Kind)> {
232+
-> CargoResult<Vec<(ProcessBuilder, Kind)>> {
232233
let base = process("rustc", package, cx);
233234
let base = build_base_args(base, target, crate_types.as_slice());
234235

235236
let target_cmd = build_plugin_args(base.clone(), cx, package, target, KindTarget);
236237
let plugin_cmd = build_plugin_args(base, cx, package, target, KindPlugin);
237-
let target_cmd = build_deps_args(target_cmd, target, package, cx, KindTarget);
238-
let plugin_cmd = build_deps_args(plugin_cmd, target, package, cx, KindPlugin);
238+
let target_cmd = try!(build_deps_args(target_cmd, target, package, cx,
239+
KindTarget));
240+
let plugin_cmd = try!(build_deps_args(plugin_cmd, target, package, cx,
241+
KindPlugin));
239242

240-
match req {
243+
Ok(match req {
241244
Target => vec![(target_cmd, KindTarget)],
242245
Plugin => vec![(plugin_cmd, KindPlugin)],
243246
PluginAndTarget if cx.config.target().is_none() =>
244247
vec![(target_cmd, KindTarget)],
245248
PluginAndTarget => vec![(target_cmd, KindTarget),
246249
(plugin_cmd, KindPlugin)],
247-
}
250+
})
248251
}
249252

250253

251-
fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> Work {
254+
fn rustdoc(package: &Package, target: &Target,
255+
cx: &mut Context) -> CargoResult<Work> {
252256
let kind = KindTarget;
253257
let pkg_root = package.get_root();
254258
let cx_root = cx.layout(kind).proxy().dest().join("doc");
255259
let rustdoc = process("rustdoc", package, cx).cwd(pkg_root.clone());
256260
let rustdoc = rustdoc.arg(target.get_src_path())
257261
.arg("-o").arg(cx_root)
258262
.arg("--crate-name").arg(target.get_name());
259-
let rustdoc = build_deps_args(rustdoc, target, package, cx, kind);
263+
let rustdoc = try!(build_deps_args(rustdoc, target, package, cx, kind));
260264

261265
log!(5, "commands={}", rustdoc);
262266

@@ -266,7 +270,7 @@ fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> Work {
266270

267271
let primary = cx.primary;
268272
let name = package.get_name().to_string();
269-
proc() {
273+
Ok(proc() {
270274
if primary {
271275
try!(rustdoc.exec().chain_error(|| {
272276
human(format!("Could not document `{}`.", name))
@@ -278,7 +282,7 @@ fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> Work {
278282
}))
279283
}
280284
Ok(())
281-
}
285+
})
282286
}
283287

284288
fn build_base_args(mut cmd: ProcessBuilder,
@@ -355,7 +359,8 @@ fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package,
355359
}
356360

357361
fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
358-
cx: &Context, kind: Kind) -> ProcessBuilder {
362+
cx: &Context,
363+
kind: Kind) -> CargoResult<ProcessBuilder> {
359364
enum LinkReason { Dependency, LocalLib }
360365

361366
let layout = cx.layout(kind);
@@ -367,7 +372,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
367372
cmd = push_native_dirs(cmd, &layout, package, cx, &mut HashSet::new());
368373

369374
for &(_, target) in cx.dep_targets(package).iter() {
370-
cmd = link_to(cmd, target, cx, kind, Dependency);
375+
cmd = try!(link_to(cmd, target, cx, kind, Dependency));
371376
}
372377

373378
let mut targets = package.get_targets().iter().filter(|target| {
@@ -376,14 +381,15 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
376381

377382
if target.is_bin() {
378383
for target in targets {
379-
cmd = link_to(cmd, target, cx, kind, LocalLib);
384+
cmd = try!(link_to(cmd, target, cx, kind, LocalLib));
380385
}
381386
}
382387

383-
return cmd;
388+
return Ok(cmd);
384389

385390
fn link_to(mut cmd: ProcessBuilder, target: &Target,
386-
cx: &Context, kind: Kind, reason: LinkReason) -> ProcessBuilder {
391+
cx: &Context, kind: Kind,
392+
reason: LinkReason) -> CargoResult<ProcessBuilder> {
387393
// If this target is itself a plugin *or* if it's being linked to a
388394
// plugin, then we want the plugin directory. Otherwise we want the
389395
// target directory (hence the || here).
@@ -393,7 +399,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
393399
KindTarget => KindTarget,
394400
});
395401

396-
for filename in cx.target_filenames(target).iter() {
402+
for filename in try!(cx.target_filenames(target)).iter() {
397403
let mut v = Vec::new();
398404
v.push_all(target.get_name().as_bytes());
399405
v.push(b'=');
@@ -405,7 +411,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
405411
v.push_all(filename.as_bytes());
406412
cmd = cmd.arg("--extern").arg(v.as_slice());
407413
}
408-
return cmd;
414+
return Ok(cmd);
409415
}
410416

411417
fn push_native_dirs(mut cmd: ProcessBuilder, layout: &layout::LayoutProxy,

tests/test_cargo_cross_compile.rs

+19
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,22 @@ test!(simple_cargo_run {
456456
assert_that(p.cargo_process("run").arg("--target").arg(target),
457457
execs().with_status(0));
458458
})
459+
460+
test!(cross_but_no_dylibs {
461+
let p = project("foo")
462+
.file("Cargo.toml", r#"
463+
[package]
464+
name = "foo"
465+
version = "0.0.0"
466+
authors = []
467+
468+
[lib]
469+
name = "foo"
470+
crate-type = ["dylib"]
471+
"#)
472+
.file("src/lib.rs", "");
473+
assert_that(p.cargo_process("build").arg("--target").arg("arm-apple-ios"),
474+
execs().with_status(101)
475+
.with_stderr("dylib outputs are not supported for \
476+
arm-apple-ios"));
477+
})

0 commit comments

Comments
 (0)