12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
+ use ar;
15
16
use compiler:: { Cacheable , ColorMode , Compiler , CompilerArguments , CompileCommand , CompilerHasher , CompilerKind ,
16
17
Compilation , HashResult } ;
17
18
use compiler:: args:: * ;
@@ -89,6 +90,8 @@ pub struct ParsedArguments {
89
90
staticlibs : Vec < PathBuf > ,
90
91
/// The crate name passed to --crate-name.
91
92
crate_name : String ,
93
+ /// The crate types that will be generated
94
+ crate_types : CrateTypes ,
92
95
/// If dependency info is being emitted, the name of the dep info file.
93
96
dep_info : Option < PathBuf > ,
94
97
/// The value of any `--color` option passed on the commandline.
@@ -112,14 +115,16 @@ pub struct RustCompilation {
112
115
crate_link_paths : Vec < PathBuf > ,
113
116
/// The crate name being compiled.
114
117
crate_name : String ,
118
+ /// The crate types that will be generated
119
+ crate_types : CrateTypes ,
115
120
/// The current working directory
116
121
cwd : PathBuf ,
117
122
/// The environment variables
118
123
env_vars : Vec < ( OsString , OsString ) > ,
119
124
}
120
125
121
126
// The selection of crate types for this compilation
122
- #[ derive( Debug , Clone ) ]
127
+ #[ derive( Debug , Clone , PartialEq ) ]
123
128
pub struct CrateTypes {
124
129
rlib : bool ,
125
130
staticlib : bool ,
@@ -791,6 +796,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
791
796
CompilerArguments :: Ok ( ParsedArguments {
792
797
arguments : args,
793
798
output_dir : output_dir. into ( ) ,
799
+ crate_types,
794
800
externs : externs,
795
801
crate_link_paths,
796
802
staticlibs : staticlibs,
@@ -812,7 +818,7 @@ impl<T> CompilerHasher<T> for RustHasher
812
818
-> SFuture < HashResult >
813
819
{
814
820
let me = * self ;
815
- let RustHasher { executable, sysroot, compiler_shlibs_digests, parsed_args : ParsedArguments { arguments, output_dir, externs, crate_link_paths, staticlibs, crate_name, dep_info, color_mode : _ } } = me;
821
+ let RustHasher { executable, sysroot, compiler_shlibs_digests, parsed_args : ParsedArguments { arguments, output_dir, externs, crate_link_paths, staticlibs, crate_name, crate_types , dep_info, color_mode : _ } } = me;
816
822
trace ! ( "[{}]: generate_hash_key" , crate_name) ;
817
823
// TODO: this doesn't produce correct arguments if they should be concatenated - should use iter_os_strings
818
824
let os_string_arguments: Vec < ( OsString , Option < OsString > ) > = arguments. iter ( )
@@ -938,7 +944,8 @@ impl<T> CompilerHasher<T> for RustHasher
938
944
inputs : inputs,
939
945
outputs : outputs,
940
946
crate_link_paths,
941
- crate_name : crate_name,
947
+ crate_name,
948
+ crate_types,
942
949
cwd,
943
950
env_vars,
944
951
} ) ,
@@ -1005,7 +1012,7 @@ impl Compilation for RustCompilation {
1005
1012
1006
1013
#[ cfg( feature = "dist-client" ) ]
1007
1014
fn into_dist_inputs_creator ( self : Box < Self > , path_transformer : & mut dist:: PathTransformer ) -> Result < ( Box < FnMut ( & mut io:: Write ) > , Box < pkg:: CompilerPackager > ) > {
1008
- let RustCompilation { inputs, crate_link_paths, sysroot, .. } = * { self } ;
1015
+ let RustCompilation { inputs, crate_link_paths, sysroot, crate_types , .. } = * { self } ;
1009
1016
trace ! ( "Dist inputs: inputs={:?} crate_link_paths={:?}" , inputs, crate_link_paths) ;
1010
1017
1011
1018
let mut tar_inputs = vec ! [ ] ;
@@ -1046,10 +1053,37 @@ impl Compilation for RustCompilation {
1046
1053
// There are almost certainly duplicates from explicit externs also within the lib search paths
1047
1054
all_tar_inputs. dedup ( ) ;
1048
1055
1056
+ // If we're just creating an rlib then the only thing inspected inside dependency rlibs is the
1057
+ // metadata, in which case we can create a trimmed rlib (which is actually a .a) with the metadata
1058
+ let can_trim_rlibs = if let CrateTypes { rlib : true , staticlib : false } = crate_types { true } else { false } ;
1059
+
1049
1060
for ( input_path, dist_input_path) in all_tar_inputs. iter ( ) {
1050
1061
let mut file_header = pkg:: make_tar_header ( input_path, dist_input_path) . unwrap ( ) ;
1051
- file_header. set_cksum ( ) ;
1052
- builder. append ( & file_header, fs:: File :: open ( input_path) . unwrap ( ) ) . unwrap ( ) ;
1062
+ let file = fs:: File :: open ( input_path) . unwrap ( ) ;
1063
+ if can_trim_rlibs && input_path. extension ( ) . unwrap ( ) == "rlib" {
1064
+ let mut archive = ar:: Archive :: new ( file) ;
1065
+
1066
+ while let Some ( entry_result) = archive. next_entry ( ) {
1067
+ let mut entry = entry_result. unwrap ( ) ;
1068
+ if entry. header ( ) . identifier ( ) != b"rust.metadata.bin" {
1069
+ continue
1070
+ }
1071
+ let mut metadata = vec ! [ ] ;
1072
+ io:: copy ( & mut entry, & mut metadata) . unwrap ( ) ;
1073
+ let mut metadata_ar = vec ! [ ] ;
1074
+ {
1075
+ let mut ar_builder = ar:: Builder :: new ( & mut metadata_ar) ;
1076
+ ar_builder. append ( entry. header ( ) , metadata. as_slice ( ) ) . unwrap ( )
1077
+ }
1078
+ file_header. set_size ( metadata_ar. len ( ) as u64 ) ;
1079
+ file_header. set_cksum ( ) ;
1080
+ builder. append ( & file_header, metadata_ar. as_slice ( ) ) . unwrap ( ) ;
1081
+ break
1082
+ }
1083
+ } else {
1084
+ file_header. set_cksum ( ) ;
1085
+ builder. append ( & file_header, file) . unwrap ( )
1086
+ }
1053
1087
}
1054
1088
1055
1089
// Finish archive
@@ -1416,6 +1450,7 @@ c:/foo/bar.rs:
1416
1450
crate_link_paths : vec ! [ ] ,
1417
1451
staticlibs : vec ! [ f. tempdir. path( ) . join( "libbaz.a" ) ] ,
1418
1452
crate_name : "foo" . into ( ) ,
1453
+ crate_types : CrateTypes { rlib : true , staticlib : false } ,
1419
1454
dep_info : None ,
1420
1455
color_mode : ColorMode :: Auto ,
1421
1456
}
0 commit comments