authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-24 21:10:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-24 21:13:01-07:00
log4f0850fe285937e37a7e9260c399867d3f61a487
tree5ce8d9d2ecda1f428e423da500bf9067e2a20d20
parent054fafd7d9a5226f21e7be1737c6d352fe39f795

don't delete C import .c source from zig-cache

preventing CacheUnavailable error when doing `@cImport`

2 files changed, 69 insertions(+), 80 deletions(-)

src/Compilation.zig+68-80
......@@ -1248,100 +1248,88 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
12481248 defer arena_allocator.deinit();
12491249 const arena = &arena_allocator.allocator;
12501250
1251 // We need a place to leave the .h file so we can can log it in case of verbose_cimport.
1252 // This block is so that the defers for closing the tmp directory handle can run before
1253 // we try to delete the directory after the block.
1254 const result: struct { tmp_dir_sub_path: []const u8, digest: [Cache.hex_digest_len]u8 } = blk: {
1255 const tmp_digest = man.hash.peek();
1256 const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest });
1257 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
1258 defer zig_cache_tmp_dir.close();
1259 const cimport_c_basename = "cimport.c";
1260 const out_h_path = try comp.local_cache_directory.join(arena, &[_][]const u8{
1261 tmp_dir_sub_path, cimport_c_basename,
1262 });
1263 const out_dep_path = try std.fmt.allocPrint(arena, "{}.d", .{out_h_path});
1264
1265 try zig_cache_tmp_dir.writeFile(cimport_c_basename, c_src);
1266 if (comp.verbose_cimport) {
1267 log.info("C import source: {}", .{out_h_path});
1268 }
1251 const tmp_digest = man.hash.peek();
1252 const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest });
1253 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
1254 defer zig_cache_tmp_dir.close();
1255 const cimport_c_basename = "cimport.c";
1256 const out_h_path = try comp.local_cache_directory.join(arena, &[_][]const u8{
1257 tmp_dir_sub_path, cimport_c_basename,
1258 });
1259 const out_dep_path = try std.fmt.allocPrint(arena, "{}.d", .{out_h_path});
12691260
1270 var argv = std.ArrayList([]const u8).init(comp.gpa);
1271 defer argv.deinit();
1261 try zig_cache_tmp_dir.writeFile(cimport_c_basename, c_src);
1262 if (comp.verbose_cimport) {
1263 log.info("C import source: {}", .{out_h_path});
1264 }
12721265
1273 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
1266 var argv = std.ArrayList([]const u8).init(comp.gpa);
1267 defer argv.deinit();
12741268
1275 try argv.append(out_h_path);
1269 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
12761270
1277 if (comp.verbose_cc) {
1278 dump_argv(argv.items);
1279 }
1271 try argv.append(out_h_path);
12801272
1281 // Convert to null terminated args.
1282 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);
1283 new_argv_with_sentinel[argv.items.len] = null;
1284 const new_argv = new_argv_with_sentinel[0..argv.items.len :null];
1285 for (argv.items) |arg, i| {
1286 new_argv[i] = try arena.dupeZ(u8, arg);
1287 }
1273 if (comp.verbose_cc) {
1274 dump_argv(argv.items);
1275 }
12881276
1289 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});
1290 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);
1291 var clang_errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
1292 const tree = translate_c.translate(
1293 comp.gpa,
1294 new_argv.ptr,
1295 new_argv.ptr + new_argv.len,
1296 &clang_errors,
1297 c_headers_dir_path_z,
1298 ) catch |err| switch (err) {
1299 error.OutOfMemory => return error.OutOfMemory,
1300 error.ASTUnitFailure => {
1301 log.warn("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{});
1302 return error.ASTUnitFailure;
1303 },
1304 error.SemanticAnalyzeFail => {
1305 return CImportResult{
1306 .out_zig_path = "",
1307 .errors = clang_errors,
1308 };
1309 },
1310 };
1311 defer tree.deinit();
1277 // Convert to null terminated args.
1278 const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);
1279 new_argv_with_sentinel[argv.items.len] = null;
1280 const new_argv = new_argv_with_sentinel[0..argv.items.len :null];
1281 for (argv.items) |arg, i| {
1282 new_argv[i] = try arena.dupeZ(u8, arg);
1283 }
13121284
1313 if (comp.verbose_cimport) {
1314 log.info("C import .d file: {}", .{out_dep_path});
1315 }
1285 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});
1286 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);
1287 var clang_errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
1288 const tree = translate_c.translate(
1289 comp.gpa,
1290 new_argv.ptr,
1291 new_argv.ptr + new_argv.len,
1292 &clang_errors,
1293 c_headers_dir_path_z,
1294 ) catch |err| switch (err) {
1295 error.OutOfMemory => return error.OutOfMemory,
1296 error.ASTUnitFailure => {
1297 log.warn("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{});
1298 return error.ASTUnitFailure;
1299 },
1300 error.SemanticAnalyzeFail => {
1301 return CImportResult{
1302 .out_zig_path = "",
1303 .errors = clang_errors,
1304 };
1305 },
1306 };
1307 defer tree.deinit();
13161308
1317 const dep_basename = std.fs.path.basename(out_dep_path);
1318 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
1309 if (comp.verbose_cimport) {
1310 log.info("C import .d file: {}", .{out_dep_path});
1311 }
13191312
1320 const digest = man.final();
1321 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
1322 var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{});
1323 defer o_dir.close();
1313 const dep_basename = std.fs.path.basename(out_dep_path);
1314 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
13241315
1325 var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{});
1326 defer out_zig_file.close();
1316 const digest = man.final();
1317 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
1318 var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{});
1319 defer o_dir.close();
13271320
1328 var bos = std.io.bufferedOutStream(out_zig_file.writer());
1329 _ = try std.zig.render(comp.gpa, bos.writer(), tree);
1330 try bos.flush();
1321 var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{});
1322 defer out_zig_file.close();
13311323
1332 man.writeManifest() catch |err| {
1333 log.warn("failed to write cache manifest for C import: {}", .{@errorName(err)});
1334 };
1324 var bos = std.io.bufferedOutStream(out_zig_file.writer());
1325 _ = try std.zig.render(comp.gpa, bos.writer(), tree);
1326 try bos.flush();
13351327
1336 break :blk .{ .tmp_dir_sub_path = tmp_dir_sub_path, .digest = digest };
1328 man.writeManifest() catch |err| {
1329 log.warn("failed to write cache manifest for C import: {}", .{@errorName(err)});
13371330 };
1338 if (!comp.verbose_cimport) {
1339 // Remove the tmp dir and files to save space because we don't need them again.
1340 comp.local_cache_directory.handle.deleteTree(result.tmp_dir_sub_path) catch |err| {
1341 log.warn("failed to delete tmp files for C import: {}", .{@errorName(err)});
1342 };
1343 }
1344 break :digest result.digest;
1331
1332 break :digest digest;
13451333 } else man.final();
13461334
13471335 const out_zig_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{
src/stage1.zig+1
......@@ -347,6 +347,7 @@ export fn stage2_cimport(
347347 error.Unexpected => return .Unexpected,
348348 error.InputOutput => return .FileSystem,
349349 error.ASTUnitFailure => return .ASTUnitFailure,
350 error.CacheUnavailable => return .CacheUnavailable,
350351 else => return .Unexpected,
351352 };
352353 out_zig_path_ptr.* = result.out_zig_path.ptr;