@@ -63,12 +63,66 @@ 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
+ if outputs. outputs . contains_key ( & OutputType :: Metadata ) {
72
+ let out_filename = filename_for_metadata ( sess, crate_name, outputs) ;
73
+ // To avoid races with another rustc process scanning the output directory,
74
+ // we need to write the file somewhere else and atomically move it to its
75
+ // final destination, with a `fs::rename` call. In order for the rename to
76
+ // always succeed, the temporary file needs to be on the same filesystem,
77
+ // which is why we create it inside the output directory specifically.
78
+ let metadata_tmpdir = TempFileBuilder :: new ( )
79
+ . prefix ( "rmeta" )
80
+ . tempdir_in ( out_filename. parent ( ) . unwrap ( ) )
81
+ . unwrap_or_else ( |err| sess. fatal ( & format ! ( "couldn't create a temp dir: {}" , err) ) ) ;
82
+ let metadata = emit_metadata ( sess, codegen_results, & metadata_tmpdir) ;
83
+ match fs:: rename ( & metadata, & out_filename) {
84
+ Ok ( _) => {
85
+ if sess. opts . debugging_opts . emit_directives {
86
+ sess. parse_sess . span_diagnostic . maybe_emit_json_directive (
87
+ format ! ( "metadata file written: {}" , out_filename. display( ) ) ) ;
88
+ }
89
+ }
90
+ Err ( e) => sess. fatal ( & format ! ( "failed to write {}: {}" , out_filename. display( ) , e) ) ,
91
+ }
92
+ }
93
+
94
+ let tmpdir = TempFileBuilder :: new ( ) . prefix ( "rustc" ) . tempdir ( ) . unwrap_or_else ( |err|
95
+ sess. fatal ( & format ! ( "couldn't create a temp dir: {}" , err) ) ) ;
96
+
97
+ if outputs. outputs . should_codegen ( ) {
98
+ let out_filename = out_filename ( sess, crate_type, outputs, crate_name) ;
99
+ match crate_type {
100
+ config:: CrateType :: Rlib => {
101
+ link_rlib :: < B > ( sess,
102
+ codegen_results,
103
+ RlibFlavor :: Normal ,
104
+ & out_filename,
105
+ & tmpdir) . build ( ) ;
106
+ }
107
+ config:: CrateType :: Staticlib => {
108
+ link_staticlib :: < B > ( sess, codegen_results, & out_filename, & tmpdir) ;
109
+ }
110
+ _ => {
111
+ link_natively :: < B > (
112
+ sess,
113
+ crate_type,
114
+ & out_filename,
115
+ codegen_results,
116
+ tmpdir. path ( ) ,
117
+ target_cpu,
118
+ ) ;
119
+ }
120
+ }
121
+ }
122
+
123
+ if sess. opts . cg . save_temps {
124
+ let _ = tmpdir. into_path ( ) ;
125
+ }
72
126
}
73
127
74
128
// Remove the temporary object file and metadata if we aren't saving temps
@@ -85,7 +139,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
85
139
if let Some ( ref obj) = metadata_module. object {
86
140
remove ( sess, obj) ;
87
141
}
88
- }
142
+ }
89
143
if let Some ( ref allocator_module) = codegen_results. allocator_module {
90
144
if let Some ( ref obj) = allocator_module. object {
91
145
remove ( sess, obj) ;
@@ -97,73 +151,6 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
97
151
}
98
152
}
99
153
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
154
// The third parameter is for env vars, used on windows to set up the
168
155
// path for MSVC to find its DLLs, and gcc to find its bundled
169
156
// toolchain
0 commit comments