4747use serialize:: json:: { Json , ToJson } ;
4848use std:: collections:: BTreeMap ;
4949use std:: default:: Default ;
50+ use std:: fmt;
51+ use std:: path:: { Path , PathBuf } ;
5052use syntax:: abi:: { Abi , lookup as lookup_abi} ;
5153
5254use { LinkerFlavor , PanicStrategy , RelroLevel } ;
@@ -824,11 +826,10 @@ impl Target {
824826 ///
825827 /// The error string could come from any of the APIs called, including
826828 /// filesystem access and JSON decoding.
827- pub fn search ( target : & str ) -> Result < Target , String > {
829+ pub fn search ( target_triple : & TargetTriple ) -> Result < Target , String > {
828830 use std:: env;
829831 use std:: ffi:: OsString ;
830832 use std:: fs;
831- use std:: path:: { Path , PathBuf } ;
832833 use serialize:: json;
833834
834835 fn load_file ( path : & Path ) -> Result < Target , String > {
@@ -838,35 +839,40 @@ impl Target {
838839 Target :: from_json ( obj)
839840 }
840841
841- if let Ok ( t) = load_specific ( target) {
842- return Ok ( t)
843- }
844-
845- let path = Path :: new ( target) ;
846-
847- if path. is_file ( ) {
848- return load_file ( & path) ;
849- }
842+ match target_triple {
843+ & TargetTriple :: TargetTriple ( ref target_triple) => {
844+ // check if triple is in list of supported targets
845+ if let Ok ( t) = load_specific ( target_triple) {
846+ return Ok ( t)
847+ }
850848
851- let path = {
852- let mut target = target. to_string ( ) ;
853- target. push_str ( ".json" ) ;
854- PathBuf :: from ( target)
855- } ;
849+ // search for a file named `target_triple`.json in RUST_TARGET_PATH
850+ let path = {
851+ let mut target = target_triple. to_string ( ) ;
852+ target. push_str ( ".json" ) ;
853+ PathBuf :: from ( target)
854+ } ;
856855
857- let target_path = env:: var_os ( "RUST_TARGET_PATH" )
858- . unwrap_or ( OsString :: new ( ) ) ;
856+ let target_path = env:: var_os ( "RUST_TARGET_PATH" )
857+ . unwrap_or ( OsString :: new ( ) ) ;
859858
860- // FIXME 16351: add a sane default search path?
859+ // FIXME 16351: add a sane default search path?
861860
862- for dir in env:: split_paths ( & target_path) {
863- let p = dir. join ( & path) ;
864- if p. is_file ( ) {
865- return load_file ( & p) ;
861+ for dir in env:: split_paths ( & target_path) {
862+ let p = dir. join ( & path) ;
863+ if p. is_file ( ) {
864+ return load_file ( & p) ;
865+ }
866+ }
867+ Err ( format ! ( "Could not find specification for target {:?}" , target_triple) )
868+ }
869+ & TargetTriple :: TargetPath ( ref target_path) => {
870+ if target_path. is_file ( ) {
871+ return load_file ( & target_path) ;
872+ }
873+ Err ( format ! ( "Target path {:?} is not a valid file" , target_path) )
866874 }
867875 }
868-
869- Err ( format ! ( "Could not find specification for target {:?}" , target) )
870876 }
871877}
872878
@@ -1014,3 +1020,36 @@ fn maybe_jemalloc() -> Option<String> {
10141020 None
10151021 }
10161022}
1023+
1024+ /// Either a target triple string or a path to a JSON file.
1025+ #[ derive( PartialEq , Clone , Debug , Hash , RustcEncodable , RustcDecodable ) ]
1026+ pub enum TargetTriple {
1027+ TargetTriple ( String ) ,
1028+ TargetPath ( PathBuf ) ,
1029+ }
1030+
1031+ impl TargetTriple {
1032+ /// Creates a target target from the passed target triple string.
1033+ pub fn from_triple ( triple : & str ) -> Self {
1034+ TargetTriple :: TargetTriple ( triple. to_string ( ) )
1035+ }
1036+
1037+ /// Returns a string triple for this target.
1038+ ///
1039+ /// If this target is a path, the file name (without extension) is returned.
1040+ pub fn triple ( & self ) -> & str {
1041+ match self {
1042+ & TargetTriple :: TargetTriple ( ref triple) => triple,
1043+ & TargetTriple :: TargetPath ( ref path) => {
1044+ path. file_stem ( ) . expect ( "target path must not be empty" ) . to_str ( )
1045+ . expect ( "target path must be valid unicode" )
1046+ }
1047+ }
1048+ }
1049+ }
1050+
1051+ impl fmt:: Display for TargetTriple {
1052+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1053+ write ! ( f, "{}" , self . triple( ) )
1054+ }
1055+ }
0 commit comments