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