aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-05-13 08:24:21 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-05-13 08:24:21 +0200
commit1aee896cae0747263e607de125a93023b5a9b320 (patch)
tree49841fe55b55de0058176b025ec015ba990c1b61 /src
parent6c3050e3c3eee19a9de2c912dc653062e5597b67 (diff)
parent4b59f564344598b4d1f1a51839a4dc5cbf357012 (diff)
downloadzig-1aee896cae0747263e607de125a93023b5a9b320.tar.gz
zig-1aee896cae0747263e607de125a93023b5a9b320.zip
Merge branch 'master' into streamline-stage2-build-script
Diffstat (limited to 'src')
-rw-r--r--src/Cache.zig21
-rw-r--r--src/Compilation.zig19
-rw-r--r--src/link/Elf.zig13
-rw-r--r--src/link/MachO.zig5
-rw-r--r--src/link/MachO/Zld.zig12
-rw-r--r--src/main.zig94
-rw-r--r--src/target.zig21
7 files changed, 70 insertions, 115 deletions
diff --git a/src/Cache.zig b/src/Cache.zig
index 5bc32b4b68..6c17f52d69 100644
--- a/src/Cache.zig
+++ b/src/Cache.zig
@@ -11,6 +11,7 @@ const testing = std.testing;
const mem = std.mem;
const fmt = std.fmt;
const Allocator = std.mem.Allocator;
+const Compilation = @import("Compilation.zig");
/// Be sure to call `Manifest.deinit` after successful initialization.
pub fn obtain(cache: *const Cache) Manifest {
@@ -61,7 +62,7 @@ pub const File = struct {
pub const HashHelper = struct {
hasher: Hasher = hasher_init,
- const EmitLoc = @import("Compilation.zig").EmitLoc;
+ const EmitLoc = Compilation.EmitLoc;
/// Record a slice of bytes as an dependency of the process being cached
pub fn addBytes(hh: *HashHelper, bytes: []const u8) void {
@@ -220,6 +221,24 @@ pub const Manifest = struct {
return idx;
}
+ pub fn hashCSource(self: *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 fn addOptionalFile(self: *Manifest, optional_file_path: ?[]const u8) !void {
self.hash.add(optional_file_path != null);
const file_path = optional_file_path orelse return;
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 71df776855..b14e598f71 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2260,23 +2260,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *
man.hash.add(comp.clang_preprocessor_mode);
- _ = try man.addFile(c_object.src.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_object.src.extra_flags.len) : (arg_i += 1) {
- const arg = c_object.src.extra_flags[arg_i];
- man.hash.addBytes(arg);
- for (file_args) |file_arg| {
- if (mem.eql(u8, file_arg, arg) and arg_i + 1 < c_object.src.extra_flags.len) {
- arg_i += 1;
- _ = try man.addFile(c_object.src.extra_flags[arg_i], null);
- }
- }
- }
- }
+ try man.hashCSource(c_object.src);
{
const is_collision = blk: {
@@ -3039,7 +3023,6 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
.Exe => true,
};
return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
- comp.bin_file.options.libc_installation == null and
target_util.libcNeedsLibUnwind(comp.getTarget());
}
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 91ee6f3206..fbbe40022a 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1648,17 +1648,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
// libc dep
if (self.base.options.link_libc) {
if (self.base.options.libc_installation != null) {
+ if (target_util.libcNeedsLibUnwind(target)) {
+ try argv.append(comp.libunwind_static_lib.?.full_object_path);
+ }
const needs_grouping = self.base.options.link_mode == .Static;
if (needs_grouping) try argv.append("--start-group");
- // This matches the order of glibc.libs
- try argv.appendSlice(&[_][]const u8{
- "-lm",
- "-lpthread",
- "-lc",
- "-ldl",
- "-lrt",
- "-lutil",
- });
+ try argv.appendSlice(target_util.libcFullLinkFlags(target));
if (needs_grouping) try argv.append("--end-group");
} else if (target.isGnuLibC()) {
try argv.append(comp.libunwind_static_lib.?.full_object_path);
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 09414b4cdd..2ae9575b7e 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -442,6 +442,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
const main_cmd = &self.load_commands.items[self.main_cmd_index.?].Main;
main_cmd.entryoff = addr - text_segment.inner.vmaddr;
+ main_cmd.stacksize = self.base.options.stack_size_override orelse 0;
self.load_commands_dirty = true;
}
try self.writeRebaseInfoTable();
@@ -695,7 +696,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
Compilation.dump_argv(argv.items);
}
- try zld.link(input_files.items, full_out_path);
+ try zld.link(input_files.items, full_out_path, .{
+ .stack_size = self.base.options.stack_size_override,
+ });
break :outer;
}
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index 3904192995..c619d0634b 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -29,6 +29,10 @@ page_size: ?u16 = null,
file: ?fs.File = null,
out_path: ?[]const u8 = null,
+// TODO these args will become obselete once Zld is coalesced with incremental
+// linker.
+stack_size: u64 = 0,
+
objects: std.ArrayListUnmanaged(*Object) = .{},
archives: std.ArrayListUnmanaged(*Archive) = .{},
@@ -172,7 +176,11 @@ pub fn closeFiles(self: Zld) void {
if (self.file) |f| f.close();
}
-pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {
+const LinkArgs = struct {
+ stack_size: ?u64 = null,
+};
+
+pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void {
if (files.len == 0) return error.NoInputFiles;
if (out_path.len == 0) return error.EmptyOutputPath;
@@ -206,6 +214,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void {
.read = true,
.mode = if (std.Target.current.os.tag == .windows) 0 else 0o777,
});
+ self.stack_size = args.stack_size orelse 0;
try self.populateMetadata();
try self.parseInputFiles(files);
@@ -2204,6 +2213,7 @@ fn setEntryPoint(self: *Zld) !void {
const entry_sym = sym.cast(Symbol.Regular) orelse unreachable;
const ec = &self.load_commands.items[self.main_cmd_index.?].Main;
ec.entryoff = @intCast(u32, entry_sym.address - seg.inner.vmaddr);
+ ec.stacksize = self.stack_size;
}
fn writeRebaseInfoTable(self: *Zld) !void {
diff --git a/src/main.zig b/src/main.zig
index a0a11bbbbc..bd57c1f14f 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -2172,7 +2172,7 @@ fn cmdTranslateC(comp: *Compilation, arena: *Allocator, enable_cache: bool) !voi
defer if (enable_cache) man.deinit();
man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
- _ = man.addFile(c_source_file.src_path, null) catch |err| {
+ man.hashCSource(c_source_file) catch |err| {
fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) });
};
@@ -2202,12 +2202,16 @@ fn cmdTranslateC(comp: *Compilation, arena: *Allocator, enable_cache: bool) !voi
}
// Convert to null terminated args.
- const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, argv.items.len + 1);
- new_argv_with_sentinel[argv.items.len] = null;
- const new_argv = new_argv_with_sentinel[0..argv.items.len :null];
+ const clang_args_len = argv.items.len + c_source_file.extra_flags.len;
+ const new_argv_with_sentinel = try arena.alloc(?[*:0]const u8, clang_args_len + 1);
+ new_argv_with_sentinel[clang_args_len] = null;
+ const new_argv = new_argv_with_sentinel[0..clang_args_len :null];
for (argv.items) |arg, i| {
new_argv[i] = try arena.dupeZ(u8, arg);
}
+ for (c_source_file.extra_flags) |arg, i| {
+ new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
+ }
const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});
const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);
@@ -3396,88 +3400,8 @@ test "fds" {
gimmeMoreOfThoseSweetSweetFileDescriptors();
}
-fn detectNativeCpuWithLLVM(
- arch: std.Target.Cpu.Arch,
- llvm_cpu_name_z: ?[*:0]const u8,
- llvm_cpu_features_opt: ?[*:0]const u8,
-) !std.Target.Cpu {
- var result = std.Target.Cpu.baseline(arch);
-
- if (llvm_cpu_name_z) |cpu_name_z| {
- const llvm_cpu_name = mem.spanZ(cpu_name_z);
-
- for (arch.allCpuModels()) |model| {
- const this_llvm_name = model.llvm_name orelse continue;
- if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
- // Here we use the non-dependencies-populated set,
- // so that subtracting features later in this function
- // affect the prepopulated set.
- result = std.Target.Cpu{
- .arch = arch,
- .model = model,
- .features = model.features,
- };
- break;
- }
- }
- }
-
- const all_features = arch.allFeaturesList();
-
- if (llvm_cpu_features_opt) |llvm_cpu_features| {
- var it = mem.tokenize(mem.spanZ(llvm_cpu_features), ",");
- while (it.next()) |decorated_llvm_feat| {
- var op: enum {
- add,
- sub,
- } = undefined;
- var llvm_feat: []const u8 = undefined;
- if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
- op = .add;
- llvm_feat = decorated_llvm_feat[1..];
- } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
- op = .sub;
- llvm_feat = decorated_llvm_feat[1..];
- } else {
- return error.InvalidLlvmCpuFeaturesFormat;
- }
- for (all_features) |feature, index_usize| {
- const this_llvm_name = feature.llvm_name orelse continue;
- if (mem.eql(u8, llvm_feat, this_llvm_name)) {
- const index = @intCast(std.Target.Cpu.Feature.Set.Index, index_usize);
- switch (op) {
- .add => result.features.addFeature(index),
- .sub => result.features.removeFeature(index),
- }
- break;
- }
- }
- }
- }
-
- result.features.populateDependencies(all_features);
- return result;
-}
-
fn detectNativeTargetInfo(gpa: *Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
- var info = try std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
- if (info.cpu_detection_unimplemented) {
- const arch = std.Target.current.cpu.arch;
-
- // We want to just use detected_info.target but implementing
- // CPU model & feature detection is todo so here we rely on LLVM.
- // https://github.com/ziglang/zig/issues/4591
- if (!build_options.have_llvm)
- fatal("CPU features detection is not yet available for {s} without LLVM extensions", .{@tagName(arch)});
-
- const llvm = @import("codegen/llvm/bindings.zig");
- const llvm_cpu_name = llvm.GetHostCPUName();
- const llvm_cpu_features = llvm.GetNativeFeatures();
- info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features);
- cross_target.updateCpuFeatures(&info.target.cpu.features);
- info.target.cpu.arch = cross_target.getCpuArch();
- }
- return info;
+ return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
}
/// Indicate that we are now terminating with a successful exit code.
diff --git a/src/target.zig b/src/target.zig
index 1e31f99dc1..c2018db012 100644
--- a/src/target.zig
+++ b/src/target.zig
@@ -374,3 +374,24 @@ pub fn hasRedZone(target: std.Target) bool {
else => false,
};
}
+
+pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
+ // The linking order of these is significant and should match the order other
+ // c compilers such as gcc or clang use.
+ return switch (target.os.tag) {
+ .netbsd, .openbsd => &[_][]const u8{
+ "-lm",
+ "-lpthread",
+ "-lc",
+ "-lutil",
+ },
+ else => &[_][]const u8{
+ "-lm",
+ "-lpthread",
+ "-lc",
+ "-ldl",
+ "-lrt",
+ "-lutil",
+ },
+ };
+}