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