Skip to content

Commit cc34113

Browse files
emberianeddyb
authored andcommitted
Implement flexible target specification
Removes all target-specific knowledge from rustc. Some targets have changed during this, but none of these should be very visible outside of cross-compilation. The changes make our targets more consistent. iX86-unknown-linux-gnu is now only available as i686-unknown-linux-gnu. We used to accept any value of X greater than 1. i686 was released in 1995, and should encompass the bare minimum of what Rust supports on x86 CPUs. The only two windows targets are now i686-pc-windows-gnu and x86_64-pc-windows-gnu. The iOS target has been renamed from arm-apple-ios to arm-apple-darwin. A complete list of the targets we accept now: arm-apple-darwin arm-linux-androideabi arm-unknown-linux-gnueabi arm-unknown-linux-gnueabihf i686-apple-darwin i686-pc-windows-gnu i686-unknown-freebsd i686-unknown-linux-gnu mips-unknown-linux-gnu mipsel-unknown-linux-gnu x86_64-apple-darwin x86_64-unknown-freebsd x86_64-unknown-linux-gnu x86_64-pc-windows-gnu Closes rust-lang#16093 [breaking-change]
1 parent 5d335c9 commit cc34113

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1539
-840
lines changed

configure

+5-6
Original file line numberDiff line numberDiff line change
@@ -306,37 +306,36 @@ case $CFG_OSTYPE in
306306
# instead, msys defines $MSYSTEM which is MINGW32 on i686 and
307307
# MINGW64 on x86_64.
308308
CFG_CPUTYPE=i686
309-
CFG_OSTYPE=w64-mingw32
309+
CFG_OSTYPE=pc-windows-gnu
310310
if [ "$MSYSTEM" = MINGW64 ]
311311
then
312312
CFG_CPUTYPE=x86_64
313-
CFG_OSTYPE=w64-mingw32
314313
fi
315314
;;
316315

317316
# Thad's Cygwin identifers below
318317

319318
# Vista 32 bit
320319
CYGWIN_NT-6.0)
321-
CFG_OSTYPE=pc-mingw32
320+
CFG_OSTYPE=pc-windows-gnu
322321
CFG_CPUTYPE=i686
323322
;;
324323

325324
# Vista 64 bit
326325
CYGWIN_NT-6.0-WOW64)
327-
CFG_OSTYPE=w64-mingw32
326+
CFG_OSTYPE=pc-windows-gnu
328327
CFG_CPUTYPE=x86_64
329328
;;
330329

331330
# Win 7 32 bit
332331
CYGWIN_NT-6.1)
333-
CFG_OSTYPE=pc-mingw32
332+
CFG_OSTYPE=pc-windows-gnu
334333
CFG_CPUTYPE=i686
335334
;;
336335

337336
# Win 7 64 bit
338337
CYGWIN_NT-6.1-WOW64)
339-
CFG_OSTYPE=w64-mingw32
338+
CFG_OSTYPE=pc-windows-gnu
340339
CFG_CPUTYPE=x86_64
341340
;;
342341

mk/platform.mk

+151-180
Large diffs are not rendered by default.

src/librustc/back/link.rs

+88-183
Large diffs are not rendered by default.

src/librustc/back/write.rs

+27-32
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use driver::config;
1717
use llvm;
1818
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
1919
use util::common::time;
20-
use syntax::abi;
2120
use syntax::codemap;
2221
use syntax::diagnostic;
2322
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
@@ -151,20 +150,8 @@ impl Emitter for SharedEmitter {
151150
// Note that without those flags various linking errors might
152151
// arise as some of intrinsics are converted into function calls
153152
// and nobody provides implementations those functions
154-
fn target_feature<'a>(sess: &'a Session) -> &'a str {
155-
match sess.targ_cfg.os {
156-
abi::OsAndroid => {
157-
if "" == sess.opts.cg.target_feature.as_slice() {
158-
"+v7"
159-
} else {
160-
sess.opts.cg.target_feature.as_slice()
161-
}
162-
},
163-
abi::OsiOS if sess.targ_cfg.arch == abi::Arm => {
164-
"+v7,+thumb2,+vfp3,+neon"
165-
},
166-
_ => sess.opts.cg.target_feature.as_slice()
167-
}
153+
fn target_feature(sess: &Session) -> String {
154+
format!("{},{}", sess.target.target.options.features, sess.opts.cg.target_feature)
168155
}
169156

170157
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
@@ -177,7 +164,11 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
177164
}
178165

179166
fn create_target_machine(sess: &Session) -> TargetMachineRef {
180-
let reloc_model = match sess.opts.cg.relocation_model.as_slice() {
167+
let reloc_model_arg = match sess.opts.cg.relocation_model {
168+
Some(ref s) => s.as_slice(),
169+
None => sess.target.target.options.relocation_model.as_slice()
170+
};
171+
let reloc_model = match reloc_model_arg {
181172
"pic" => llvm::RelocPIC,
182173
"static" => llvm::RelocStatic,
183174
"default" => llvm::RelocDefault,
@@ -196,18 +187,18 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
196187
let use_softfp = sess.opts.cg.soft_float;
197188

198189
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
199-
// FIXME: #11954: mac64 unwinding may not work with fp elim
200190
let no_fp_elim = (sess.opts.debuginfo != NoDebugInfo) ||
201-
(sess.targ_cfg.os == abi::OsMacos &&
202-
sess.targ_cfg.arch == abi::X86_64);
191+
!sess.target.target.options.eliminate_frame_pointer;
203192

204-
// OSX has -dead_strip, which doesn't rely on ffunction_sections
205-
// FIXME(#13846) this should be enabled for windows
206-
let ffunction_sections = sess.targ_cfg.os != abi::OsMacos &&
207-
sess.targ_cfg.os != abi::OsWindows;
193+
let ffunction_sections = sess.target.target.options.function_sections;
208194
let fdata_sections = ffunction_sections;
209195

210-
let code_model = match sess.opts.cg.code_model.as_slice() {
196+
let code_model_arg = match sess.opts.cg.code_model {
197+
Some(ref s) => s.as_slice(),
198+
None => sess.target.target.options.code_model.as_slice()
199+
};
200+
201+
let code_model = match code_model_arg {
211202
"default" => llvm::CodeModelDefault,
212203
"small" => llvm::CodeModelSmall,
213204
"kernel" => llvm::CodeModelKernel,
@@ -224,12 +215,14 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
224215
};
225216

226217
unsafe {
227-
sess.targ_cfg
228-
.target_strs
229-
.target_triple
230-
.as_slice()
231-
.with_c_str(|t| {
232-
sess.opts.cg.target_cpu.as_slice().with_c_str(|cpu| {
218+
sess.target.target
219+
.llvm_target
220+
.as_slice()
221+
.with_c_str(|t| {
222+
match sess.opts.cg.target_cpu {
223+
Some(ref s) => s.as_slice(),
224+
None => sess.target.target.options.cpu.as_slice()
225+
}.with_c_str(|cpu| {
233226
target_feature(sess).with_c_str(|features| {
234227
llvm::LLVMRustCreateTargetMachine(
235228
t, cpu, features,
@@ -654,7 +647,7 @@ pub fn run_passes(sess: &Session,
654647
// the desired path. This will give the correct behavior whether or
655648
// not GCC adds --force-exe-suffix.
656649
let windows_output_path =
657-
if sess.targ_cfg.os == abi::OsWindows {
650+
if sess.target.target.options.is_like_windows {
658651
Some(output_path.with_extension("o.exe"))
659652
} else {
660653
None
@@ -663,7 +656,7 @@ pub fn run_passes(sess: &Session,
663656
let pname = get_cc_prog(sess);
664657
let mut cmd = Command::new(pname.as_slice());
665658

666-
cmd.args(sess.targ_cfg.target_strs.cc_args.as_slice());
659+
cmd.args(sess.target.target.options.pre_link_args.as_slice());
667660
cmd.arg("-nostdlib");
668661

669662
for index in range(0, trans.modules.len()) {
@@ -674,6 +667,8 @@ pub fn run_passes(sess: &Session,
674667
.arg("-o")
675668
.arg(windows_output_path.as_ref().unwrap_or(output_path));
676669

670+
cmd.args(sess.target.target.options.post_link_args.as_slice());
671+
677672
if (sess.opts.debugging_opts & config::PRINT_LINK_ARGS) != 0 {
678673
println!("{}", &cmd);
679674
}

src/librustc/driver/config.rs

+53-104
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ use driver::session::Session;
1717

1818
use back;
1919
use back::write;
20-
use back::target_strs;
21-
use back::{arm, x86, x86_64, mips, mipsel};
20+
use rustc_back::target::Target;
2221
use lint;
2322

24-
use syntax::abi;
2523
use syntax::ast;
2624
use syntax::ast::{IntTy, UintTy};
2725
use syntax::attr;
2826
use syntax::attr::AttrMetaMethods;
29-
use syntax::diagnostic::{ColorConfig, Auto, Always, Never};
27+
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
3028
use syntax::parse;
3129
use syntax::parse::token::InternedString;
3230

@@ -39,9 +37,7 @@ use std::fmt;
3937
use llvm;
4038

4139
pub struct Config {
42-
pub os: abi::Os,
43-
pub arch: abi::Architecture,
44-
pub target_strs: target_strs::t,
40+
pub target: Target,
4541
pub int_type: IntTy,
4642
pub uint_type: UintTy,
4743
}
@@ -291,6 +287,13 @@ macro_rules! cgoptions(
291287
}
292288
}
293289

290+
fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
291+
match v {
292+
Some(..) => false,
293+
None => { *slot = Some(true); true }
294+
}
295+
}
296+
294297
fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
295298
match v {
296299
Some(s) => { *slot = Some(s.to_string()); true },
@@ -318,6 +321,18 @@ macro_rules! cgoptions(
318321
}
319322
}
320323

324+
fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
325+
-> bool {
326+
match v {
327+
Some(s) => {
328+
let v = s.words().map(|s| s.to_string()).collect();
329+
*slot = Some(v);
330+
true
331+
},
332+
None => false,
333+
}
334+
}
335+
321336
fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
322337
use std::from_str::FromStr;
323338
match v.and_then(FromStr::from_str) {
@@ -351,9 +366,9 @@ cgoptions!(
351366
"tool to assemble archives with"),
352367
linker: Option<String> = (None, parse_opt_string,
353368
"system linker to link outputs with"),
354-
link_args: Vec<String> = (Vec::new(), parse_list,
369+
link_args: Option<Vec<String>> = (None, parse_opt_list,
355370
"extra arguments to pass to the linker (space separated)"),
356-
target_cpu: String = ("generic".to_string(), parse_string,
371+
target_cpu: Option<String> = (None, parse_opt_string,
357372
"select target processor (llc -mcpu=help for details)"),
358373
target_feature: String = ("".to_string(), parse_string,
359374
"target specific attributes (llc -mattr=help for details)"),
@@ -377,11 +392,11 @@ cgoptions!(
377392
"prefer dynamic linking to static linking"),
378393
no_integrated_as: bool = (false, parse_bool,
379394
"use an external assembler rather than LLVM's integrated one"),
380-
no_redzone: bool = (false, parse_bool,
395+
no_redzone: Option<bool> = (None, parse_opt_bool,
381396
"disable the use of the redzone"),
382-
relocation_model: String = ("pic".to_string(), parse_string,
397+
relocation_model: Option<String> = (None, parse_opt_string,
383398
"choose the relocation model to use (llc -relocation-model for details)"),
384-
code_model: String = ("default".to_string(), parse_string,
399+
code_model: Option<String> = (None, parse_opt_string,
385400
"choose the code model to use (llc -code-model for details)"),
386401
metadata: Vec<String> = (Vec::new(), parse_list,
387402
"metadata to mangle symbol names with"),
@@ -433,40 +448,27 @@ pub fn default_lib_output() -> CrateType {
433448
}
434449

435450
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
436-
let tos = match sess.targ_cfg.os {
437-
abi::OsWindows => InternedString::new("windows"),
438-
abi::OsMacos => InternedString::new("macos"),
439-
abi::OsLinux => InternedString::new("linux"),
440-
abi::OsAndroid => InternedString::new("android"),
441-
abi::OsFreebsd => InternedString::new("freebsd"),
442-
abi::OsDragonfly => InternedString::new("dragonfly"),
443-
abi::OsiOS => InternedString::new("ios"),
444-
};
451+
use syntax::parse::token::intern_and_get_ident as intern;
445452

446-
// ARM is bi-endian, however using NDK seems to default
447-
// to little-endian unless a flag is provided.
448-
let (end,arch,wordsz) = match sess.targ_cfg.arch {
449-
abi::X86 => ("little", "x86", "32"),
450-
abi::X86_64 => ("little", "x86_64", "64"),
451-
abi::Arm => ("little", "arm", "32"),
452-
abi::Mips => ("big", "mips", "32"),
453-
abi::Mipsel => ("little", "mipsel", "32")
454-
};
453+
let end = sess.target.target.target_endian.as_slice();
454+
let arch = sess.target.target.arch.as_slice();
455+
let wordsz = sess.target.target.target_word_size.as_slice();
456+
let os = sess.target.target.target_os.as_slice();
455457

456-
let fam = match sess.targ_cfg.os {
457-
abi::OsWindows => InternedString::new("windows"),
458-
_ => InternedString::new("unix")
458+
let fam = match sess.target.target.options.is_like_windows {
459+
true => InternedString::new("windows"),
460+
false => InternedString::new("unix")
459461
};
460462

461463
let mk = attr::mk_name_value_item_str;
462464
return vec!(// Target bindings.
463465
attr::mk_word_item(fam.clone()),
464-
mk(InternedString::new("target_os"), tos),
466+
mk(InternedString::new("target_os"), intern(os)),
465467
mk(InternedString::new("target_family"), fam),
466-
mk(InternedString::new("target_arch"), InternedString::new(arch)),
467-
mk(InternedString::new("target_endian"), InternedString::new(end)),
468+
mk(InternedString::new("target_arch"), intern(arch)),
469+
mk(InternedString::new("target_endian"), intern(end)),
468470
mk(InternedString::new("target_word_size"),
469-
InternedString::new(wordsz))
471+
intern(wordsz))
470472
);
471473
}
472474

@@ -489,76 +491,23 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
489491
user_cfg.into_iter().collect::<Vec<_>>().append(default_cfg.as_slice())
490492
}
491493

492-
pub fn get_os(triple: &str) -> Option<abi::Os> {
493-
for &(name, os) in os_names.iter() {
494-
if triple.contains(name) { return Some(os) }
495-
}
496-
None
497-
}
498-
static os_names : &'static [(&'static str, abi::Os)] = &[
499-
("mingw32", abi::OsWindows),
500-
("win32", abi::OsWindows),
501-
("windows", abi::OsWindows),
502-
("darwin", abi::OsMacos),
503-
("android", abi::OsAndroid),
504-
("linux", abi::OsLinux),
505-
("freebsd", abi::OsFreebsd),
506-
("dragonfly", abi::OsDragonfly),
507-
("ios", abi::OsiOS)];
508-
509-
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
510-
for &(arch, abi) in architecture_abis.iter() {
511-
if triple.contains(arch) { return Some(abi) }
512-
}
513-
None
514-
}
515-
static architecture_abis : &'static [(&'static str, abi::Architecture)] = &[
516-
("i386", abi::X86),
517-
("i486", abi::X86),
518-
("i586", abi::X86),
519-
("i686", abi::X86),
520-
("i786", abi::X86),
521-
522-
("x86_64", abi::X86_64),
523-
524-
("arm", abi::Arm),
525-
("xscale", abi::Arm),
526-
("thumb", abi::Arm),
527-
528-
("mipsel", abi::Mipsel),
529-
("mips", abi::Mips)];
530-
531-
pub fn build_target_config(sopts: &Options) -> Config {
532-
let os = match get_os(sopts.target_triple.as_slice()) {
533-
Some(os) => os,
534-
None => early_error("unknown operating system")
535-
};
536-
let arch = match get_arch(sopts.target_triple.as_slice()) {
537-
Some(arch) => arch,
538-
None => {
539-
early_error(format!("unknown architecture: {}",
540-
sopts.target_triple.as_slice()).as_slice())
541-
}
542-
};
543-
let (int_type, uint_type) = match arch {
544-
abi::X86 => (ast::TyI32, ast::TyU32),
545-
abi::X86_64 => (ast::TyI64, ast::TyU64),
546-
abi::Arm => (ast::TyI32, ast::TyU32),
547-
abi::Mips => (ast::TyI32, ast::TyU32),
548-
abi::Mipsel => (ast::TyI32, ast::TyU32)
494+
pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
495+
let target = match Target::search(opts.target_triple.as_slice()) {
496+
Ok(t) => t,
497+
Err(e) => {
498+
sp.handler().fatal((format!("Error loading target specification: {}", e)).as_slice());
499+
}
549500
};
550-
let target_triple = sopts.target_triple.clone();
551-
let target_strs = match arch {
552-
abi::X86 => x86::get_target_strs(target_triple, os),
553-
abi::X86_64 => x86_64::get_target_strs(target_triple, os),
554-
abi::Arm => arm::get_target_strs(target_triple, os),
555-
abi::Mips => mips::get_target_strs(target_triple, os),
556-
abi::Mipsel => mipsel::get_target_strs(target_triple, os)
501+
502+
let (int_type, uint_type) = match target.target_word_size.as_slice() {
503+
"32" => (ast::TyI32, ast::TyU32),
504+
"64" => (ast::TyI64, ast::TyU64),
505+
w => sp.handler().fatal((format!("target specification was invalid: unrecognized \
506+
target-word-size {}", w)).as_slice())
557507
};
508+
558509
Config {
559-
os: os,
560-
arch: arch,
561-
target_strs: target_strs,
510+
target: target,
562511
int_type: int_type,
563512
uint_type: uint_type,
564513
}

0 commit comments

Comments
 (0)