| ... | ... | @@ -304,6 +304,8 @@ const usage_build_generic = |
| 304 | 304 | \\ --version-script [path] Provide a version .map file |
| 305 | 305 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 306 | 306 | \\ --version [ver] Dynamic library semver |
| 307 | \\ -fsoname[=name] (linux) Override the default SONAME value |
| 308 | \\ -fno-soname (linux) Disable emitting a SONAME |
| 307 | 309 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 308 | 310 | \\ -rpath [path] Add directory to the runtime library search path |
| 309 | 311 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library |
| ... | ... | @@ -348,6 +350,12 @@ const repl_help = |
| 348 | 350 | \\ |
| 349 | 351 | ; |
| 350 | 352 | |
| 353 | const SOName = union(enum) { |
| 354 | no, |
| 355 | yes_default_value, |
| 356 | yes: []const u8, |
| 357 | }; |
| 358 | |
| 351 | 359 | const Emit = union(enum) { |
| 352 | 360 | no, |
| 353 | 361 | yes_default_path, |
| ... | ... | @@ -450,6 +458,7 @@ fn buildOutputType( |
| 450 | 458 | var target_ofmt: ?[]const u8 = null; |
| 451 | 459 | var output_mode: std.builtin.OutputMode = undefined; |
| 452 | 460 | var emit_h: Emit = undefined; |
| 461 | var soname: SOName = undefined; |
| 453 | 462 | var ensure_libc_on_non_freestanding = false; |
| 454 | 463 | var ensure_libcpp_on_non_freestanding = false; |
| 455 | 464 | var link_libc = false; |
| ... | ... | @@ -464,7 +473,6 @@ fn buildOutputType( |
| 464 | 473 | var linker_script: ?[]const u8 = null; |
| 465 | 474 | var version_script: ?[]const u8 = null; |
| 466 | 475 | var disable_c_depfile = false; |
| 467 | | var override_soname: ?[]const u8 = null; |
| 468 | 476 | var linker_gc_sections: ?bool = null; |
| 469 | 477 | var linker_allow_shlib_undefined: ?bool = null; |
| 470 | 478 | var linker_bind_global_refs_locally: ?bool = null; |
| ... | ... | @@ -561,6 +569,8 @@ fn buildOutputType( |
| 561 | 569 | // .translate_c, .zig_test, .run => emit_h = .no, |
| 562 | 570 | // else => unreachable, |
| 563 | 571 | //} |
| 572 | |
| 573 | soname = .yes_default_value; |
| 564 | 574 | const args = all_args[2..]; |
| 565 | 575 | var i: usize = 0; |
| 566 | 576 | args_loop: while (i < args.len) : (i += 1) { |
| ... | ... | @@ -821,6 +831,12 @@ fn buildOutputType( |
| 821 | 831 | use_clang = false; |
| 822 | 832 | } else if (mem.eql(u8, arg, "-rdynamic")) { |
| 823 | 833 | rdynamic = true; |
| 834 | } else if (mem.eql(u8, arg, "-fsoname")) { |
| 835 | soname = .yes_default_value; |
| 836 | } else if (mem.startsWith(u8, arg, "-fsoname=")) { |
| 837 | soname = .{ .yes = arg["-fsoname=".len..] }; |
| 838 | } else if (mem.eql(u8, arg, "-fno-soname")) { |
| 839 | soname = .no; |
| 824 | 840 | } else if (mem.eql(u8, arg, "-femit-bin")) { |
| 825 | 841 | emit_bin = .yes_default_path; |
| 826 | 842 | } else if (mem.startsWith(u8, arg, "-femit-bin=")) { |
| ... | ... | @@ -948,6 +964,7 @@ fn buildOutputType( |
| 948 | 964 | }, |
| 949 | 965 | .cc, .cpp => { |
| 950 | 966 | emit_h = .no; |
| 967 | soname = .no; |
| 951 | 968 | strip = true; |
| 952 | 969 | ensure_libc_on_non_freestanding = true; |
| 953 | 970 | ensure_libcpp_on_non_freestanding = arg_mode == .cpp; |
| ... | ... | @@ -1091,33 +1108,33 @@ fn buildOutputType( |
| 1091 | 1108 | if (i >= linker_args.items.len) { |
| 1092 | 1109 | fatal("expected linker arg after '{}'", .{arg}); |
| 1093 | 1110 | } |
| 1094 | | const soname = linker_args.items[i]; |
| 1095 | | override_soname = soname; |
| 1111 | const name = linker_args.items[i]; |
| 1112 | soname = .{ .yes = name }; |
| 1096 | 1113 | // Use it as --name. |
| 1097 | 1114 | // Example: libsoundio.so.2 |
| 1098 | 1115 | var prefix: usize = 0; |
| 1099 | | if (mem.startsWith(u8, soname, "lib")) { |
| 1116 | if (mem.startsWith(u8, name, "lib")) { |
| 1100 | 1117 | prefix = 3; |
| 1101 | 1118 | } |
| 1102 | | var end: usize = soname.len; |
| 1103 | | if (mem.endsWith(u8, soname, ".so")) { |
| 1119 | var end: usize = name.len; |
| 1120 | if (mem.endsWith(u8, name, ".so")) { |
| 1104 | 1121 | end -= 3; |
| 1105 | 1122 | } else { |
| 1106 | 1123 | var found_digit = false; |
| 1107 | | while (end > 0 and std.ascii.isDigit(soname[end - 1])) { |
| 1124 | while (end > 0 and std.ascii.isDigit(name[end - 1])) { |
| 1108 | 1125 | found_digit = true; |
| 1109 | 1126 | end -= 1; |
| 1110 | 1127 | } |
| 1111 | | if (found_digit and end > 0 and soname[end - 1] == '.') { |
| 1128 | if (found_digit and end > 0 and name[end - 1] == '.') { |
| 1112 | 1129 | end -= 1; |
| 1113 | 1130 | } else { |
| 1114 | | end = soname.len; |
| 1131 | end = name.len; |
| 1115 | 1132 | } |
| 1116 | | if (mem.endsWith(u8, soname[prefix..end], ".so")) { |
| 1133 | if (mem.endsWith(u8, name[prefix..end], ".so")) { |
| 1117 | 1134 | end -= 3; |
| 1118 | 1135 | } |
| 1119 | 1136 | } |
| 1120 | | provided_name = soname[prefix..end]; |
| 1137 | provided_name = name[prefix..end]; |
| 1121 | 1138 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 1122 | 1139 | i += 1; |
| 1123 | 1140 | if (i >= linker_args.items.len) { |
| ... | ... | @@ -1419,6 +1436,18 @@ fn buildOutputType( |
| 1419 | 1436 | const have_enable_cache = enable_cache orelse false; |
| 1420 | 1437 | const optional_version = if (have_version) version else null; |
| 1421 | 1438 | |
| 1439 | const resolved_soname: ?[]const u8 = switch (soname) { |
| 1440 | .yes => |explicit| explicit, |
| 1441 | .no => null, |
| 1442 | .yes_default_value => switch (object_format) { |
| 1443 | .elf => if (have_version) |
| 1444 | try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major }) |
| 1445 | else |
| 1446 | try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name}), |
| 1447 | else => null, |
| 1448 | }, |
| 1449 | }; |
| 1450 | |
| 1422 | 1451 | const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) { |
| 1423 | 1452 | .no => null, |
| 1424 | 1453 | .yes_default_path => Compilation.EmitLoc{ |
| ... | ... | @@ -1645,7 +1674,7 @@ fn buildOutputType( |
| 1645 | 1674 | .linker_script = linker_script, |
| 1646 | 1675 | .version_script = version_script, |
| 1647 | 1676 | .disable_c_depfile = disable_c_depfile, |
| 1648 | | .override_soname = override_soname, |
| 1677 | .soname = resolved_soname, |
| 1649 | 1678 | .linker_gc_sections = linker_gc_sections, |
| 1650 | 1679 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| 1651 | 1680 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, |