| author | |
| committer | |
| log | 429a219f42c93957dee41021a22547549a8c54a2 |
| tree | 43cd5f8a742d0d936e4f09cf9d31af344b7b0444 |
| parent | c55984b58f6a235893556f0b906e1ba3d301ec12 |
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.3 files changed, 28 insertions(+), 34 deletions(-)
src/Compilation.zig+13-2| ... | ... | @@ -510,8 +510,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 510 | 510 | { |
| 511 | 511 | break :dl true; |
| 512 | 512 | } |
| 513 | if (options.system_libs.len != 0) { | |
| 514 | // when creating a executable that links to system libraries, | |
| 513 | const any_dyn_libs: bool = x: { | |
| 514 | if (options.system_libs.len != 0) | |
| 515 | break :x true; | |
| 516 | for (options.link_objects) |obj| { | |
| 517 | switch (classifyFileExt(obj)) { | |
| 518 | .shared_library => break :x true, | |
| 519 | else => continue, | |
| 520 | } | |
| 521 | } | |
| 522 | break :x false; | |
| 523 | }; | |
| 524 | if (any_dyn_libs) { | |
| 525 | // When creating a executable that links to system libraries, | |
| 515 | 526 | // we require dynamic linking, but we must not link static libraries |
| 516 | 527 | // or object files dynamically! |
| 517 | 528 | break :dl (options.output_mode == .Exe); |
test/standalone/cat/main.zig+12-32| ... | ... | @@ -5,41 +5,38 @@ const fs = std.fs; |
| 5 | 5 | const mem = std.mem; |
| 6 | 6 | const warn = std.log.warn; |
| 7 | 7 | |
| 8 | var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; | |
| 9 | const allocator = &general_purpose_allocator.allocator; | |
| 10 | ||
| 11 | 8 | pub fn main() !void { |
| 12 | defer _ = general_purpose_allocator.deinit(); | |
| 9 | var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); | |
| 10 | defer arena_instance.deinit(); | |
| 11 | const arena = &arena_instance.allocator; | |
| 12 | ||
| 13 | const args = try process.argsAlloc(arena); | |
| 13 | 14 | |
| 14 | var args_it = process.args(); | |
| 15 | const exe = try unwrapArg(args_it.next(allocator).?); | |
| 16 | defer allocator.free(exe); | |
| 15 | const exe = args[0]; | |
| 17 | 16 | var catted_anything = false; |
| 18 | 17 | const stdout_file = io.getStdOut(); |
| 19 | 18 | |
| 20 | 19 | const cwd = fs.cwd(); |
| 21 | 20 | |
| 22 | while (args_it.next(allocator)) |arg_or_err| { | |
| 23 | const arg = try unwrapArg(arg_or_err); | |
| 24 | defer allocator.free(arg); | |
| 21 | for (args[1..]) |arg| { | |
| 25 | 22 | if (mem.eql(u8, arg, "-")) { |
| 26 | 23 | catted_anything = true; |
| 27 | try cat_file(stdout_file, io.getStdIn()); | |
| 28 | } else if (arg[0] == '-') { | |
| 24 | try stdout_file.writeFileAll(io.getStdIn(), .{}); | |
| 25 | } else if (mem.startsWith(u8, arg, "-")) { | |
| 29 | 26 | return usage(exe); |
| 30 | 27 | } else { |
| 31 | 28 | const file = cwd.openFile(arg, .{}) catch |err| { |
| 32 | warn("Unable to open file: {}\n", .{@errorName(err)}); | |
| 29 | warn("Unable to open file: {s}\n", .{@errorName(err)}); | |
| 33 | 30 | return err; |
| 34 | 31 | }; |
| 35 | 32 | defer file.close(); |
| 36 | 33 | |
| 37 | 34 | catted_anything = true; |
| 38 | try cat_file(stdout_file, file); | |
| 35 | try stdout_file.writeFileAll(file, .{}); | |
| 39 | 36 | } |
| 40 | 37 | } |
| 41 | 38 | if (!catted_anything) { |
| 42 | try cat_file(stdout_file, io.getStdIn()); | |
| 39 | try stdout_file.writeFileAll(io.getStdIn(), .{}); | |
| 43 | 40 | } |
| 44 | 41 | } |
| 45 | 42 | |
| ... | ... | @@ -47,20 +44,3 @@ fn usage(exe: []const u8) !void { |
| 47 | 44 | warn("Usage: {} [FILE]...\n", .{exe}); |
| 48 | 45 | return error.Invalid; |
| 49 | 46 | } |
| 50 | ||
| 51 | // TODO use copy_file_range | |
| 52 | fn cat_file(stdout: fs.File, file: fs.File) !void { | |
| 53 | var fifo = std.fifo.LinearFifo(u8, .{ .Static = 1024 * 4 }).init(); | |
| 54 | ||
| 55 | fifo.pump(file.reader(), stdout.writer()) catch |err| { | |
| 56 | warn("Unable to read from stream or write to stdout: {}\n", .{@errorName(err)}); | |
| 57 | return err; | |
| 58 | }; | |
| 59 | } | |
| 60 | ||
| 61 | fn unwrapArg(arg: anyerror![]u8) ![]u8 { | |
| 62 | return arg catch |err| { | |
| 63 | warn("Unable to parse command line: {}\n", .{err}); | |
| 64 | return err; | |
| 65 | }; | |
| 66 | } |
test/standalone/shared_library/build.zig+3| ... | ... | @@ -1,9 +1,12 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | 3 | pub fn build(b: *Builder) void { |
| 4 | const target = b.standardTargetOptions(.{}); | |
| 4 | 5 | const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); |
| 6 | lib.setTarget(target); | |
| 5 | 7 | |
| 6 | 8 | const exe = b.addExecutable("test", null); |
| 9 | exe.setTarget(target); | |
| 7 | 10 | exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"}); |
| 8 | 11 | exe.linkLibrary(lib); |
| 9 | 12 | exe.linkSystemLibrary("c"); |