mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
Merge pull request #15459 from motiejus/build-id-full
stage2: implement `--build-id` styles
This commit is contained in:
commit
c1add1e19e
@ -165,8 +165,14 @@ pub fn build(b: *std.Build) !void {
|
||||
exe.strip = strip;
|
||||
exe.pie = pie;
|
||||
exe.sanitize_thread = sanitize_thread;
|
||||
exe.build_id = b.option(bool, "build-id", "Include a build id note") orelse false;
|
||||
exe.entitlements = entitlements;
|
||||
|
||||
exe.build_id = b.option(
|
||||
std.Build.Step.Compile.BuildId,
|
||||
"build-id",
|
||||
"Request creation of '.note.gnu.build-id' section",
|
||||
);
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
test_step.dependOn(&exe.step);
|
||||
|
||||
@ -181,6 +181,7 @@ const TypeId = enum {
|
||||
@"enum",
|
||||
string,
|
||||
list,
|
||||
build_id,
|
||||
};
|
||||
|
||||
const TopLevelStep = struct {
|
||||
@ -832,13 +833,13 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
} else if (mem.eql(u8, s, "false")) {
|
||||
return false;
|
||||
} else {
|
||||
log.err("Expected -D{s} to be a boolean, but received '{s}'\n", .{ name, s });
|
||||
log.err("Expected -D{s} to be a boolean, but received '{s}'", .{ name, s });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
}
|
||||
},
|
||||
.list, .map => {
|
||||
log.err("Expected -D{s} to be a boolean, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be a boolean, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -847,7 +848,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.int => switch (option_ptr.value) {
|
||||
.flag, .list, .map => {
|
||||
log.err("Expected -D{s} to be an integer, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be an integer, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -856,12 +857,12 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
.scalar => |s| {
|
||||
const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {
|
||||
error.Overflow => {
|
||||
log.err("-D{s} value {s} cannot fit into type {s}.\n", .{ name, s, @typeName(T) });
|
||||
log.err("-D{s} value {s} cannot fit into type {s}.", .{ name, s, @typeName(T) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
},
|
||||
else => {
|
||||
log.err("Expected -D{s} to be an integer of type {s}.\n", .{ name, @typeName(T) });
|
||||
log.err("Expected -D{s} to be an integer of type {s}.", .{ name, @typeName(T) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
},
|
||||
@ -871,7 +872,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.float => switch (option_ptr.value) {
|
||||
.flag, .map, .list => {
|
||||
log.err("Expected -D{s} to be a float, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be a float, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -879,7 +880,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.scalar => |s| {
|
||||
const n = std.fmt.parseFloat(T, s) catch {
|
||||
log.err("Expected -D{s} to be a float of type {s}.\n", .{ name, @typeName(T) });
|
||||
log.err("Expected -D{s} to be a float of type {s}.", .{ name, @typeName(T) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
};
|
||||
@ -888,7 +889,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.@"enum" => switch (option_ptr.value) {
|
||||
.flag, .map, .list => {
|
||||
log.err("Expected -D{s} to be an enum, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be an enum, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -898,7 +899,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
if (std.meta.stringToEnum(T, s)) |enum_lit| {
|
||||
return enum_lit;
|
||||
} else {
|
||||
log.err("Expected -D{s} to be of type {s}.\n", .{ name, @typeName(T) });
|
||||
log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(T) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
}
|
||||
@ -906,7 +907,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.string => switch (option_ptr.value) {
|
||||
.flag, .list, .map => {
|
||||
log.err("Expected -D{s} to be a string, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be a string, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -914,9 +915,27 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
|
||||
},
|
||||
.scalar => |s| return s,
|
||||
},
|
||||
.build_id => switch (option_ptr.value) {
|
||||
.flag, .map, .list => {
|
||||
log.err("Expected -D{s} to be an enum, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
},
|
||||
.scalar => |s| {
|
||||
if (Step.Compile.BuildId.parse(s)) |build_id| {
|
||||
return build_id;
|
||||
} else |err| {
|
||||
log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
}
|
||||
},
|
||||
},
|
||||
.list => switch (option_ptr.value) {
|
||||
.flag, .map => {
|
||||
log.err("Expected -D{s} to be a list, but received a {s}.\n", .{
|
||||
log.err("Expected -D{s} to be a list, but received a {s}.", .{
|
||||
name, @tagName(option_ptr.value),
|
||||
});
|
||||
self.markInvalidUserInput();
|
||||
@ -1183,15 +1202,18 @@ pub fn addUserInputFlag(self: *Build, name_raw: []const u8) !bool {
|
||||
}
|
||||
|
||||
fn typeToEnum(comptime T: type) TypeId {
|
||||
return switch (@typeInfo(T)) {
|
||||
.Int => .int,
|
||||
.Float => .float,
|
||||
.Bool => .bool,
|
||||
.Enum => .@"enum",
|
||||
else => switch (T) {
|
||||
[]const u8 => .string,
|
||||
[]const []const u8 => .list,
|
||||
else => @compileError("Unsupported type: " ++ @typeName(T)),
|
||||
return switch (T) {
|
||||
Step.Compile.BuildId => .build_id,
|
||||
else => return switch (@typeInfo(T)) {
|
||||
.Int => .int,
|
||||
.Float => .float,
|
||||
.Bool => .bool,
|
||||
.Enum => .@"enum",
|
||||
else => switch (T) {
|
||||
[]const u8 => .string,
|
||||
[]const []const u8 => .list,
|
||||
else => @compileError("Unsupported type: " ++ @typeName(T)),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -235,6 +235,10 @@ pub const HashHelper = struct {
|
||||
.none => {},
|
||||
}
|
||||
},
|
||||
std.Build.Step.Compile.BuildId => switch (x) {
|
||||
.none, .fast, .uuid, .sha1, .md5 => hh.add(std.meta.activeTag(x)),
|
||||
.hexstring => |hex_string| hh.addBytes(hex_string.toSlice()),
|
||||
},
|
||||
else => switch (@typeInfo(@TypeOf(x))) {
|
||||
.Bool, .Int, .Enum, .Array => hh.addBytes(mem.asBytes(&x)),
|
||||
else => @compileError("unable to hash type " ++ @typeName(@TypeOf(x))),
|
||||
|
||||
@ -116,7 +116,7 @@ each_lib_rpath: ?bool = null,
|
||||
/// As an example, the bloaty project refuses to work unless its inputs have
|
||||
/// build ids, in order to prevent accidental mismatches.
|
||||
/// The default is to not include this section because it slows down linking.
|
||||
build_id: ?bool = null,
|
||||
build_id: ?BuildId = null,
|
||||
|
||||
/// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF
|
||||
/// file.
|
||||
@ -288,6 +288,82 @@ pub const Options = struct {
|
||||
use_lld: ?bool = null,
|
||||
};
|
||||
|
||||
pub const BuildId = union(enum) {
|
||||
none,
|
||||
fast,
|
||||
uuid,
|
||||
sha1,
|
||||
md5,
|
||||
hexstring: HexString,
|
||||
|
||||
pub fn eql(a: BuildId, b: BuildId) bool {
|
||||
const a_tag = std.meta.activeTag(a);
|
||||
const b_tag = std.meta.activeTag(b);
|
||||
if (a_tag != b_tag) return false;
|
||||
return switch (a) {
|
||||
.none, .fast, .uuid, .sha1, .md5 => true,
|
||||
.hexstring => |a_hexstring| mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
|
||||
};
|
||||
}
|
||||
|
||||
pub const HexString = struct {
|
||||
bytes: [32]u8,
|
||||
len: u8,
|
||||
|
||||
/// Result is byte values, *not* hex-encoded.
|
||||
pub fn toSlice(hs: *const HexString) []const u8 {
|
||||
return hs.bytes[0..hs.len];
|
||||
}
|
||||
};
|
||||
|
||||
/// Input is byte values, *not* hex-encoded.
|
||||
/// Asserts `bytes` fits inside `HexString`
|
||||
pub fn initHexString(bytes: []const u8) BuildId {
|
||||
var result: BuildId = .{ .hexstring = .{
|
||||
.bytes = undefined,
|
||||
.len = @intCast(u8, bytes.len),
|
||||
} };
|
||||
@memcpy(result.hexstring.bytes[0..bytes.len], bytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Converts UTF-8 text to a `BuildId`.
|
||||
pub fn parse(text: []const u8) !BuildId {
|
||||
if (mem.eql(u8, text, "none")) {
|
||||
return .none;
|
||||
} else if (mem.eql(u8, text, "fast")) {
|
||||
return .fast;
|
||||
} else if (mem.eql(u8, text, "uuid")) {
|
||||
return .uuid;
|
||||
} else if (mem.eql(u8, text, "sha1") or mem.eql(u8, text, "tree")) {
|
||||
return .sha1;
|
||||
} else if (mem.eql(u8, text, "md5")) {
|
||||
return .md5;
|
||||
} else if (mem.startsWith(u8, text, "0x")) {
|
||||
var result: BuildId = .{ .hexstring = undefined };
|
||||
const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
|
||||
result.hexstring.len = @intCast(u8, slice.len);
|
||||
return result;
|
||||
}
|
||||
return error.InvalidBuildIdStyle;
|
||||
}
|
||||
|
||||
test parse {
|
||||
try std.testing.expectEqual(BuildId.md5, try parse("md5"));
|
||||
try std.testing.expectEqual(BuildId.none, try parse("none"));
|
||||
try std.testing.expectEqual(BuildId.fast, try parse("fast"));
|
||||
try std.testing.expectEqual(BuildId.uuid, try parse("uuid"));
|
||||
try std.testing.expectEqual(BuildId.sha1, try parse("sha1"));
|
||||
try std.testing.expectEqual(BuildId.sha1, try parse("tree"));
|
||||
|
||||
try std.testing.expect(BuildId.initHexString("").eql(try parse("0x")));
|
||||
try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456")));
|
||||
try std.testing.expectError(error.InvalidLength, parse("0x12-34"));
|
||||
try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb"));
|
||||
try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx"));
|
||||
}
|
||||
};
|
||||
|
||||
pub const Kind = enum {
|
||||
exe,
|
||||
lib,
|
||||
@ -1810,7 +1886,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
|
||||
try addFlag(&zig_args, "valgrind", self.valgrind_support);
|
||||
try addFlag(&zig_args, "each-lib-rpath", self.each_lib_rpath);
|
||||
try addFlag(&zig_args, "build-id", self.build_id);
|
||||
|
||||
if (self.build_id) |build_id| {
|
||||
try zig_args.append(switch (build_id) {
|
||||
.hexstring => |hs| b.fmt("--build-id=0x{s}", .{
|
||||
std.fmt.fmtSliceHexLower(hs.toSlice()),
|
||||
}),
|
||||
.none, .fast, .uuid, .sha1, .md5 => b.fmt("--build-id={s}", .{@tagName(build_id)}),
|
||||
});
|
||||
}
|
||||
|
||||
if (self.zig_lib_dir) |dir| {
|
||||
try zig_args.append("--zig-lib-dir");
|
||||
|
||||
@ -29,6 +29,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 BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const translate_c = @import("translate_c.zig");
|
||||
const clang = @import("clang.zig");
|
||||
@ -563,7 +564,7 @@ pub const InitOptions = struct {
|
||||
linker_print_map: bool = false,
|
||||
linker_opt_bisect_limit: i32 = -1,
|
||||
each_lib_rpath: ?bool = null,
|
||||
build_id: ?bool = null,
|
||||
build_id: ?BuildId = null,
|
||||
disable_c_depfile: bool = false,
|
||||
linker_z_nodelete: bool = false,
|
||||
linker_z_notext: bool = false,
|
||||
@ -797,7 +798,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
const unwind_tables = options.want_unwind_tables orelse
|
||||
(link_libunwind or target_util.needUnwindTables(options.target));
|
||||
const link_eh_frame_hdr = options.link_eh_frame_hdr or unwind_tables;
|
||||
const build_id = options.build_id orelse false;
|
||||
const build_id = options.build_id orelse .none;
|
||||
|
||||
// Make a decision on whether to use LLD or our own linker.
|
||||
const use_lld = options.use_lld orelse blk: {
|
||||
@ -828,7 +829,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
options.output_mode == .Lib or
|
||||
options.linker_script != null or options.version_script != null or
|
||||
options.emit_implib != null or
|
||||
build_id or
|
||||
build_id != .none or
|
||||
options.symbol_wrap_set.count() > 0)
|
||||
{
|
||||
break :blk true;
|
||||
|
||||
@ -10,6 +10,7 @@ const wasi_libc = @import("wasi_libc.zig");
|
||||
|
||||
const Air = @import("Air.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const Compilation = @import("Compilation.zig");
|
||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
@ -157,7 +158,7 @@ pub const Options = struct {
|
||||
skip_linker_dependencies: bool,
|
||||
parent_compilation_link_libc: bool,
|
||||
each_lib_rpath: bool,
|
||||
build_id: bool,
|
||||
build_id: BuildId,
|
||||
disable_lld_caching: bool,
|
||||
is_test: bool,
|
||||
hash_style: HashStyle,
|
||||
|
||||
@ -1542,8 +1542,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
|
||||
try argv.append("-z");
|
||||
try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
|
||||
|
||||
if (self.base.options.build_id) {
|
||||
try argv.append("--build-id");
|
||||
switch (self.base.options.build_id) {
|
||||
.none => {},
|
||||
.fast, .uuid, .sha1, .md5 => {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
|
||||
@tagName(self.base.options.build_id),
|
||||
}));
|
||||
},
|
||||
.hexstring => |hs| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
|
||||
std.fmt.fmtSliceHexLower(hs.toSlice()),
|
||||
}));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3797,8 +3797,29 @@ fn writeToFile(
|
||||
if (!wasm.base.options.strip) {
|
||||
// The build id must be computed on the main sections only,
|
||||
// so we have to do it now, before the debug sections.
|
||||
if (wasm.base.options.build_id) {
|
||||
try emitBuildIdSection(&binary_bytes);
|
||||
switch (wasm.base.options.build_id) {
|
||||
.none => {},
|
||||
.fast => {
|
||||
var id: [16]u8 = undefined;
|
||||
std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
|
||||
var uuid: [36]u8 = undefined;
|
||||
_ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{
|
||||
std.fmt.fmtSliceHexLower(id[0..4]),
|
||||
std.fmt.fmtSliceHexLower(id[4..6]),
|
||||
std.fmt.fmtSliceHexLower(id[6..8]),
|
||||
std.fmt.fmtSliceHexLower(id[8..10]),
|
||||
std.fmt.fmtSliceHexLower(id[10..]),
|
||||
});
|
||||
try emitBuildIdSection(&binary_bytes, &uuid);
|
||||
},
|
||||
.hexstring => |hs| {
|
||||
var buffer: [32 * 2]u8 = undefined;
|
||||
const str = std.fmt.bufPrint(&buffer, "{s}", .{
|
||||
std.fmt.fmtSliceHexLower(hs.toSlice()),
|
||||
}) catch unreachable;
|
||||
try emitBuildIdSection(&binary_bytes, str);
|
||||
},
|
||||
else => |mode| log.err("build-id '{s}' is not supported for WASM", .{@tagName(mode)}),
|
||||
}
|
||||
|
||||
// if (wasm.dwarf) |*dwarf| {
|
||||
@ -3942,25 +3963,17 @@ fn emitProducerSection(binary_bytes: *std.ArrayList(u8)) !void {
|
||||
);
|
||||
}
|
||||
|
||||
fn emitBuildIdSection(binary_bytes: *std.ArrayList(u8)) !void {
|
||||
fn emitBuildIdSection(binary_bytes: *std.ArrayList(u8), build_id: []const u8) !void {
|
||||
const header_offset = try reserveCustomSectionHeader(binary_bytes);
|
||||
|
||||
const writer = binary_bytes.writer();
|
||||
const build_id = "build_id";
|
||||
try leb.writeULEB128(writer, @intCast(u32, build_id.len));
|
||||
try writer.writeAll(build_id);
|
||||
|
||||
var id: [16]u8 = undefined;
|
||||
std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
|
||||
var uuid: [36]u8 = undefined;
|
||||
_ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{
|
||||
std.fmt.fmtSliceHexLower(id[0..4]), std.fmt.fmtSliceHexLower(id[4..6]), std.fmt.fmtSliceHexLower(id[6..8]),
|
||||
std.fmt.fmtSliceHexLower(id[8..10]), std.fmt.fmtSliceHexLower(id[10..]),
|
||||
});
|
||||
const hdr_build_id = "build_id";
|
||||
try leb.writeULEB128(writer, @intCast(u32, hdr_build_id.len));
|
||||
try writer.writeAll(hdr_build_id);
|
||||
|
||||
try leb.writeULEB128(writer, @as(u32, 1));
|
||||
try leb.writeULEB128(writer, @as(u32, uuid.len));
|
||||
try writer.writeAll(&uuid);
|
||||
try leb.writeULEB128(writer, @intCast(u32, build_id.len));
|
||||
try writer.writeAll(build_id);
|
||||
|
||||
try writeCustomSectionHeader(
|
||||
binary_bytes.items,
|
||||
|
||||
35
src/main.zig
35
src/main.zig
@ -22,6 +22,7 @@ const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
const wasi_libc = @import("wasi_libc.zig");
|
||||
const translate_c = @import("translate_c.zig");
|
||||
const clang = @import("clang.zig");
|
||||
const BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const target_util = @import("target.zig");
|
||||
const crash_report = @import("crash_report.zig");
|
||||
@ -493,8 +494,10 @@ const usage_build_generic =
|
||||
\\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library
|
||||
\\ -fallow-shlib-undefined Allows undefined symbols in shared libraries
|
||||
\\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries
|
||||
\\ -fbuild-id Helps coordinate stripped binaries with debug symbols
|
||||
\\ -fno-build-id (default) Saves a bit of time linking
|
||||
\\ --build-id[=style] At a minor link-time expense, coordinates stripped binaries
|
||||
\\ fast, uuid, sha1, md5 with debug symbols via a '.note.gnu.build-id' section
|
||||
\\ 0x[hexstring] Maximum 32 bytes
|
||||
\\ none (default) Disable build-id
|
||||
\\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
|
||||
\\ --emit-relocs Enable output of relocation sections for post build tools
|
||||
\\ -z [arg] Set linker extension flags
|
||||
@ -817,7 +820,7 @@ fn buildOutputType(
|
||||
var link_eh_frame_hdr = false;
|
||||
var link_emit_relocs = false;
|
||||
var each_lib_rpath: ?bool = null;
|
||||
var build_id: ?bool = null;
|
||||
var build_id: ?BuildId = null;
|
||||
var sysroot: ?[]const u8 = null;
|
||||
var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC");
|
||||
var machine_code_model: std.builtin.CodeModel = .default;
|
||||
@ -1202,10 +1205,6 @@ fn buildOutputType(
|
||||
each_lib_rpath = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
|
||||
each_lib_rpath = false;
|
||||
} else if (mem.eql(u8, arg, "-fbuild-id")) {
|
||||
build_id = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-build-id")) {
|
||||
build_id = false;
|
||||
} else if (mem.eql(u8, arg, "--test-cmd-bin")) {
|
||||
try test_exec_args.append(null);
|
||||
} else if (mem.eql(u8, arg, "--test-evented-io")) {
|
||||
@ -1446,6 +1445,15 @@ fn buildOutputType(
|
||||
linker_gc_sections = true;
|
||||
} else if (mem.eql(u8, arg, "--no-gc-sections")) {
|
||||
linker_gc_sections = false;
|
||||
} else if (mem.eql(u8, arg, "--build-id")) {
|
||||
build_id = .fast;
|
||||
} else if (mem.startsWith(u8, arg, "--build-id=")) {
|
||||
const style = arg["--build-id=".len..];
|
||||
build_id = BuildId.parse(style) catch |err| {
|
||||
fatal("unable to parse --build-id style '{s}': {s}", .{
|
||||
style, @errorName(err),
|
||||
});
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
||||
if (!crash_report.is_enabled) {
|
||||
std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
|
||||
@ -1684,9 +1692,12 @@ fn buildOutputType(
|
||||
if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
|
||||
const key = linker_arg[0..equals_pos];
|
||||
const value = linker_arg[equals_pos + 1 ..];
|
||||
if (mem.eql(u8, key, "build-id")) {
|
||||
build_id = true;
|
||||
warn("ignoring build-id style argument: '{s}'", .{value});
|
||||
if (mem.eql(u8, key, "--build-id")) {
|
||||
build_id = BuildId.parse(value) catch |err| {
|
||||
fatal("unable to parse --build-id style '{s}': {s}", .{
|
||||
value, @errorName(err),
|
||||
});
|
||||
};
|
||||
continue;
|
||||
} else if (mem.eql(u8, key, "--sort-common")) {
|
||||
// this ignores --sort=common=<anything>; ignoring plain --sort-common
|
||||
@ -1698,7 +1709,9 @@ fn buildOutputType(
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (mem.eql(u8, linker_arg, "--as-needed")) {
|
||||
if (mem.eql(u8, linker_arg, "--build-id")) {
|
||||
build_id = .fast;
|
||||
} else if (mem.eql(u8, linker_arg, "--as-needed")) {
|
||||
needed = false;
|
||||
} else if (mem.eql(u8, linker_arg, "--no-as-needed")) {
|
||||
needed = true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user