| ... | ... | @@ -271,6 +271,7 @@ pub const InitOptions = struct { |
| 271 | 271 | self_exe_path: ?[]const u8 = null, |
| 272 | 272 | version: ?std.builtin.Version = null, |
| 273 | 273 | libc_installation: ?*const LibCInstallation = null, |
| 274 | machine_code_model: std.builtin.CodeModel = .default, |
| 274 | 275 | }; |
| 275 | 276 | |
| 276 | 277 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| ... | ... | @@ -319,6 +320,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 319 | 320 | // We would also want to prefer LLVM for architectures that we don't have self-hosted support for too. |
| 320 | 321 | break :blk false; |
| 321 | 322 | }; |
| 323 | if (!use_llvm and options.machine_code_model != .default) { |
| 324 | return error.MachineCodeModelNotSupported; |
| 325 | } |
| 322 | 326 | |
| 323 | 327 | const is_exe_or_dyn_lib = switch (options.output_mode) { |
| 324 | 328 | .Obj => false, |
| ... | ... | @@ -425,6 +429,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 425 | 429 | cache.hash.add(options.strip); |
| 426 | 430 | cache.hash.add(options.link_libc); |
| 427 | 431 | cache.hash.add(options.output_mode); |
| 432 | cache.hash.add(options.machine_code_model); |
| 428 | 433 | // TODO audit this and make sure everything is in it |
| 429 | 434 | |
| 430 | 435 | const module: ?*Module = if (options.root_pkg) |root_pkg| blk: { |
| ... | ... | @@ -593,6 +598,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 593 | 598 | .stack_check = stack_check, |
| 594 | 599 | .single_threaded = single_threaded, |
| 595 | 600 | .debug_link = options.debug_link, |
| 601 | .machine_code_model = options.machine_code_model, |
| 596 | 602 | }); |
| 597 | 603 | errdefer bin_file.destroy(); |
| 598 | 604 | |
| ... | ... | @@ -964,10 +970,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 964 | 970 | ch.hash.addListOfBytes(comp.clang_argv); |
| 965 | 971 | ch.hash.add(comp.bin_file.options.link_libcpp); |
| 966 | 972 | ch.hash.addListOfBytes(comp.libc_include_dir_list); |
| 967 | | // TODO |
| 968 | | //cache_int(cache_hash, g->code_model); |
| 969 | | //cache_bool(cache_hash, codegen_have_frame_pointer(g)); |
| 970 | | _ = try ch.addFile(c_object.src_path, null); |
| 973 | _ = try ch.addFile(c_object.src.src_path, null); |
| 971 | 974 | { |
| 972 | 975 | // Hash the extra flags, with special care to call addFile for file parameters. |
| 973 | 976 | // TODO this logic can likely be improved by utilizing clang_options_data.zig. |
| ... | ... | @@ -989,7 +992,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 989 | 992 | defer arena_allocator.deinit(); |
| 990 | 993 | const arena = &arena_allocator.allocator; |
| 991 | 994 | |
| 992 | | const c_source_basename = std.fs.path.basename(c_object.src_path); |
| 995 | const c_source_basename = std.fs.path.basename(c_object.src.src_path); |
| 993 | 996 | // Special case when doing build-obj for just one C file. When there are more than one object |
| 994 | 997 | // file and building an object we need to link them together, but with just one it should go |
| 995 | 998 | // directly to the output file. |
| ... | ... | @@ -1012,14 +1015,14 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1012 | 1015 | |
| 1013 | 1016 | try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" }); |
| 1014 | 1017 | |
| 1015 | | const ext = classifyFileExt(c_object.src_path); |
| 1018 | const ext = classifyFileExt(c_object.src.src_path); |
| 1016 | 1019 | // TODO capture the .d file and deal with caching stuff |
| 1017 | 1020 | try comp.addCCArgs(arena, &argv, ext, false, null); |
| 1018 | 1021 | |
| 1019 | 1022 | try argv.append("-o"); |
| 1020 | 1023 | try argv.append(out_obj_path); |
| 1021 | 1024 | |
| 1022 | | try argv.append(c_object.src_path); |
| 1025 | try argv.append(c_object.src.src_path); |
| 1023 | 1026 | try argv.appendSlice(c_object.src.extra_flags); |
| 1024 | 1027 | |
| 1025 | 1028 | if (comp.debug_cc) { |
| ... | ... | @@ -1095,7 +1098,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { |
| 1095 | 1098 | try std.os.renameat(zig_cache_tmp_dir.fd, tmp_basename, o_dir.fd, o_basename); |
| 1096 | 1099 | |
| 1097 | 1100 | ch.writeManifest() catch |err| { |
| 1098 | | std.log.warn("failed to write cache manifest when compiling '{}': {}", .{ c_object.src_path, @errorName(err) }); |
| 1101 | std.log.warn("failed to write cache manifest when compiling '{}': {}", .{ c_object.src.src_path, @errorName(err) }); |
| 1099 | 1102 | }; |
| 1100 | 1103 | break :blk digest; |
| 1101 | 1104 | }; |
| ... | ... | @@ -1219,6 +1222,10 @@ fn addCCArgs( |
| 1219 | 1222 | // flag = SplitIterator_next(&it); |
| 1220 | 1223 | // } |
| 1221 | 1224 | //} |
| 1225 | const mcmodel = comp.bin_file.options.machine_code_model; |
| 1226 | if (mcmodel != .default) { |
| 1227 | try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={}", .{@tagName(mcmodel)})); |
| 1228 | } |
| 1222 | 1229 | if (translate_c) { |
| 1223 | 1230 | // This gives us access to preprocessing entities, presumably at the cost of performance. |
| 1224 | 1231 | try argv.append("-Xclang"); |
| ... | ... | @@ -1432,6 +1439,9 @@ test "classifyFileExt" { |
| 1432 | 1439 | } |
| 1433 | 1440 | |
| 1434 | 1441 | fn haveFramePointer(comp: *Compilation) bool { |
| 1442 | // If you complicate this logic make sure you update the parent cache hash. |
| 1443 | // Right now it's not in the cache hash because the value depends on optimize_mode |
| 1444 | // and strip which are both already part of the hash. |
| 1435 | 1445 | return switch (comp.bin_file.options.optimize_mode) { |
| 1436 | 1446 | .Debug, .ReleaseSafe => !comp.bin_file.options.strip, |
| 1437 | 1447 | .ReleaseSmall, .ReleaseFast => false, |