aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-11-27 17:54:22 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-11-27 17:54:22 -0700
commit9268972ff942f1d9db8fd0b89a8efe528d67e930 (patch)
tree45a3a65f31c53e6839e27aa831f8cd49d9e8b9a4 /src/main.zig
parent9e4360c335c543ad4ff80791257eabfc556f3ac1 (diff)
parentc3b0182f31c874eb9f1bb21397debdfdbf6161d3 (diff)
downloadzig-9268972ff942f1d9db8fd0b89a8efe528d67e930.tar.gz
zig-9268972ff942f1d9db8fd0b89a8efe528d67e930.zip
Merge branch 'kubkon-elf-soname-opt-in' into master
closes #7162
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig53
1 files changed, 41 insertions, 12 deletions
diff --git a/src/main.zig b/src/main.zig
index 8de94e1abd..3939ed7b37 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -306,6 +306,8 @@ const usage_build_generic =
\\ --version-script [path] Provide a version .map file
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
\\ --version [ver] Dynamic library semver
+ \\ -fsoname[=name] (linux) Override the default SONAME value
+ \\ -fno-soname (linux) Disable emitting a SONAME
\\ -rdynamic Add all symbols to the dynamic symbol table
\\ -rpath [path] Add directory to the runtime library search path
\\ -feach-lib-rpath Ensure adding rpath for each used dynamic library
@@ -350,6 +352,12 @@ const repl_help =
\\
;
+const SOName = union(enum) {
+ no,
+ yes_default_value,
+ yes: []const u8,
+};
+
const Emit = union(enum) {
no,
yes_default_path,
@@ -452,6 +460,7 @@ fn buildOutputType(
var target_ofmt: ?[]const u8 = null;
var output_mode: std.builtin.OutputMode = undefined;
var emit_h: Emit = undefined;
+ var soname: SOName = undefined;
var ensure_libc_on_non_freestanding = false;
var ensure_libcpp_on_non_freestanding = false;
var link_libc = false;
@@ -467,7 +476,6 @@ fn buildOutputType(
var linker_script: ?[]const u8 = null;
var version_script: ?[]const u8 = null;
var disable_c_depfile = false;
- var override_soname: ?[]const u8 = null;
var linker_gc_sections: ?bool = null;
var linker_allow_shlib_undefined: ?bool = null;
var linker_bind_global_refs_locally: ?bool = null;
@@ -564,6 +572,8 @@ fn buildOutputType(
// .translate_c, .zig_test, .run => emit_h = .no,
// else => unreachable,
//}
+
+ soname = .yes_default_value;
const args = all_args[2..];
var i: usize = 0;
args_loop: while (i < args.len) : (i += 1) {
@@ -828,6 +838,12 @@ fn buildOutputType(
use_clang = false;
} else if (mem.eql(u8, arg, "-rdynamic")) {
rdynamic = true;
+ } else if (mem.eql(u8, arg, "-fsoname")) {
+ soname = .yes_default_value;
+ } else if (mem.startsWith(u8, arg, "-fsoname=")) {
+ soname = .{ .yes = arg["-fsoname=".len..] };
+ } else if (mem.eql(u8, arg, "-fno-soname")) {
+ soname = .no;
} else if (mem.eql(u8, arg, "-femit-bin")) {
emit_bin = .yes_default_path;
} else if (mem.startsWith(u8, arg, "-femit-bin=")) {
@@ -955,6 +971,7 @@ fn buildOutputType(
},
.cc, .cpp => {
emit_h = .no;
+ soname = .no;
strip = true;
ensure_libc_on_non_freestanding = true;
ensure_libcpp_on_non_freestanding = arg_mode == .cpp;
@@ -1108,33 +1125,33 @@ fn buildOutputType(
if (i >= linker_args.items.len) {
fatal("expected linker arg after '{}'", .{arg});
}
- const soname = linker_args.items[i];
- override_soname = soname;
+ const name = linker_args.items[i];
+ soname = .{ .yes = name };
// Use it as --name.
// Example: libsoundio.so.2
var prefix: usize = 0;
- if (mem.startsWith(u8, soname, "lib")) {
+ if (mem.startsWith(u8, name, "lib")) {
prefix = 3;
}
- var end: usize = soname.len;
- if (mem.endsWith(u8, soname, ".so")) {
+ var end: usize = name.len;
+ if (mem.endsWith(u8, name, ".so")) {
end -= 3;
} else {
var found_digit = false;
- while (end > 0 and std.ascii.isDigit(soname[end - 1])) {
+ while (end > 0 and std.ascii.isDigit(name[end - 1])) {
found_digit = true;
end -= 1;
}
- if (found_digit and end > 0 and soname[end - 1] == '.') {
+ if (found_digit and end > 0 and name[end - 1] == '.') {
end -= 1;
} else {
- end = soname.len;
+ end = name.len;
}
- if (mem.endsWith(u8, soname[prefix..end], ".so")) {
+ if (mem.endsWith(u8, name[prefix..end], ".so")) {
end -= 3;
}
}
- provided_name = soname[prefix..end];
+ provided_name = name[prefix..end];
} else if (mem.eql(u8, arg, "-rpath")) {
i += 1;
if (i >= linker_args.items.len) {
@@ -1433,6 +1450,18 @@ fn buildOutputType(
const have_enable_cache = enable_cache orelse false;
const optional_version = if (have_version) version else null;
+ const resolved_soname: ?[]const u8 = switch (soname) {
+ .yes => |explicit| explicit,
+ .no => null,
+ .yes_default_value => switch (object_format) {
+ .elf => if (have_version)
+ try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major })
+ else
+ try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name}),
+ else => null,
+ },
+ };
+
const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {
.no => null,
.yes_default_path => Compilation.EmitLoc{
@@ -1660,7 +1689,7 @@ fn buildOutputType(
.linker_script = linker_script,
.version_script = version_script,
.disable_c_depfile = disable_c_depfile,
- .override_soname = override_soname,
+ .soname = resolved_soname,
.linker_gc_sections = linker_gc_sections,
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
.linker_bind_global_refs_locally = linker_bind_global_refs_locally,