authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-26 16:26:19-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-26 16:26:19-07:00
logeec825cea21048461aa4bb6a057e7179d9a118bc
tree9dfb6d7f6a1ba7c4315559beb83bf1406fde4551
parentb196dd1d7958aee86095bd06190eee484a562488

zig cc: support -Bdynamic and -Bstatic parameters

Related: #10050

2 files changed, 63 insertions(+), 2 deletions(-)

src/link/Elf.zig+1-1
...@@ -1553,7 +1553,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1553,7 +1553,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1553 defer test_path.deinit();1553 defer test_path.deinit();
1554 for (self.base.options.lib_dirs) |lib_dir_path| {1554 for (self.base.options.lib_dirs) |lib_dir_path| {
1555 for (self.base.options.system_libs.keys()) |link_lib| {1555 for (self.base.options.system_libs.keys()) |link_lib| {
1556 test_path.shrinkRetainingCapacity(0);1556 test_path.clearRetainingCapacity();
1557 const sep = fs.path.sep_str;1557 const sep = fs.path.sep_str;
1558 try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{1558 try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{
1559 lib_dir_path, link_lib,1559 lib_dir_path, link_lib,
src/main.zig+62-1
...@@ -668,6 +668,9 @@ fn buildOutputType(...@@ -668,6 +668,9 @@ fn buildOutputType(
668 var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa);668 var system_libs = std.StringArrayHashMap(Compilation.SystemLib).init(gpa);
669 defer system_libs.deinit();669 defer system_libs.deinit();
670670
671 var static_libs = std.ArrayList([]const u8).init(gpa);
672 defer static_libs.deinit();
673
671 var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(gpa);674 var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(gpa);
672 defer wasi_emulated_libs.deinit();675 defer wasi_emulated_libs.deinit();
673676
...@@ -1253,6 +1256,7 @@ fn buildOutputType(...@@ -1253,6 +1256,7 @@ fn buildOutputType(
1253 var it = ClangArgIterator.init(arena, all_args);1256 var it = ClangArgIterator.init(arena, all_args);
1254 var emit_llvm = false;1257 var emit_llvm = false;
1255 var needed = false;1258 var needed = false;
1259 var force_static_libs = false;
1256 while (it.has_next) {1260 while (it.has_next) {
1257 it.next() catch |err| {1261 it.next() catch |err| {
1258 fatal("unable to parse command line parameters: {s}", .{@errorName(err)});1262 fatal("unable to parse command line parameters: {s}", .{@errorName(err)});
...@@ -1287,7 +1291,11 @@ fn buildOutputType(...@@ -1287,7 +1291,11 @@ fn buildOutputType(
1287 // -l1291 // -l
1288 // We don't know whether this library is part of libc or libc++ until1292 // We don't know whether this library is part of libc or libc++ until
1289 // we resolve the target, so we simply append to the list for now.1293 // we resolve the target, so we simply append to the list for now.
1290 try system_libs.put(it.only_arg, .{ .needed = needed });1294 if (force_static_libs) {
1295 try static_libs.append(it.only_arg);
1296 } else {
1297 try system_libs.put(it.only_arg, .{ .needed = needed });
1298 }
1291 },1299 },
1292 .ignore => {},1300 .ignore => {},
1293 .driver_punt => {1301 .driver_punt => {
...@@ -1333,6 +1341,17 @@ fn buildOutputType(...@@ -1333,6 +1341,17 @@ fn buildOutputType(
1333 needed = false;1341 needed = false;
1334 } else if (mem.eql(u8, linker_arg, "--no-as-needed")) {1342 } else if (mem.eql(u8, linker_arg, "--no-as-needed")) {
1335 needed = true;1343 needed = true;
1344 } else if (mem.eql(u8, linker_arg, "-Bdynamic") or
1345 mem.eql(u8, linker_arg, "-dy") or
1346 mem.eql(u8, linker_arg, "-call_shared"))
1347 {
1348 force_static_libs = false;
1349 } else if (mem.eql(u8, linker_arg, "-Bstatic") or
1350 mem.eql(u8, linker_arg, "-dn") or
1351 mem.eql(u8, linker_arg, "-non_shared") or
1352 mem.eql(u8, linker_arg, "-static"))
1353 {
1354 force_static_libs = true;
1336 } else {1355 } else {
1337 try linker_args.append(linker_arg);1356 try linker_args.append(linker_arg);
1338 }1357 }
...@@ -1893,6 +1912,48 @@ fn buildOutputType(...@@ -1893,6 +1912,48 @@ fn buildOutputType(
1893 }1912 }
1894 }1913 }
18951914
1915 {
1916 // Resolve static libraries into full paths.
1917 const sep = fs.path.sep_str;
1918
1919 var test_path = std.ArrayList(u8).init(gpa);
1920 defer test_path.deinit();
1921
1922 for (static_libs.items) |static_lib| {
1923 for (lib_dirs.items) |lib_dir_path| {
1924 test_path.clearRetainingCapacity();
1925 try test_path.writer().print("{s}" ++ sep ++ "{s}{s}{s}", .{
1926 lib_dir_path,
1927 target_info.target.libPrefix(),
1928 static_lib,
1929 target_info.target.staticLibSuffix(),
1930 });
1931 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
1932 error.FileNotFound => continue,
1933 else => |e| fatal("unable to search for static library '{s}': {s}", .{
1934 test_path.items, @errorName(e),
1935 }),
1936 };
1937 try link_objects.append(try arena.dupe(u8, test_path.items));
1938 break;
1939 } else {
1940 var search_paths = std.ArrayList(u8).init(arena);
1941 for (lib_dirs.items) |lib_dir_path| {
1942 try search_paths.writer().print("\n {s}" ++ sep ++ "{s}{s}{s}", .{
1943 lib_dir_path,
1944 target_info.target.libPrefix(),
1945 static_lib,
1946 target_info.target.staticLibSuffix(),
1947 });
1948 }
1949 try search_paths.appendSlice("\n suggestion: use full paths to static libraries on the command line rather than using -l and -L arguments");
1950 fatal("static library '{s}' not found. search paths: {s}", .{
1951 static_lib, search_paths.items,
1952 });
1953 }
1954 }
1955 }
1956
1896 const object_format: std.Target.ObjectFormat = blk: {1957 const object_format: std.Target.ObjectFormat = blk: {
1897 const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat();1958 const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat();
1898 if (mem.eql(u8, ofmt, "elf")) {1959 if (mem.eql(u8, ofmt, "elf")) {