From 429a219f42c93957dee41021a22547549a8c54a2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 30 Nov 2020 20:18:40 -0700 Subject: [PATCH] stage2: fix not detecting all dynamic libraries Positional shared library arguments were not being detected as causing dynamic linking, resulting in invalid linker lines. LLD did not have an error message for this when targeting x86_64-linux but it did emit an error message when targeting aarch64-linux, which is how I noticed the problem. This surfaced an error having to do with fifo.pipe() in the cat example which I did not diagnose but solved the issue by doing the revamp that was already overdue for that example. It appears that the zig-window project was exploiting the previous behavior for it to function properly, so this prompts the question, is there some kind of static/dynamic executable hybrid that the compiler should recognize? Unclear - but we can discuss that in #7240. --- src/Compilation.zig | 15 ++++++-- test/standalone/cat/main.zig | 44 +++++++----------------- test/standalone/shared_library/build.zig | 3 ++ 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index df48e5a39183b093086e33988147f4821d15daa6..a5bf7a0ebb8022c7e1e3b5c20998c8de3e7f4b10 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -510,8 +510,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { { break :dl true; } - if (options.system_libs.len != 0) { - // when creating a executable that links to system libraries, + const any_dyn_libs: bool = x: { + if (options.system_libs.len != 0) + break :x true; + for (options.link_objects) |obj| { + switch (classifyFileExt(obj)) { + .shared_library => break :x true, + else => continue, + } + } + break :x false; + }; + if (any_dyn_libs) { + // When creating a executable that links to system libraries, // we require dynamic linking, but we must not link static libraries // or object files dynamically! break :dl (options.output_mode == .Exe); diff --git a/test/standalone/cat/main.zig b/test/standalone/cat/main.zig index 65cd2b1e7ef767f8a2bf082d04de62fc06bcb577..89e5fde3cdd80211a1f5aac1e35aaf44347e8a06 100644 --- a/test/standalone/cat/main.zig +++ b/test/standalone/cat/main.zig @@ -5,41 +5,38 @@ const fs = std.fs; const mem = std.mem; const warn = std.log.warn; -var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; -const allocator = &general_purpose_allocator.allocator; - pub fn main() !void { - defer _ = general_purpose_allocator.deinit(); + var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena_instance.deinit(); + const arena = &arena_instance.allocator; - var args_it = process.args(); - const exe = try unwrapArg(args_it.next(allocator).?); - defer allocator.free(exe); + const args = try process.argsAlloc(arena); + + const exe = args[0]; var catted_anything = false; const stdout_file = io.getStdOut(); const cwd = fs.cwd(); - while (args_it.next(allocator)) |arg_or_err| { - const arg = try unwrapArg(arg_or_err); - defer allocator.free(arg); + for (args[1..]) |arg| { if (mem.eql(u8, arg, "-")) { catted_anything = true; - try cat_file(stdout_file, io.getStdIn()); - } else if (arg[0] == '-') { + try stdout_file.writeFileAll(io.getStdIn(), .{}); + } else if (mem.startsWith(u8, arg, "-")) { return usage(exe); } else { const file = cwd.openFile(arg, .{}) catch |err| { - warn("Unable to open file: {}\n", .{@errorName(err)}); + warn("Unable to open file: {s}\n", .{@errorName(err)}); return err; }; defer file.close(); catted_anything = true; - try cat_file(stdout_file, file); + try stdout_file.writeFileAll(file, .{}); } } if (!catted_anything) { - try cat_file(stdout_file, io.getStdIn()); + try stdout_file.writeFileAll(io.getStdIn(), .{}); } } @@ -47,20 +44,3 @@ fn usage(exe: []const u8) !void { warn("Usage: {} [FILE]...\n", .{exe}); return error.Invalid; } - -// TODO use copy_file_range -fn cat_file(stdout: fs.File, file: fs.File) !void { - var fifo = std.fifo.LinearFifo(u8, .{ .Static = 1024 * 4 }).init(); - - fifo.pump(file.reader(), stdout.writer()) catch |err| { - warn("Unable to read from stream or write to stdout: {}\n", .{@errorName(err)}); - return err; - }; -} - -fn unwrapArg(arg: anyerror![]u8) ![]u8 { - return arg catch |err| { - warn("Unable to parse command line: {}\n", .{err}); - return err; - }; -} diff --git a/test/standalone/shared_library/build.zig b/test/standalone/shared_library/build.zig index cb7437bcaaae3a37f37a6be65c080b76c7f20e16..18188311c7b2ba22e9c078ba5b1759854e066b94 100644 --- a/test/standalone/shared_library/build.zig +++ b/test/standalone/shared_library/build.zig @@ -1,9 +1,12 @@ const Builder = @import("std").build.Builder; pub fn build(b: *Builder) void { + const target = b.standardTargetOptions(.{}); const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); + lib.setTarget(target); const exe = b.addExecutable("test", null); + exe.setTarget(target); exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); exe.linkLibrary(lib); exe.linkSystemLibrary("c"); -- 2.54.0