| ... | ... | @@ -306,6 +306,8 @@ const usage_build_generic = |
| 306 | 306 | \\ --version-script [path] Provide a version .map file |
| 307 | 307 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 308 | 308 | \\ --version [ver] Dynamic library semver |
| 309 | \\ -fsoname[=name] (linux) Override the default SONAME value |
| 310 | \\ -fno-soname (linux) Disable emitting a SONAME |
| 309 | 311 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 310 | 312 | \\ -rpath [path] Add directory to the runtime library search path |
| 311 | 313 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library |
| ... | ... | @@ -350,6 +352,12 @@ const repl_help = |
| 350 | 352 | \\ |
| 351 | 353 | ; |
| 352 | 354 | |
| 355 | const SOName = union(enum) { |
| 356 | no, |
| 357 | yes_default_value, |
| 358 | yes: []const u8, |
| 359 | }; |
| 360 | |
| 353 | 361 | const Emit = union(enum) { |
| 354 | 362 | no, |
| 355 | 363 | yes_default_path, |
| ... | ... | @@ -452,6 +460,7 @@ fn buildOutputType( |
| 452 | 460 | var target_ofmt: ?[]const u8 = null; |
| 453 | 461 | var output_mode: std.builtin.OutputMode = undefined; |
| 454 | 462 | var emit_h: Emit = undefined; |
| 463 | var soname: SOName = undefined; |
| 455 | 464 | var ensure_libc_on_non_freestanding = false; |
| 456 | 465 | var ensure_libcpp_on_non_freestanding = false; |
| 457 | 466 | var link_libc = false; |
| ... | ... | @@ -467,7 +476,6 @@ fn buildOutputType( |
| 467 | 476 | var linker_script: ?[]const u8 = null; |
| 468 | 477 | var version_script: ?[]const u8 = null; |
| 469 | 478 | var disable_c_depfile = false; |
| 470 | | var override_soname: ?[]const u8 = null; |
| 471 | 479 | var linker_gc_sections: ?bool = null; |
| 472 | 480 | var linker_allow_shlib_undefined: ?bool = null; |
| 473 | 481 | var linker_bind_global_refs_locally: ?bool = null; |
| ... | ... | @@ -564,6 +572,8 @@ fn buildOutputType( |
| 564 | 572 | // .translate_c, .zig_test, .run => emit_h = .no, |
| 565 | 573 | // else => unreachable, |
| 566 | 574 | //} |
| 575 | |
| 576 | soname = .yes_default_value; |
| 567 | 577 | const args = all_args[2..]; |
| 568 | 578 | var i: usize = 0; |
| 569 | 579 | args_loop: while (i < args.len) : (i += 1) { |
| ... | ... | @@ -828,6 +838,12 @@ fn buildOutputType( |
| 828 | 838 | use_clang = false; |
| 829 | 839 | } else if (mem.eql(u8, arg, "-rdynamic")) { |
| 830 | 840 | rdynamic = true; |
| 841 | } else if (mem.eql(u8, arg, "-fsoname")) { |
| 842 | soname = .yes_default_value; |
| 843 | } else if (mem.startsWith(u8, arg, "-fsoname=")) { |
| 844 | soname = .{ .yes = arg["-fsoname=".len..] }; |
| 845 | } else if (mem.eql(u8, arg, "-fno-soname")) { |
| 846 | soname = .no; |
| 831 | 847 | } else if (mem.eql(u8, arg, "-femit-bin")) { |
| 832 | 848 | emit_bin = .yes_default_path; |
| 833 | 849 | } else if (mem.startsWith(u8, arg, "-femit-bin=")) { |
| ... | ... | @@ -955,6 +971,7 @@ fn buildOutputType( |
| 955 | 971 | }, |
| 956 | 972 | .cc, .cpp => { |
| 957 | 973 | emit_h = .no; |
| 974 | soname = .no; |
| 958 | 975 | strip = true; |
| 959 | 976 | ensure_libc_on_non_freestanding = true; |
| 960 | 977 | ensure_libcpp_on_non_freestanding = arg_mode == .cpp; |
| ... | ... | @@ -1108,33 +1125,33 @@ fn buildOutputType( |
| 1108 | 1125 | if (i >= linker_args.items.len) { |
| 1109 | 1126 | fatal("expected linker arg after '{}'", .{arg}); |
| 1110 | 1127 | } |
| 1111 | | const soname = linker_args.items[i]; |
| 1112 | | override_soname = soname; |
| 1128 | const name = linker_args.items[i]; |
| 1129 | soname = .{ .yes = name }; |
| 1113 | 1130 | // Use it as --name. |
| 1114 | 1131 | // Example: libsoundio.so.2 |
| 1115 | 1132 | var prefix: usize = 0; |
| 1116 | | if (mem.startsWith(u8, soname, "lib")) { |
| 1133 | if (mem.startsWith(u8, name, "lib")) { |
| 1117 | 1134 | prefix = 3; |
| 1118 | 1135 | } |
| 1119 | | var end: usize = soname.len; |
| 1120 | | if (mem.endsWith(u8, soname, ".so")) { |
| 1136 | var end: usize = name.len; |
| 1137 | if (mem.endsWith(u8, name, ".so")) { |
| 1121 | 1138 | end -= 3; |
| 1122 | 1139 | } else { |
| 1123 | 1140 | var found_digit = false; |
| 1124 | | while (end > 0 and std.ascii.isDigit(soname[end - 1])) { |
| 1141 | while (end > 0 and std.ascii.isDigit(name[end - 1])) { |
| 1125 | 1142 | found_digit = true; |
| 1126 | 1143 | end -= 1; |
| 1127 | 1144 | } |
| 1128 | | if (found_digit and end > 0 and soname[end - 1] == '.') { |
| 1145 | if (found_digit and end > 0 and name[end - 1] == '.') { |
| 1129 | 1146 | end -= 1; |
| 1130 | 1147 | } else { |
| 1131 | | end = soname.len; |
| 1148 | end = name.len; |
| 1132 | 1149 | } |
| 1133 | | if (mem.endsWith(u8, soname[prefix..end], ".so")) { |
| 1150 | if (mem.endsWith(u8, name[prefix..end], ".so")) { |
| 1134 | 1151 | end -= 3; |
| 1135 | 1152 | } |
| 1136 | 1153 | } |
| 1137 | | provided_name = soname[prefix..end]; |
| 1154 | provided_name = name[prefix..end]; |
| 1138 | 1155 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 1139 | 1156 | i += 1; |
| 1140 | 1157 | if (i >= linker_args.items.len) { |
| ... | ... | @@ -1433,6 +1450,18 @@ fn buildOutputType( |
| 1433 | 1450 | const have_enable_cache = enable_cache orelse false; |
| 1434 | 1451 | const optional_version = if (have_version) version else null; |
| 1435 | 1452 | |
| 1453 | const resolved_soname: ?[]const u8 = switch (soname) { |
| 1454 | .yes => |explicit| explicit, |
| 1455 | .no => null, |
| 1456 | .yes_default_value => switch (object_format) { |
| 1457 | .elf => if (have_version) |
| 1458 | try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major }) |
| 1459 | else |
| 1460 | try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name}), |
| 1461 | else => null, |
| 1462 | }, |
| 1463 | }; |
| 1464 | |
| 1436 | 1465 | const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) { |
| 1437 | 1466 | .no => null, |
| 1438 | 1467 | .yes_default_path => Compilation.EmitLoc{ |
| ... | ... | @@ -1660,7 +1689,7 @@ fn buildOutputType( |
| 1660 | 1689 | .linker_script = linker_script, |
| 1661 | 1690 | .version_script = version_script, |
| 1662 | 1691 | .disable_c_depfile = disable_c_depfile, |
| 1663 | | .override_soname = override_soname, |
| 1692 | .soname = resolved_soname, |
| 1664 | 1693 | .linker_gc_sections = linker_gc_sections, |
| 1665 | 1694 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| 1666 | 1695 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, |