@@ -7,7 +7,7 @@ use rustc::session::config::{
7
7
} ;
8
8
use rustc:: session:: search_paths:: PathKind ;
9
9
use rustc:: middle:: dependency_format:: Linkage ;
10
- use rustc:: middle:: cstore:: { LibSource , NativeLibrary , NativeLibraryKind } ;
10
+ use rustc:: middle:: cstore:: { EncodedMetadata , LibSource , NativeLibrary , NativeLibraryKind } ;
11
11
use rustc:: util:: common:: { time, time_ext} ;
12
12
use rustc:: hir:: def_id:: CrateNum ;
13
13
use rustc_data_structures:: fx:: FxHashSet ;
@@ -50,9 +50,9 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
50
50
outputs : & OutputFilenames ,
51
51
crate_name : & str ,
52
52
target_cpu : & str ) {
53
+ let output_metadata = sess. opts . output_types . contains_key ( & OutputType :: Metadata ) ;
53
54
for & crate_type in sess. crate_types . borrow ( ) . iter ( ) {
54
55
// Ignore executable crates if we have -Z no-codegen, as they will error.
55
- let output_metadata = sess. opts . output_types . contains_key ( & OutputType :: Metadata ) ;
56
56
if ( sess. opts . debugging_opts . no_codegen || !sess. opts . output_types . should_codegen ( ) ) &&
57
57
!output_metadata &&
58
58
crate_type == config:: CrateType :: Executable {
@@ -63,12 +63,43 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
63
63
bug ! ( "invalid output type `{:?}` for target os `{}`" ,
64
64
crate_type, sess. opts. target_triple) ;
65
65
}
66
- link_binary_output :: < B > ( sess,
67
- codegen_results,
68
- crate_type,
69
- outputs,
70
- crate_name,
71
- target_cpu) ;
66
+
67
+ for obj in codegen_results. modules . iter ( ) . filter_map ( |m| m. object . as_ref ( ) ) {
68
+ check_file_is_writeable ( obj, sess) ;
69
+ }
70
+
71
+ let tmpdir = TempFileBuilder :: new ( ) . prefix ( "rustc" ) . tempdir ( ) . unwrap_or_else ( |err|
72
+ sess. fatal ( & format ! ( "couldn't create a temp dir: {}" , err) ) ) ;
73
+
74
+ if outputs. outputs . should_codegen ( ) {
75
+ let out_filename = out_filename ( sess, crate_type, outputs, crate_name) ;
76
+ match crate_type {
77
+ config:: CrateType :: Rlib => {
78
+ link_rlib :: < B > ( sess,
79
+ codegen_results,
80
+ RlibFlavor :: Normal ,
81
+ & out_filename,
82
+ & tmpdir) . build ( ) ;
83
+ }
84
+ config:: CrateType :: Staticlib => {
85
+ link_staticlib :: < B > ( sess, codegen_results, & out_filename, & tmpdir) ;
86
+ }
87
+ _ => {
88
+ link_natively :: < B > (
89
+ sess,
90
+ crate_type,
91
+ & out_filename,
92
+ codegen_results,
93
+ tmpdir. path ( ) ,
94
+ target_cpu,
95
+ ) ;
96
+ }
97
+ }
98
+ }
99
+
100
+ if sess. opts . cg . save_temps {
101
+ let _ = tmpdir. into_path ( ) ;
102
+ }
72
103
}
73
104
74
105
// Remove the temporary object file and metadata if we aren't saving temps
@@ -85,7 +116,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
85
116
if let Some ( ref obj) = metadata_module. object {
86
117
remove ( sess, obj) ;
87
118
}
88
- }
119
+ }
89
120
if let Some ( ref allocator_module) = codegen_results. allocator_module {
90
121
if let Some ( ref obj) = allocator_module. object {
91
122
remove ( sess, obj) ;
@@ -97,73 +128,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
97
128
}
98
129
}
99
130
100
- fn link_binary_output < ' a , B : ArchiveBuilder < ' a > > ( sess : & ' a Session ,
101
- codegen_results : & CodegenResults ,
102
- crate_type : config:: CrateType ,
103
- outputs : & OutputFilenames ,
104
- crate_name : & str ,
105
- target_cpu : & str ) {
106
- for obj in codegen_results. modules . iter ( ) . filter_map ( |m| m. object . as_ref ( ) ) {
107
- check_file_is_writeable ( obj, sess) ;
108
- }
109
-
110
- if outputs. outputs . contains_key ( & OutputType :: Metadata ) {
111
- let out_filename = filename_for_metadata ( sess, crate_name, outputs) ;
112
- // To avoid races with another rustc process scanning the output directory,
113
- // we need to write the file somewhere else and atomically move it to its
114
- // final destination, with a `fs::rename` call. In order for the rename to
115
- // always succeed, the temporary file needs to be on the same filesystem,
116
- // which is why we create it inside the output directory specifically.
117
- let metadata_tmpdir = TempFileBuilder :: new ( )
118
- . prefix ( "rmeta" )
119
- . tempdir_in ( out_filename. parent ( ) . unwrap ( ) )
120
- . unwrap_or_else ( |err| sess. fatal ( & format ! ( "couldn't create a temp dir: {}" , err) ) ) ;
121
- let metadata = emit_metadata ( sess, codegen_results, & metadata_tmpdir) ;
122
- match fs:: rename ( & metadata, & out_filename) {
123
- Ok ( _) => {
124
- if sess. opts . debugging_opts . emit_directives {
125
- sess. parse_sess . span_diagnostic . maybe_emit_json_directive (
126
- format ! ( "metadata file written: {}" , out_filename. display( ) ) ) ;
127
- }
128
- }
129
- Err ( e) => sess. fatal ( & format ! ( "failed to write {}: {}" , out_filename. display( ) , e) ) ,
130
- }
131
- }
132
-
133
- let tmpdir = TempFileBuilder :: new ( ) . prefix ( "rustc" ) . tempdir ( ) . unwrap_or_else ( |err|
134
- sess. fatal ( & format ! ( "couldn't create a temp dir: {}" , err) ) ) ;
135
-
136
- if outputs. outputs . should_codegen ( ) {
137
- let out_filename = out_filename ( sess, crate_type, outputs, crate_name) ;
138
- match crate_type {
139
- config:: CrateType :: Rlib => {
140
- link_rlib :: < B > ( sess,
141
- codegen_results,
142
- RlibFlavor :: Normal ,
143
- & out_filename,
144
- & tmpdir) . build ( ) ;
145
- }
146
- config:: CrateType :: Staticlib => {
147
- link_staticlib :: < B > ( sess, codegen_results, & out_filename, & tmpdir) ;
148
- }
149
- _ => {
150
- link_natively :: < B > (
151
- sess,
152
- crate_type,
153
- & out_filename,
154
- codegen_results,
155
- tmpdir. path ( ) ,
156
- target_cpu,
157
- ) ;
158
- }
159
- }
160
- }
161
-
162
- if sess. opts . cg . save_temps {
163
- let _ = tmpdir. into_path ( ) ;
164
- }
165
- }
166
-
167
131
// The third parameter is for env vars, used on windows to set up the
168
132
// path for MSVC to find its DLLs, and gcc to find its bundled
169
133
// toolchain
@@ -261,13 +225,13 @@ pub fn each_linked_rlib(sess: &Session,
261
225
/// building an `.rlib` (stomping over one another), or writing an `.rmeta` into a
262
226
/// directory being searched for `extern crate` (observing an incomplete file).
263
227
/// The returned path is the temporary file containing the complete metadata.
264
- fn emit_metadata < ' a > (
228
+ pub fn emit_metadata < ' a > (
265
229
sess : & ' a Session ,
266
- codegen_results : & CodegenResults ,
230
+ metadata : & EncodedMetadata ,
267
231
tmpdir : & TempDir
268
232
) -> PathBuf {
269
233
let out_filename = tmpdir. path ( ) . join ( METADATA_FILENAME ) ;
270
- let result = fs:: write ( & out_filename, & codegen_results . metadata . raw_data ) ;
234
+ let result = fs:: write ( & out_filename, & metadata. raw_data ) ;
271
235
272
236
if let Err ( e) = result {
273
237
sess. fatal ( & format ! ( "failed to write {}: {}" , out_filename. display( ) , e) ) ;
@@ -351,7 +315,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
351
315
RlibFlavor :: Normal => {
352
316
// Instead of putting the metadata in an object file section, rlibs
353
317
// contain the metadata in a separate file.
354
- ab. add_file ( & emit_metadata ( sess, codegen_results, tmpdir) ) ;
318
+ ab. add_file ( & emit_metadata ( sess, & codegen_results. metadata , tmpdir) ) ;
355
319
356
320
// For LTO purposes, the bytecode of this library is also inserted
357
321
// into the archive.
0 commit comments