aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-02-18 09:33:27 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-02-18 09:33:27 -0700
commitefdc94c10712f610e7de5e49fd9cd6f88b4bbbae (patch)
tree4b66ec30176843b0efd87b73199c75aa2fba675d /src/Compilation.zig
parent06df842e4d313e81444063803deff306602e0a17 (diff)
parentc32171991b25b323cd68ff96c294bf5a6fa753b8 (diff)
downloadzig-efdc94c10712f610e7de5e49fd9cd6f88b4bbbae.tar.gz
zig-efdc94c10712f610e7de5e49fd9cd6f88b4bbbae.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig149
1 files changed, 87 insertions, 62 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 2aae38c260..44201ab834 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -26,7 +26,7 @@ const wasi_libc = @import("wasi_libc.zig");
const fatal = @import("main.zig").fatal;
const clangMain = @import("main.zig").clangMain;
const Module = @import("Module.zig");
-const Cache = @import("Cache.zig");
+const Cache = std.Build.Cache;
const translate_c = @import("translate_c.zig");
const clang = @import("clang.zig");
const c_codegen = @import("codegen/c.zig");
@@ -807,44 +807,7 @@ pub const AllErrors = struct {
}
};
-pub const Directory = struct {
- /// This field is redundant for operations that can act on the open directory handle
- /// directly, but it is needed when passing the directory to a child process.
- /// `null` means cwd.
- path: ?[]const u8,
- handle: std.fs.Dir,
-
- pub fn join(self: Directory, allocator: Allocator, paths: []const []const u8) ![]u8 {
- if (self.path) |p| {
- // TODO clean way to do this with only 1 allocation
- const part2 = try std.fs.path.join(allocator, paths);
- defer allocator.free(part2);
- return std.fs.path.join(allocator, &[_][]const u8{ p, part2 });
- } else {
- return std.fs.path.join(allocator, paths);
- }
- }
-
- pub fn joinZ(self: Directory, allocator: Allocator, paths: []const []const u8) ![:0]u8 {
- if (self.path) |p| {
- // TODO clean way to do this with only 1 allocation
- const part2 = try std.fs.path.join(allocator, paths);
- defer allocator.free(part2);
- return std.fs.path.joinZ(allocator, &[_][]const u8{ p, part2 });
- } else {
- return std.fs.path.joinZ(allocator, paths);
- }
- }
-
- /// Whether or not the handle should be closed, or the path should be freed
- /// is determined by usage, however this function is provided for convenience
- /// if it happens to be what the caller needs.
- pub fn closeAndFree(self: *Directory, gpa: Allocator) void {
- self.handle.close();
- if (self.path) |p| gpa.free(p);
- self.* = undefined;
- }
-};
+pub const Directory = Cache.Directory;
pub const EmitLoc = struct {
/// If this is `null` it means the file will be output to the cache directory.
@@ -854,6 +817,35 @@ pub const EmitLoc = struct {
basename: []const u8,
};
+pub const cache_helpers = struct {
+ pub fn addEmitLoc(hh: *Cache.HashHelper, emit_loc: EmitLoc) void {
+ hh.addBytes(emit_loc.basename);
+ }
+
+ pub fn addOptionalEmitLoc(hh: *Cache.HashHelper, optional_emit_loc: ?EmitLoc) void {
+ hh.add(optional_emit_loc != null);
+ addEmitLoc(hh, optional_emit_loc orelse return);
+ }
+
+ pub fn hashCSource(self: *Cache.Manifest, c_source: Compilation.CSourceFile) !void {
+ _ = try self.addFile(c_source.src_path, null);
+ // Hash the extra flags, with special care to call addFile for file parameters.
+ // TODO this logic can likely be improved by utilizing clang_options_data.zig.
+ const file_args = [_][]const u8{"-include"};
+ var arg_i: usize = 0;
+ while (arg_i < c_source.extra_flags.len) : (arg_i += 1) {
+ const arg = c_source.extra_flags[arg_i];
+ self.hash.addBytes(arg);
+ for (file_args) |file_arg| {
+ if (mem.eql(u8, file_arg, arg) and arg_i + 1 < c_source.extra_flags.len) {
+ arg_i += 1;
+ _ = try self.addFile(c_source.extra_flags[arg_i], null);
+ }
+ }
+ }
+ }
+};
+
pub const ClangPreprocessorMode = enum {
no,
/// This means we are doing `zig cc -E -o <path>`.
@@ -997,6 +989,7 @@ pub const InitOptions = struct {
linker_optimization: ?u8 = null,
linker_compress_debug_sections: ?link.CompressDebugSections = null,
linker_module_definition_file: ?[]const u8 = null,
+ linker_sort_section: ?link.SortSection = null,
major_subsystem_version: ?u32 = null,
minor_subsystem_version: ?u32 = null,
clang_passthrough_mode: bool = false,
@@ -1029,6 +1022,7 @@ pub const InitOptions = struct {
/// This is for stage1 and should be deleted upon completion of self-hosting.
color: Color = .auto,
reference_trace: ?u32 = null,
+ error_tracing: ?bool = null,
test_filter: ?[]const u8 = null,
test_name_prefix: ?[]const u8 = null,
test_runner_path: ?[]const u8 = null,
@@ -1522,8 +1516,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
cache.hash.add(link_libunwind);
cache.hash.add(options.output_mode);
cache.hash.add(options.machine_code_model);
- cache.hash.addOptionalEmitLoc(options.emit_bin);
- cache.hash.addOptionalEmitLoc(options.emit_implib);
+ cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_bin);
+ cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_implib);
cache.hash.addBytes(options.root_name);
if (options.target.os.tag == .wasi) cache.hash.add(wasi_exec_model);
// TODO audit this and make sure everything is in it
@@ -1621,26 +1615,46 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const root_pkg = if (options.is_test) root_pkg: {
// TODO: we currently have two packages named 'root' here, which is weird. This
// should be changed as part of the resolution of #12201
- const test_pkg = if (options.test_runner_path) |test_runner|
- try Package.create(gpa, "root", null, test_runner)
- else
- try Package.createWithDir(
- gpa,
- "root",
- options.zig_lib_directory,
- null,
- "test_runner.zig",
- );
+ const test_pkg = if (options.test_runner_path) |test_runner| test_pkg: {
+ const test_dir = std.fs.path.dirname(test_runner);
+ const basename = std.fs.path.basename(test_runner);
+ const pkg = try Package.create(gpa, "root", test_dir, basename);
+
+ // copy package table from main_pkg to root_pkg
+ pkg.table = try main_pkg.table.clone(gpa);
+ break :test_pkg pkg;
+ } else try Package.createWithDir(
+ gpa,
+ "root",
+ options.zig_lib_directory,
+ null,
+ "test_runner.zig",
+ );
errdefer test_pkg.destroy(gpa);
break :root_pkg test_pkg;
} else main_pkg;
errdefer if (options.is_test) root_pkg.destroy(gpa);
+ const compiler_rt_pkg = if (include_compiler_rt and options.output_mode == .Obj) compiler_rt_pkg: {
+ break :compiler_rt_pkg try Package.createWithDir(
+ gpa,
+ "compiler_rt",
+ options.zig_lib_directory,
+ null,
+ "compiler_rt.zig",
+ );
+ } else null;
+ errdefer if (compiler_rt_pkg) |p| p.destroy(gpa);
+
try main_pkg.addAndAdopt(gpa, builtin_pkg);
try main_pkg.add(gpa, root_pkg);
try main_pkg.addAndAdopt(gpa, std_pkg);
+ if (compiler_rt_pkg) |p| {
+ try main_pkg.addAndAdopt(gpa, p);
+ }
+
const main_pkg_is_std = m: {
const std_path = try std.fs.path.resolve(arena, &[_][]const u8{
std_pkg.root_src_directory.path orelse ".",
@@ -1710,8 +1724,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const error_return_tracing = !strip and switch (options.optimize_mode) {
.Debug, .ReleaseSafe => (!options.target.isWasm() or options.target.os.tag == .emscripten) and
- !options.target.cpu.arch.isBpf(),
- .ReleaseFast, .ReleaseSmall => false,
+ !options.target.cpu.arch.isBpf() and (options.error_tracing orelse true),
+ .ReleaseFast => options.error_tracing orelse false,
+ .ReleaseSmall => false,
};
// For resource management purposes.
@@ -1839,6 +1854,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
.compress_debug_sections = options.linker_compress_debug_sections orelse .none,
.module_definition_file = options.linker_module_definition_file,
+ .sort_section = options.linker_sort_section,
.import_memory = options.linker_import_memory orelse false,
.import_symbols = options.linker_import_symbols,
.import_table = options.linker_import_table,
@@ -2356,6 +2372,10 @@ pub fn update(comp: *Compilation) !void {
_ = try module.importPkg(module.main_pkg);
}
+ if (module.main_pkg.table.get("compiler_rt")) |compiler_rt_pkg| {
+ _ = try module.importPkg(compiler_rt_pkg);
+ }
+
// Put a work item in for every known source file to detect if
// it changed, and, if so, re-compute ZIR and then queue the job
// to update it.
@@ -2380,6 +2400,10 @@ pub fn update(comp: *Compilation) !void {
if (comp.bin_file.options.is_test) {
try comp.work_queue.writeItem(.{ .analyze_pkg = module.main_pkg });
}
+
+ if (module.main_pkg.table.get("compiler_rt")) |compiler_rt_pkg| {
+ try comp.work_queue.writeItem(.{ .analyze_pkg = compiler_rt_pkg });
+ }
}
// If the terminal is dumb, we dont want to show the user all the output.
@@ -2631,11 +2655,11 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.addListOfBytes(key.src.extra_flags);
}
- man.hash.addOptionalEmitLoc(comp.emit_asm);
- man.hash.addOptionalEmitLoc(comp.emit_llvm_ir);
- man.hash.addOptionalEmitLoc(comp.emit_llvm_bc);
- man.hash.addOptionalEmitLoc(comp.emit_analysis);
- man.hash.addOptionalEmitLoc(comp.emit_docs);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_analysis);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_docs);
man.hash.addListOfBytes(comp.clang_argv);
@@ -2662,6 +2686,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.add(comp.bin_file.options.hash_style);
man.hash.add(comp.bin_file.options.compress_debug_sections);
man.hash.add(comp.bin_file.options.include_compiler_rt);
+ man.hash.addOptional(comp.bin_file.options.sort_section);
if (comp.bin_file.options.link_libc) {
man.hash.add(comp.bin_file.options.libc_installation != null);
if (comp.bin_file.options.libc_installation) |libc_installation| {
@@ -3954,11 +3979,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
defer man.deinit();
man.hash.add(comp.clang_preprocessor_mode);
- man.hash.addOptionalEmitLoc(comp.emit_asm);
- man.hash.addOptionalEmitLoc(comp.emit_llvm_ir);
- man.hash.addOptionalEmitLoc(comp.emit_llvm_bc);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
+ cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
- try man.hashCSource(c_object.src);
+ try cache_helpers.hashCSource(&man, c_object.src);
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
defer arena_allocator.deinit();