├── .gitignore ├── README.md ├── ZigValaStep.zig └── samples └── basic ├── ZigValaStep.zig ├── build.zig └── src └── main.vala /.gitignore: -------------------------------------------------------------------------------- 1 | **/zig-cache/* 2 | **/zig-out/* 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zig-vala 2 | Integration of Vala with Zig('s Build System). 3 | 4 | # Usage 5 | The easiest way to use it is to just download ``ZigValaStep.zig`` to your project directory. 6 | Then include it in your build.zig: 7 | ```zig 8 | const ZigValaStep = @import("ZigValaStep.zig"); 9 | ``` 10 | 11 | You can create a Vala application as such: 12 | ```zig 13 | const vala = ZigValaStep.init(b, "app_name"); 14 | ``` 15 | 16 | Add source files: 17 | ```zig 18 | vala.addSourceFile("src/main.vala"); 19 | ``` 20 | 21 | Next, add all the package dependencies, such as GTK3, for example: 22 | ```zig 23 | vala.addPackage("gtk+-3.0); 24 | ``` 25 | 26 | Finally, hook up the executable: 27 | ```zig 28 | vala.exe.setTarget(target); 29 | vala.exe.setBuildMode(mode); 30 | vala.exe.install(); 31 | ``` 32 | 33 | # License 34 | ``ZigValaStep.zig`` is licensed under MIT License. -------------------------------------------------------------------------------- /ZigValaStep.zig: -------------------------------------------------------------------------------- 1 | // ZigValaStep.zig - Integration of Vala with Zig. 2 | // Copyright 2021 iddev5. Licensed under MIT License. 3 | const std = @import("std"); 4 | const Step = std.build.Step; 5 | const Builder = std.build.Builder; 6 | 7 | builder: *Builder, 8 | step: Step, 9 | exe: *std.build.LibExeObjStep, 10 | files: std.ArrayList([]const u8), 11 | deps: std.ArrayList([]const u8), 12 | path: []const u8, 13 | 14 | const ZigValaStep = @This(); 15 | 16 | pub fn init(b: *Builder, name: []const u8) *ZigValaStep { 17 | var res = b.allocator.create(ZigValaStep) catch @panic("out of memory"); 18 | res.* = .{ 19 | .files = std.ArrayList([]const u8).init(b.allocator), 20 | .step = Step.init(.custom, "compile a vala project", b.allocator, make), 21 | .exe = b.addExecutable(name, null), 22 | .builder = b, 23 | .deps = std.ArrayList([]const u8).init(b.allocator), 24 | .path = std.fs.path.join(b.allocator, &.{ b.build_root, "zig-cache", "vala" }) catch @panic("out of memory"), 25 | }; 26 | 27 | res.exe.step.dependOn(&res.step); 28 | res.exe.linkLibC(); 29 | 30 | return res; 31 | } 32 | 33 | pub fn addSourceFile(self: *ZigValaStep, file: []const u8) void { 34 | const allocator = self.builder.allocator; 35 | 36 | const c_file = std.fs.path.join(allocator, &.{ 37 | self.path, 38 | std.mem.concat( 39 | allocator, 40 | u8, 41 | &.{ removeExtension(file), ".c" }, 42 | ) catch @panic("out of memory"), 43 | }) catch @panic("out of memory"); 44 | defer allocator.free(c_file); 45 | 46 | self.exe.addCSourceFile(c_file, &.{}); 47 | self.files.append(file) catch @panic("out of memory"); 48 | } 49 | 50 | pub fn addPackage(self: *ZigValaStep, pkg: []const u8) void { 51 | self.deps.append(pkg) catch @panic("out of memory"); 52 | self.exe.linkSystemLibrary(pkg); 53 | } 54 | 55 | fn removeExtension(filename: []const u8) []const u8 { 56 | const index = std.mem.lastIndexOfScalar(u8, filename, '.') orelse return filename; 57 | if (index == 0) return filename; 58 | return filename[0..index]; 59 | } 60 | 61 | fn make(step: *Step) !void { 62 | const self = @fieldParentPtr(ZigValaStep, "step", step); 63 | const builder = self.builder; 64 | const allocator = builder.allocator; 65 | 66 | var args = std.ArrayList([]const u8).init(allocator); 67 | defer args.deinit(); 68 | 69 | try args.append("valac"); 70 | try args.append("-C"); 71 | try args.append("-d"); 72 | try args.append(self.path); 73 | 74 | for (self.files.items) |file| { 75 | try args.append(file); 76 | } 77 | 78 | for (self.deps.items) |dep| { 79 | try args.append("--pkg"); 80 | try args.append(dep); 81 | } 82 | 83 | const proc = try std.ChildProcess.init(args.items, allocator); 84 | defer proc.deinit(); 85 | 86 | proc.stdin_behavior = .Ignore; 87 | proc.stdout_behavior = .Inherit; 88 | proc.stderr_behavior = .Inherit; 89 | proc.cwd = builder.build_root; 90 | proc.env_map = builder.env_map; 91 | 92 | try proc.spawn(); 93 | const result = try proc.wait(); 94 | switch (result) { 95 | .Exited => |code| if (code != 0) { 96 | std.os.exit(0xff); 97 | }, 98 | else => { 99 | std.log.err("valac failed with: {}", .{result}); 100 | std.os.exit(0xff); 101 | }, 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /samples/basic/ZigValaStep.zig: -------------------------------------------------------------------------------- 1 | ../../ZigValaStep.zig -------------------------------------------------------------------------------- /samples/basic/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const ZigValaStep = @import("ZigValaStep.zig"); 3 | 4 | pub fn build(b: *std.build.Builder) void { 5 | const target = b.standardTargetOptions(.{}); 6 | const mode = b.standardReleaseOptions(); 7 | 8 | const vala = ZigValaStep.init(b, "basic"); 9 | vala.addSourceFile("src/main.vala"); 10 | vala.addPackage("gtk+-3.0"); 11 | vala.exe.setTarget(target); 12 | vala.exe.setBuildMode(mode); 13 | vala.exe.install(); 14 | 15 | const run_cmd = vala.exe.run(); 16 | run_cmd.step.dependOn(b.getInstallStep()); 17 | if (b.args) |args| { 18 | run_cmd.addArgs(args); 19 | } 20 | 21 | const run_step = b.step("run", "Run the app"); 22 | run_step.dependOn(&run_cmd.step); 23 | } 24 | -------------------------------------------------------------------------------- /samples/basic/src/main.vala: -------------------------------------------------------------------------------- 1 | class TestApp : Gtk.Application { 2 | public TestApp() { 3 | GLib.Object(application_id: "org.iddev.testapp"); 4 | } 5 | 6 | public override void activate() { 7 | var window = new Gtk.Window(); 8 | window.title = "test app"; 9 | window.window_position = Gtk.WindowPosition.CENTER; 10 | window.set_default_size(800, 600); 11 | 12 | this.add_window(window); 13 | 14 | window.show_all(); 15 | } 16 | } 17 | 18 | int main(string[] args) { 19 | var app = new TestApp(); 20 | return app.run(args); 21 | } 22 | --------------------------------------------------------------------------------