| ... | @@ -306,6 +306,8 @@ const usage_build_generic = | ... | @@ -306,6 +306,8 @@ const usage_build_generic = |
| 306 | \\ --version-script [path] Provide a version .map file | 306 | \\ --version-script [path] Provide a version .map file |
| 307 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) | 307 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 308 | \\ --version [ver] Dynamic library semver | 308 | \\ --version [ver] Dynamic library semver |
| | 309 | \\ -fsoname[=name] (linux) Override the default SONAME value |
| | 310 | \\ -fno-soname (linux) Disable emitting a SONAME |
| 309 | \\ -rdynamic Add all symbols to the dynamic symbol table | 311 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 310 | \\ -rpath [path] Add directory to the runtime library search path | 312 | \\ -rpath [path] Add directory to the runtime library search path |
| 311 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library | 313 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library |
| ... | @@ -350,6 +352,12 @@ const repl_help = | ... | @@ -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 | const Emit = union(enum) { | 361 | const Emit = union(enum) { |
| 354 | no, | 362 | no, |
| 355 | yes_default_path, | 363 | yes_default_path, |
| ... | @@ -452,6 +460,7 @@ fn buildOutputType( | ... | @@ -452,6 +460,7 @@ fn buildOutputType( |
| 452 | var target_ofmt: ?[]const u8 = null; | 460 | var target_ofmt: ?[]const u8 = null; |
| 453 | var output_mode: std.builtin.OutputMode = undefined; | 461 | var output_mode: std.builtin.OutputMode = undefined; |
| 454 | var emit_h: Emit = undefined; | 462 | var emit_h: Emit = undefined; |
| | 463 | var soname: SOName = undefined; |
| 455 | var ensure_libc_on_non_freestanding = false; | 464 | var ensure_libc_on_non_freestanding = false; |
| 456 | var ensure_libcpp_on_non_freestanding = false; | 465 | var ensure_libcpp_on_non_freestanding = false; |
| 457 | var link_libc = false; | 466 | var link_libc = false; |
| ... | @@ -467,7 +476,6 @@ fn buildOutputType( | ... | @@ -467,7 +476,6 @@ fn buildOutputType( |
| 467 | var linker_script: ?[]const u8 = null; | 476 | var linker_script: ?[]const u8 = null; |
| 468 | var version_script: ?[]const u8 = null; | 477 | var version_script: ?[]const u8 = null; |
| 469 | var disable_c_depfile = false; | 478 | var disable_c_depfile = false; |
| 470 | var soname: ?[]const u8 = null; | | |
| 471 | var linker_gc_sections: ?bool = null; | 479 | var linker_gc_sections: ?bool = null; |
| 472 | var linker_allow_shlib_undefined: ?bool = null; | 480 | var linker_allow_shlib_undefined: ?bool = null; |
| 473 | var linker_bind_global_refs_locally: ?bool = null; | 481 | var linker_bind_global_refs_locally: ?bool = null; |
| ... | @@ -564,6 +572,8 @@ fn buildOutputType( | ... | @@ -564,6 +572,8 @@ fn buildOutputType( |
| 564 | // .translate_c, .zig_test, .run => emit_h = .no, | 572 | // .translate_c, .zig_test, .run => emit_h = .no, |
| 565 | // else => unreachable, | 573 | // else => unreachable, |
| 566 | //} | 574 | //} |
| | 575 | |
| | 576 | soname = .yes_default_value; |
| 567 | const args = all_args[2..]; | 577 | const args = all_args[2..]; |
| 568 | var i: usize = 0; | 578 | var i: usize = 0; |
| 569 | args_loop: while (i < args.len) : (i += 1) { | 579 | args_loop: while (i < args.len) : (i += 1) { |
| ... | @@ -828,6 +838,12 @@ fn buildOutputType( | ... | @@ -828,6 +838,12 @@ fn buildOutputType( |
| 828 | use_clang = false; | 838 | use_clang = false; |
| 829 | } else if (mem.eql(u8, arg, "-rdynamic")) { | 839 | } else if (mem.eql(u8, arg, "-rdynamic")) { |
| 830 | rdynamic = true; | 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 | } else if (mem.eql(u8, arg, "-femit-bin")) { | 847 | } else if (mem.eql(u8, arg, "-femit-bin")) { |
| 832 | emit_bin = .yes_default_path; | 848 | emit_bin = .yes_default_path; |
| 833 | } else if (mem.startsWith(u8, arg, "-femit-bin=")) { | 849 | } else if (mem.startsWith(u8, arg, "-femit-bin=")) { |
| ... | @@ -955,6 +971,7 @@ fn buildOutputType( | ... | @@ -955,6 +971,7 @@ fn buildOutputType( |
| 955 | }, | 971 | }, |
| 956 | .cc, .cpp => { | 972 | .cc, .cpp => { |
| 957 | emit_h = .no; | 973 | emit_h = .no; |
| | 974 | soname = .no; |
| 958 | strip = true; | 975 | strip = true; |
| 959 | ensure_libc_on_non_freestanding = true; | 976 | ensure_libc_on_non_freestanding = true; |
| 960 | ensure_libcpp_on_non_freestanding = arg_mode == .cpp; | 977 | ensure_libcpp_on_non_freestanding = arg_mode == .cpp; |
| ... | @@ -1109,7 +1126,7 @@ fn buildOutputType( | ... | @@ -1109,7 +1126,7 @@ fn buildOutputType( |
| 1109 | fatal("expected linker arg after '{}'", .{arg}); | 1126 | fatal("expected linker arg after '{}'", .{arg}); |
| 1110 | } | 1127 | } |
| 1111 | const name = linker_args.items[i]; | 1128 | const name = linker_args.items[i]; |
| 1112 | soname = name; | 1129 | soname = .{ .yes = name }; |
| 1113 | // Use it as --name. | 1130 | // Use it as --name. |
| 1114 | // Example: libsoundio.so.2 | 1131 | // Example: libsoundio.so.2 |
| 1115 | var prefix: usize = 0; | 1132 | var prefix: usize = 0; |
| ... | @@ -1433,6 +1450,18 @@ fn buildOutputType( | ... | @@ -1433,6 +1450,18 @@ fn buildOutputType( |
| 1433 | const have_enable_cache = enable_cache orelse false; | 1450 | const have_enable_cache = enable_cache orelse false; |
| 1434 | const optional_version = if (have_version) version else null; | 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 | const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) { | 1465 | const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) { |
| 1437 | .no => null, | 1466 | .no => null, |
| 1438 | .yes_default_path => Compilation.EmitLoc{ | 1467 | .yes_default_path => Compilation.EmitLoc{ |
| ... | @@ -1660,7 +1689,7 @@ fn buildOutputType( | ... | @@ -1660,7 +1689,7 @@ fn buildOutputType( |
| 1660 | .linker_script = linker_script, | 1689 | .linker_script = linker_script, |
| 1661 | .version_script = version_script, | 1690 | .version_script = version_script, |
| 1662 | .disable_c_depfile = disable_c_depfile, | 1691 | .disable_c_depfile = disable_c_depfile, |
| 1663 | .soname = soname, | 1692 | .soname = resolved_soname, |
| 1664 | .linker_gc_sections = linker_gc_sections, | 1693 | .linker_gc_sections = linker_gc_sections, |
| 1665 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, | 1694 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| 1666 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, | 1695 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, |