| ... | ... | @@ -2216,39 +2216,6 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2216 | 2216 | // -femit-llvm-bc, and -femit-asm, in the case of C objects. |
| 2217 | 2217 | comp.emitOthers(); |
| 2218 | 2218 | |
| 2219 | | { |
| 2220 | | if (comp.bin_file) |lf| { |
| 2221 | | // This is needed before reading the error flags. |
| 2222 | | lf.flush(comp, main_progress_node) catch |err| switch (err) { |
| 2223 | | error.FlushFailure => {}, // error reported through link_error_flags |
| 2224 | | error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr |
| 2225 | | else => |e| return e, |
| 2226 | | }; |
| 2227 | | } |
| 2228 | | |
| 2229 | | if (comp.module) |zcu| { |
| 2230 | | try link.File.C.flushEmitH(zcu); |
| 2231 | | |
| 2232 | | if (zcu.llvm_object) |llvm_object| { |
| 2233 | | if (build_options.only_c) unreachable; |
| 2234 | | const default_emit = switch (comp.cache_use) { |
| 2235 | | .whole => |whole| .{ |
| 2236 | | .directory = whole.tmp_artifact_directory.?, |
| 2237 | | .sub_path = "dummy", |
| 2238 | | }, |
| 2239 | | .incremental => |incremental| .{ |
| 2240 | | .directory = incremental.artifact_directory, |
| 2241 | | .sub_path = "dummy", |
| 2242 | | }, |
| 2243 | | }; |
| 2244 | | try emitLlvmObject(comp, arena, default_emit, null, llvm_object, main_progress_node); |
| 2245 | | } |
| 2246 | | } |
| 2247 | | } |
| 2248 | | |
| 2249 | | if (comp.totalErrorCount() != 0) return; |
| 2250 | | try maybeGenerateAutodocs(comp, main_progress_node); |
| 2251 | | |
| 2252 | 2219 | switch (comp.cache_use) { |
| 2253 | 2220 | .whole => |whole| { |
| 2254 | 2221 | const digest = man.final(); |
| ... | ... | @@ -2261,15 +2228,32 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2261 | 2228 | whole.tmp_artifact_directory = null; |
| 2262 | 2229 | } else unreachable; |
| 2263 | 2230 | |
| 2264 | | if (comp.bin_file) |lf| { |
| 2265 | | lf.destroy(); |
| 2266 | | comp.bin_file = null; |
| 2267 | | } |
| 2268 | | |
| 2269 | 2231 | const s = std.fs.path.sep_str; |
| 2270 | 2232 | const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int); |
| 2271 | 2233 | const o_sub_path = "o" ++ s ++ digest; |
| 2272 | 2234 | |
| 2235 | // Work around windows `AccessDenied` if any files within this |
| 2236 | // directory are open by closing and reopening the file handles. |
| 2237 | const need_writable_dance = w: { |
| 2238 | if (builtin.os.tag == .windows) { |
| 2239 | if (comp.bin_file) |lf| { |
| 2240 | // We cannot just call `makeExecutable` as it makes a false |
| 2241 | // assumption that we have a file handle open only when linking |
| 2242 | // an executable file. This used to be true when our linkers |
| 2243 | // were incapable of emitting relocatables and static archive. |
| 2244 | // Now that they are capable, we need to unconditionally close |
| 2245 | // the file handle and re-open it in the follow up call to |
| 2246 | // `makeWritable`. |
| 2247 | if (lf.file) |f| { |
| 2248 | f.close(); |
| 2249 | lf.file = null; |
| 2250 | break :w true; |
| 2251 | } |
| 2252 | } |
| 2253 | } |
| 2254 | break :w false; |
| 2255 | }; |
| 2256 | |
| 2273 | 2257 | renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path) catch |err| { |
| 2274 | 2258 | return comp.setMiscFailure( |
| 2275 | 2259 | .rename_results, |
| ... | ... | @@ -2283,15 +2267,75 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2283 | 2267 | }; |
| 2284 | 2268 | comp.wholeCacheModeSetBinFilePath(whole, &digest); |
| 2285 | 2269 | |
| 2270 | // The linker flush functions need to know the final output path |
| 2271 | // for debug info purposes because executable debug info contains |
| 2272 | // references object file paths. |
| 2273 | if (comp.bin_file) |lf| { |
| 2274 | lf.emit = .{ |
| 2275 | .directory = comp.local_cache_directory, |
| 2276 | .sub_path = whole.bin_sub_path.?, |
| 2277 | }; |
| 2278 | |
| 2279 | // Has to be after the `wholeCacheModeSetBinFilePath` above. |
| 2280 | if (need_writable_dance) { |
| 2281 | try lf.makeWritable(); |
| 2282 | } |
| 2283 | } |
| 2284 | |
| 2285 | try flush(comp, arena, main_progress_node); |
| 2286 | if (comp.totalErrorCount() != 0) return; |
| 2287 | |
| 2286 | 2288 | // Failure here only means an unnecessary cache miss. |
| 2287 | 2289 | man.writeManifest() catch |err| { |
| 2288 | 2290 | log.warn("failed to write cache manifest: {s}", .{@errorName(err)}); |
| 2289 | 2291 | }; |
| 2290 | 2292 | |
| 2293 | if (comp.bin_file) |lf| { |
| 2294 | lf.destroy(); |
| 2295 | comp.bin_file = null; |
| 2296 | } |
| 2297 | |
| 2291 | 2298 | assert(whole.lock == null); |
| 2292 | 2299 | whole.lock = man.toOwnedLock(); |
| 2293 | 2300 | }, |
| 2294 | | .incremental => {}, |
| 2301 | .incremental => { |
| 2302 | try flush(comp, arena, main_progress_node); |
| 2303 | if (comp.totalErrorCount() != 0) return; |
| 2304 | }, |
| 2305 | } |
| 2306 | } |
| 2307 | |
| 2308 | fn flush(comp: *Compilation, arena: Allocator, prog_node: *std.Progress.Node) !void { |
| 2309 | if (comp.bin_file) |lf| { |
| 2310 | // This is needed before reading the error flags. |
| 2311 | lf.flush(comp, prog_node) catch |err| switch (err) { |
| 2312 | error.FlushFailure => {}, // error reported through link_error_flags |
| 2313 | error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr |
| 2314 | else => |e| return e, |
| 2315 | }; |
| 2316 | } |
| 2317 | |
| 2318 | if (comp.module) |zcu| { |
| 2319 | try link.File.C.flushEmitH(zcu); |
| 2320 | |
| 2321 | if (zcu.llvm_object) |llvm_object| { |
| 2322 | if (build_options.only_c) unreachable; |
| 2323 | const default_emit = switch (comp.cache_use) { |
| 2324 | .whole => |whole| .{ |
| 2325 | .directory = whole.tmp_artifact_directory.?, |
| 2326 | .sub_path = "dummy", |
| 2327 | }, |
| 2328 | .incremental => |incremental| .{ |
| 2329 | .directory = incremental.artifact_directory, |
| 2330 | .sub_path = "dummy", |
| 2331 | }, |
| 2332 | }; |
| 2333 | try emitLlvmObject(comp, arena, default_emit, null, llvm_object, prog_node); |
| 2334 | } |
| 2335 | } |
| 2336 | |
| 2337 | if (comp.totalErrorCount() == 0) { |
| 2338 | try maybeGenerateAutodocs(comp, prog_node); |
| 2295 | 2339 | } |
| 2296 | 2340 | } |
| 2297 | 2341 | |