Compiling Zig compiler to `wasm32-wasi` target
eliot-akira opened this issue · comments
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
Clone Zig and compile the compiler to wasm32-wasi
target.
git clone --recursive --depth 1 --single-branch --branch master https://github.com/ziglang/zig
cd zig
zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall -Dno-langref -Dno-lib
It results in errors.
~/zig/build.zig:600:25: error: no field or member function named 'addUpdateSourceFiles' in 'Build'
const copy_zig_h = b.addUpdateSourceFiles();
~^~~~~~~~~~~~~~~~~~~~~
~/.local/lib/zig/lib/std/Build.zig:1:1: note: struct declared here
const std = @import("std.zig");
^~~~~
referenced by:
build: ~/zig/build.zig:537:9
runBuild__anon_8848: ~/.local/lib/zig/lib/std/Build.zig:2117:37
remaining reference traces hidden; use '-freference-trace' to see all reference traces
~/zig/build.zig:1289:64: error: no field named 'zig_lib_directory' in struct 'Build.Graph'
cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{}", .{b.graph.zig_lib_directory}) });
^~~~~~~~~~~~~~~~~
~/.local/lib/zig/lib/std/Build.zig:112:19: note: struct declared here
pub const Graph = struct {
^~~~~~
~/zig/test/tests.zig:775:45: error: type '[]const u8' does not support struct initialization syntax
const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path });
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
~/zig/test/standalone/cmakedefine/build.zig:83:66: error: root struct of file 'Build.Step' has no member named 'MakeOptions'
fn compare_headers(step: *std.Build.Step, options: std.Build.Step.MakeOptions) !void {
~~~~~~~~~~~~~~^~~~~~~~~~~~
~/.local/lib/zig/lib/std/Build/Step.zig:1:1: note: struct declared here
id: Id,
^~
Expected Behavior
The Zig compiler can be compiled to wasm32-wasi
target for running in the browser.
Attempts toward a solution
The closest solution I found is in the Zig Playground repo, specifically ZIG_WASM.md
.
It's a patch that allows the compilation to succeed. I'll include it below for reference.
diff --git a/build.zig b/build.zig
index 9e6e86386..ec8b6b9bd 100644
--- a/build.zig
+++ b/build.zig
@@ -237,7 +237,7 @@ pub fn build(b: *std.Build) !void {
exe_options.addOption(bool, "llvm_has_xtensa", llvm_has_xtensa);
exe_options.addOption(bool, "force_gpa", force_gpa);
exe_options.addOption(bool, "only_c", only_c);
- exe_options.addOption(bool, "only_core_functionality", only_c);
+ exe_options.addOption(bool, "only_core_functionality", true);
if (link_libc) {
exe.linkLibC();
diff --git a/src/link.zig b/src/link.zig
index 703dfb873..3bc4039e7 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -765,9 +765,9 @@ pub const File = struct {
/// Commit pending changes and write headers. Takes into account final output mode
/// and `use_lld`, not only `effectiveOutputMode`.
pub fn flush(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
- if (build_options.only_c) {
- assert(base.tag == .c);
- return @fieldParentPtr(C, "base", base).flush(comp, prog_node);
+ if (true) {
+ assert(base.tag == .wasm);
+ return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node);
}
if (comp.clang_preprocessor_mode == .yes) {
const emit = base.options.emit orelse return; // -fno-emit-bin
diff --git a/src/link/Wasm/Archive.zig b/src/link/Wasm/Archive.zig
index c4fb9b829..7fdc018ab 100644
--- a/src/link/Wasm/Archive.zig
+++ b/src/link/Wasm/Archive.zig
@@ -208,9 +208,9 @@ pub fn parseObject(archive: Archive, allocator: Allocator, file_offset: u32) !Ob
const object_name = try archive.parseName(header);
const name = name: {
- var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
- const path = try std.os.realpath(archive.name, &buffer);
- break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ path, object_name });
+ // var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
+ // const path = try std.os.realpath(archive.name, &buffer);
+ break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ archive.name, object_name });
};
defer allocator.free(name);
diff --git a/src/main.zig b/src/main.zig
index 39a7adc42..616518d15 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -200,7 +200,7 @@ pub fn main() anyerror!void {
}
// Short circuit some of the other logic for bootstrapping.
- if (build_options.only_c) {
+ if (true) {
if (mem.eql(u8, args[1], "build-exe")) {
return buildOutputType(gpa, arena, args, .{ .build = .Exe });
} else if (mem.eql(u8, args[1], "build-obj")) {
@@ -1544,7 +1544,7 @@ fn buildOutputType(
}
},
.cc, .cpp => {
- if (build_options.only_c) unreachable;
+ if (true) unreachable;
emit_h = .no;
soname = .no;
@@ -3238,7 +3238,7 @@ fn buildOutputType(
switch (listen) {
.none => {},
.stdio => {
- if (build_options.only_c) unreachable;
+ if (true) unreachable;
try serve(
comp,
std.io.getStdIn(),
@@ -3286,7 +3286,7 @@ fn buildOutputType(
error.SemanticAnalyzeFail => if (listen == .none) process.exit(1),
else => |e| return e,
};
- if (build_options.only_c) return cleanExit();
+ if (true) return cleanExit();
try comp.makeBinFileExecutable();
if (test_exec_args.items.len == 0 and object_format == .c) default_exec_args: {
Notably, I found the patch only works for Zig version 0.11
.
Versions above 0.11
result in compile errors related to os.realpath()
. I think the following issue is related:
On version 0.13
, for example, after applying the patch and running below (removed deprecated option -Dno-autodocs
and added option -freference-trace
recommended by the error message).
zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall -Dno-langref -Dno-lib -freference-trace
The error:
~/.local/lib/zig/lib/std/posix.zig:5340:9: error: WASI does not support os.realpath
@compileError("WASI does not support os.realpath");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
realpathAlloc: ~/.local/lib/zig/lib/std/fs.zig:726:40
create: src/codegen/llvm.zig:913:38
create: src/Compilation.zig:1649:64
buildOutputType: src/main.zig:3213:29
main: src/main.zig:203:20
callMain: ~/.local/lib/zig/lib/std/start.zig:524:32
wasi_start: ~/.local/lib/zig/lib/std/start.zig:207:65
Actual errors if you build it correctly:
src/introspect.zig:41:9: error: this function is unsupported on WASI
@compileError("this function is unsupported on WASI");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/introspect.zig:85:9: error: on WASI the global cache dir must be resolved with preopens
@compileError("on WASI the global cache dir must be resolved with preopens");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/std/posix.zig:145:28: error: root struct of file 'c' has no member named 'sockaddr'
pub const sockaddr = system.sockaddr;
~~~~~~^~~~~~~~~
lib/std/c.zig:1:1: note: struct declared here
const std = @import("std");
Command (change your paths to whatever matches your system):
~/release.z/zig-linux-x86_64-0.14.0-dev.311+c50f30038/zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSmall --zig-lib-dir ~/git/ziglang/zig/lib
Thank you for the response.
OK, so I'll set the options as suggested, especially --zig-lib-dir
to point to lib
in the source directory. I did make sure to use the same version of the compiler as the source to compile itself.
Maybe this should have been posted as a question in the forums, or a feature request for an additional target in ziglang/zig-bootstrap.
#10716
Seems to be a regression