Reputation: 143
Is there a way to use zig compiler as a library inside zig? After looking both in zig documentation, issues and on the internet, I can't find an answer to this question.
In one of the issues it is said that this can be done at the current time, but I couldn't find any examples of how to do it.
Upvotes: 4
Views: 1275
Reputation: 3577
It is currently non-trivial to use the zig compiler as a library due to the difficulty in including libraries with complicated build requirements. Once the package manager is released, it will likely become much easier.
For now, I would recommend calling the zig compiler as a system command
var zig = std.ChildProcess.init(&.{"zig", "build-exe", "demo.zig"}, allocator);
try zig.spawn();
try zig.wait();
However, if you really want to, here is how to use zig 0.9.0-dev.1611+f3ba72cf5
as a library
Reasons not to do this before the package manager is released:
This build.zig was made by finding all the instances of .addOption in the zig compiler's build.zig and recreating them in our own build.zig file.
// build.zig
const std = @import("std");
pub fn build(b: *std.build.Builder) !void {
const target = b.standardTargetOptions(.{});
const mode = b.standardReleaseOptions();
const exe_options = b.addOptions();
const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse 4;
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
const enable_logging = b.option(bool, "log", "Whether to enable logging") orelse false;
const enable_link_snapshots = b.option(bool, "link-snapshot", "Whether to enable linker state snapshots") orelse false;
exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames);
exe_options.addOption(bool, "skip_non_native", skip_non_native);
exe_options.addOption(bool, "have_llvm", false);
exe_options.addOption(bool, "llvm_has_m68k", false);
exe_options.addOption(bool, "llvm_has_csky", false);
exe_options.addOption(bool, "llvm_has_ve", false);
exe_options.addOption(bool, "llvm_has_arc", false);
const version = "0.0.0";
exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
const semver = try std.SemanticVersion.parse(version);
exe_options.addOption(std.SemanticVersion, "semver", semver);
exe_options.addOption(bool, "enable_logging", enable_logging);
exe_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
exe_options.addOption(bool, "enable_tracy", false);
exe_options.addOption(bool, "enable_tracy_callstack", false);
exe_options.addOption(bool, "enable_tracy_allocation", false);
exe_options.addOption(bool, "is_stage1", false);
exe_options.addOption(bool, "omit_stage2", false);
const exe = b.addExecutable("tmp", "sample.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.addOptions("build_options", exe_options);
exe.addPackage(.{
.name = "zig",
.path = .{ .path = "src/main.zig" },
.dependencies = &[_]std.build.Pkg{
.{ .name = "build_options", .path = exe_options.getSource() },
},
});
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
// sample.zig
const zig = @import("zig");
pub fn main() !void {
return zig.main(); // just calls into the zig compiler main function. you'll have to look into how https://github.com/ziglang/zig/blob/master/src/main.zig works in order to do more complicated stuff.
}
note: I recommend building this with -Dskip-non-native otherwise it will take a very long time to build due to the speed of the current stage1 compiler
zig build run -Dskip-non-native -- build-exe demo.zig
Upvotes: 3