| author | |
| committer | |
| log | 6d52678a6cfee1bc05d995bef8d963a5921ed8ea |
| tree | add8e77992efcfe39504068a95f9da74e59d7df2 |
| parent | ec02571a30e2975039cef5cb92467082ea5de5c0 |
These functions can only be exported when external libc components are
available due to the errno location dependency. Note that even when zig
libc is complete, on Windows, errno location will always be external (in
ucrtbase.dll).3 files changed, 40 insertions(+), 22 deletions(-)
build.zig+1-1| ... | @@ -518,7 +518,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -518,7 +518,7 @@ pub fn build(b: *std.Build) !void { |
| 518 | .test_extra_targets = test_extra_targets, | 518 | .test_extra_targets = test_extra_targets, |
| 519 | .root_src = "lib/c.zig", | 519 | .root_src = "lib/c.zig", |
| 520 | .name = "zigc", | 520 | .name = "zigc", |
| 521 | .desc = "Run the zigc tests", | 521 | .desc = "Run the zig libc implementation unit tests", |
| 522 | .optimize_modes = optimization_modes, | 522 | .optimize_modes = optimization_modes, |
| 523 | .include_paths = &.{}, | 523 | .include_paths = &.{}, |
| 524 | .skip_single_threaded = true, | 524 | .skip_single_threaded = true, |
lib/c.zig+25-10| ... | @@ -15,17 +15,32 @@ pub const panic = if (builtin.is_test) | ... | @@ -15,17 +15,32 @@ pub const panic = if (builtin.is_test) |
| 15 | else | 15 | else |
| 16 | std.debug.no_panic; | 16 | std.debug.no_panic; |
| 17 | 17 | ||
| 18 | /// Determines the symbol's visibility to other objects. | 18 | /// It is possible that this libc is being linked into a different test |
| 19 | /// For WebAssembly this allows the symbol to be resolved to other modules, but will not | 19 | /// compilation, as opposed to being tested itself. In such case, |
| 20 | /// export it to the host runtime. | 20 | /// `builtin.link_libc` will be `true` along with `builtin.is_test`. |
| 21 | pub const visibility: std.builtin.SymbolVisibility = .hidden; | 21 | /// |
| 22 | 22 | /// When we don't have a complete libc, `builtin.link_libc` will be `false` and | |
| 23 | /// we will be missing externally provided symbols, such as `_errno` from | ||
| 24 | /// ucrtbase.dll. In such case, we must avoid analyzing otherwise exported | ||
| 25 | /// functions because it would cause undefined symbol usage. | ||
| 26 | /// | ||
| 27 | /// Unfortunately such logic cannot be automatically done in this function body | ||
| 28 | /// since `func` will always be analyzed by the time we get here, so `comptime` | ||
| 29 | /// blocks will need to each check for `builtin.link_libc` and skip exports | ||
| 30 | /// when the exported functions have libc dependencies not provided by this | ||
| 31 | /// compilation unit. | ||
| 23 | pub inline fn symbol(comptime func: *const anyopaque, comptime name: []const u8) void { | 32 | pub inline fn symbol(comptime func: *const anyopaque, comptime name: []const u8) void { |
| 24 | // Normally, libc goes into a static archive, making all symbols | 33 | @export(func, .{ |
| 25 | // overridable. However, Zig supports including the libc functions as part | 34 | .name = name, |
| 26 | // of the Zig Compilation Unit, so to support this use case we make all | 35 | // Normally, libc goes into a static archive, making all symbols |
| 27 | // symbols weak. | 36 | // overridable. However, Zig supports including the libc functions as part |
| 28 | @export(func, .{ .name = name, .linkage = .weak, .visibility = visibility }); | 37 | // of the Zig Compilation Unit, so to support this use case we make all |
| 38 | // symbols weak. | ||
| 39 | .linkage = .weak, | ||
| 40 | // For WebAssembly, hidden visibility allows the symbol to be resolved to | ||
| 41 | // other modules, but will not export it to the host runtime. | ||
| 42 | .visibility = .hidden, | ||
| 43 | }); | ||
| 29 | } | 44 | } |
| 30 | 45 | ||
| 31 | /// Given a low-level syscall return value, sets errno and returns `-1`, or on | 46 | /// Given a low-level syscall return value, sets errno and returns `-1`, or on |
lib/c/malloc.zig+14-11| ... | @@ -23,17 +23,20 @@ const alignment: Alignment = .fromByteUnits(alignment_bytes); | ... | @@ -23,17 +23,20 @@ const alignment: Alignment = .fromByteUnits(alignment_bytes); |
| 23 | const symbol = @import("../c.zig").symbol; | 23 | const symbol = @import("../c.zig").symbol; |
| 24 | 24 | ||
| 25 | comptime { | 25 | comptime { |
| 26 | symbol(&malloc, "malloc"); | 26 | // Dependency on external errno location. |
| 27 | symbol(&aligned_alloc, "aligned_alloc"); | 27 | if (builtin.link_libc) { |
| 28 | symbol(&posix_memalign, "posix_memalign"); | 28 | symbol(&malloc, "malloc"); |
| 29 | symbol(&calloc, "calloc"); | 29 | symbol(&aligned_alloc, "aligned_alloc"); |
| 30 | symbol(&realloc, "realloc"); | 30 | symbol(&posix_memalign, "posix_memalign"); |
| 31 | symbol(&reallocarray, "reallocarray"); | 31 | symbol(&calloc, "calloc"); |
| 32 | symbol(&free, "free"); | 32 | symbol(&realloc, "realloc"); |
| 33 | symbol(&malloc_usable_size, "malloc_usable_size"); | 33 | symbol(&reallocarray, "reallocarray"); |
| 34 | 34 | symbol(&free, "free"); | |
| 35 | symbol(&valloc, "valloc"); | 35 | symbol(&malloc_usable_size, "malloc_usable_size"); |
| 36 | symbol(&memalign, "memalign"); | 36 | |
| 37 | symbol(&valloc, "valloc"); | ||
| 38 | symbol(&memalign, "memalign"); | ||
| 39 | } | ||
| 37 | } | 40 | } |
| 38 | 41 | ||
| 39 | const no_context: *anyopaque = undefined; | 42 | const no_context: *anyopaque = undefined; |