Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
optimize: [ReleaseSmall, Debug]
steps:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
- uses: mlugg/setup-zig@v1
- name: Build
run: |
zig build -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
- name: Test
run: |
zig build test
zig build test -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
windows:
runs-on: windows-latest
strategy:
Expand All @@ -34,13 +34,14 @@ jobs:
optimize: [ReleaseSmall, Debug]
steps:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
- uses: mlugg/setup-zig@v1
- name: Build
run: |
zig build -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
- name: Test
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
zig build test
zig build test -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
linux:
runs-on: ubuntu-latest
strategy:
Expand All @@ -49,10 +50,11 @@ jobs:
optimize: [ReleaseSmall, Debug]
steps:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
- uses: mlugg/setup-zig@v1
- uses: docker/setup-qemu-action@v3
- name: Build
run: |
zig build -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
- name: Test
run: |
zig build test
zig build test -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
zig-out
zig-cache
.zig-cache
result
result-*
node_modules
271 changes: 28 additions & 243 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,271 +1,56 @@
const std = @import("std");
const metap = @import("metaplus").@"meta+";

pub const Sdk = @import("src/phantom/sdk.zig");

pub const DisplayBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/display/backends.zig")), Sdk.TypeFor(.displays));
pub const FontBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/fonts/backends.zig")), Sdk.TypeFor(.fonts));
pub const PlatformBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/platform/backends.zig")), Sdk.TypeFor(.platforms));
pub const SceneBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/scene/backends.zig")), Sdk.TypeFor(.scenes));
pub const ImageFormatType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/painting/image/formats.zig")), Sdk.TypeFor(.imageFormats));

fn addSourceFiles(
b: *std.Build,
fileOverrides: *std.StringHashMap([]const u8),
rootSource: *[]const u8,
phantomSource: *std.Build.Step.WriteFile,
rootPath: []const u8,
) !void {
var depSourceRoot = try std.fs.openDirAbsolute(b.pathJoin(&.{ rootPath, "phantom" }), .{ .iterate = true });
defer depSourceRoot.close();

var walker = try depSourceRoot.walk(b.allocator);
defer walker.deinit();

while (try walker.next()) |entry| {
if (entry.kind == .directory) continue;

const entryPath = b.pathJoin(&.{ rootPath, "phantom", entry.path });
var entrySource = try Sdk.readAll(b.allocator, entryPath);
errdefer b.allocator.free(entrySource);

const entrypointRel = try std.fs.path.relative(b.allocator, std.fs.path.dirname(entryPath).?, b.pathJoin(&.{ rootPath, "phantom.zig" }));
defer b.allocator.free(entrypointRel);

const entrySourceOrig = entrySource;
entrySource = try std.mem.replaceOwned(u8, b.allocator, entrySourceOrig, "@import(\"phantom\")", b.fmt("@import(\"{s}\")", .{entrypointRel}));
b.allocator.free(entrySourceOrig);

if (fileOverrides.getPtr(entry.path)) |sourceptr| {
const fullSource = try Sdk.updateSource(b.allocator, sourceptr.*, entrySource);
errdefer b.allocator.free(fullSource);

b.allocator.free(sourceptr.*);
sourceptr.* = fullSource;
} else {
const origPath = b.pathFromRoot(b.pathJoin(&.{ "src/phantom", entry.path }));
if (Sdk.readAll(b.allocator, origPath) catch null) |origSource| {
defer b.allocator.free(origSource);

const fullSource = try Sdk.updateSource(b.allocator, origSource, entrySource);
errdefer b.allocator.free(fullSource);

try fileOverrides.put(try b.allocator.dupe(u8, entry.path), fullSource);
b.allocator.free(entrySource);
} else {
_ = phantomSource.add(b.pathJoin(&.{ "phantom", entry.path }), entrySource);
}
}
}

const src = try Sdk.readAll(b.allocator, b.pathJoin(&.{ rootPath, "phantom.zig" }));
defer b.allocator.free(src);

const fullSource = try Sdk.updateSource(b.allocator, rootSource.*, src);
errdefer b.allocator.free(fullSource);

b.allocator.free(rootSource.*);
rootSource.* = fullSource;
}

pub fn build(b: *std.Build) !void {
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const no_docs = b.option(bool, "no-docs", "skip installing documentation") orelse false;
const no_importer = b.option(bool, "no-importer", "disables the import system (not recommended)") orelse false;
const display_backend = b.option(DisplayBackendType, "display-backend", "The display backend to use for the example") orelse .headless;
const platform_backend = b.option(PlatformBackendType, "platform-backend", "The display backend to use for the example") orelse .std;
const scene_backend = b.option(SceneBackendType, "scene-backend", "The scene backend to use for the example") orelse .headless;

const vizops = b.dependency("vizops", .{
const zigimg = b.dependency("zigimg", .{
.target = target,
.optimize = optimize,
});

const metaplus = b.dependency("metaplus", .{
const z2d = b.dependency("z2d", .{
.target = target,
.optimize = optimize,
});

const anyplus = b.dependency("any+", .{
const module = b.addModule("phantom", .{
.root_source_file = b.path("lib/phantom.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{
.name = "zigimg",
.module = zigimg.module("zigimg"),
},
.{
.name = "z2d",
.module = z2d.module("z2d"),
},
},
});

const phantomOptions = b.addOptions();
phantomOptions.addOption(bool, "no_importer", no_importer);

var phantomDeps = std.ArrayList(std.Build.Module.Import).init(b.allocator);
errdefer phantomDeps.deinit();

try phantomDeps.append(.{
.name = "vizops",
.module = vizops.module("vizops"),
});

try phantomDeps.append(.{
.name = "meta+",
.module = metaplus.module("meta+"),
});

try phantomDeps.append(.{
.name = "any+",
.module = anyplus.module("any+"),
const autodoc_test = b.addObject(.{
.name = "phantom",
.root_module = module,
});

try phantomDeps.append(.{
.name = "phantom.options",
.module = phantomOptions.createModule(),
const install_docs = b.addInstallDirectory(.{
.source_dir = autodoc_test.getEmittedDocs(),
.install_dir = .prefix,
.install_subdir = "doc/phantom",
});

const phantomSource = b.addWriteFiles();

var fileOverrides = std.StringHashMap([]const u8).init(b.allocator);
defer fileOverrides.deinit();

var rootSource = try Sdk.readAll(b.allocator, b.pathFromRoot("src/phantom.zig"));
defer b.allocator.free(rootSource);

if (!no_importer) {
inline for (Sdk.availableDepenencies) |dep| {
const pkg = @field(@import("root").dependencies.packages, dep[1]);
const pkgdep = b.dependencyInner(dep[0], pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg.deps, .{
.target = target,
.optimize = optimize,
.@"no-importer" = true,
});
b.getInstallStep().dependOn(&install_docs.step);

const depSourceRootPath = b.pathJoin(&.{ pkg.build_root, "src" });
try addSourceFiles(b, &fileOverrides, &rootSource, phantomSource, depSourceRootPath);
const step_test = b.step("test", "Run unit tests");

var iter = pkgdep.module(dep[0]).import_table.iterator();
while (iter.next()) |entry| {
var alreadyExists = false;
for (phantomDeps.items) |i| {
if (std.mem.eql(u8, i.name, entry.key_ptr.*)) {
alreadyExists = true;
break;
}
}

if (!alreadyExists or !std.mem.eql(u8, entry.key_ptr.*, "phantom")) {
try phantomDeps.append(.{
.name = entry.key_ptr.*,
.module = entry.value_ptr.*,
});
}
}
}
}

if (b.option([]const u8, "import-module", "inject a module to be imported")) |importModuleString| {
const modulePathLen = std.mem.indexOf(u8, importModuleString, ":") orelse importModuleString.len;
const modulePath = importModuleString[0..modulePathLen];

try addSourceFiles(b, &fileOverrides, &rootSource, phantomSource, modulePath);

if (modulePathLen < importModuleString.len) {
const imports = try Sdk.ModuleImport.decode(b.allocator, importModuleString[(modulePathLen + 1)..]);
defer imports.deinit();

for (imports.value) |dep| {
var alreadyExists = false;
for (phantomDeps.items) |i| {
if (std.mem.eql(u8, i.name, dep.name)) {
alreadyExists = true;
break;
}

if (!alreadyExists or !std.mem.eql(u8, dep.name, "phantom")) {
try phantomDeps.append(.{
.name = dep.name,
.module = try dep.createModule(b, target, optimize),
});
}
}
}
}
}

var phantomSourceRoot = try std.fs.openDirAbsolute(b.pathFromRoot("src/phantom"), .{ .iterate = true });
defer phantomSourceRoot.close();

var walker = try phantomSourceRoot.walk(b.allocator);
defer walker.deinit();

while (try walker.next()) |entry| {
if (entry.kind == .directory) continue;

const entryPath = b.pathJoin(&.{ "phantom", entry.path });

if (fileOverrides.get(entry.path)) |source| {
_ = phantomSource.add(entryPath, source);
} else {
_ = phantomSource.addCopyFile(.{
.path = b.pathFromRoot(b.pathJoin(&.{ "src/phantom", entry.path })),
}, entryPath);
}
}

const phantom = b.addModule("phantom", .{
.root_source_file = phantomSource.add("phantom.zig", rootSource),
.imports = phantomDeps.items,
});

const step_test = b.step("test", "Run all unit tests");

const unit_tests = b.addTest(.{
.root_source_file = phantom.root_source_file.?,
const test_exe = b.addTest(.{
.target = target,
.optimize = optimize,
.root_module = module,
});

for (phantomDeps.items) |dep| {
unit_tests.root_module.addImport(dep.name, dep.module);
}

const run_unit_tests = b.addRunArtifact(unit_tests);
step_test.dependOn(&run_unit_tests.step);
b.installArtifact(unit_tests);

const exe_options = b.addOptions();
exe_options.addOption(DisplayBackendType, "display_backend", display_backend);
exe_options.addOption(PlatformBackendType, "platform_backend", platform_backend);
exe_options.addOption(SceneBackendType, "scene_backend", scene_backend);

const sdk = try Sdk.get(b, platform_backend, phantom);
defer sdk.deinit();

const pkg_example = sdk.addPackage(.{
.id = "dev.phantomui.example",
.name = "example",
.root_module = .{
.root_source_file = .{
.path = b.pathFromRoot("src/example.zig"),
},
.target = target,
.optimize = optimize,
},
.kind = .application,
.version = .{
.major = 0,
.minor = 1,
.patch = 0,
},
});

pkg_example.root_module.addImport("vizops", vizops.module("vizops"));
pkg_example.root_module.addImport("options", exe_options.createModule());

sdk.installPackage(pkg_example);

if (!no_docs) {
const docs = b.addInstallDirectory(.{
.source_dir = unit_tests.getEmittedDocs(),
.install_dir = .prefix,
.install_subdir = "docs",
});

b.getInstallStep().dependOn(&docs.step);
}
const test_run = b.addRunArtifact(test_exe);
step_test.dependOn(&test_run.step);
}
21 changes: 11 additions & 10 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
.{
.name = "phantom",
.name = .phantom,
.version = "0.1.0",
.paths = .{"."},
.dependencies = .{
.vizops = .{
.url = "http://gitlab.midstall.com/common/vizops/-/archive/cb7a23d02c3030056a59ff0cd856d95221e8da06/vizops-cb7a23d02c3030056a59ff0cd856d95221e8da06.tar.gz",
.hash = "1220813b3d22d110b409ec8619fc1da2bc2ba2e71eb37b6a921ad228b485135793be",
.zigimg = .{
.url = "https://github.com/TUSF/zigimg/archive/256cf2655bb887a30c57d8cbc1b9590643f0a824.tar.gz",
.hash = "zigimg-0.1.0-lly-O3AVEQBq5UYuvW77W180h6v41vJ9WXtBhrbLwtNH",
},
.metaplus = .{
.url = "http://gitlab.midstall.com/common/meta-plus/-/archive/9f8c3828e3c4445b80185dd24eeb61d0386b23dc/meta-plus-9f8c3828e3c4445b80185dd24eeb61d0386b23dc.tar.gz",
.hash = "122057d6a6bd7ba8b95fe67d91f584c4c0140ca26e8bea09b92f63b649dff470bf56",
.z2d = .{
.url = "https://github.com/vancluever/z2d/archive/67d2e2e1891cd467fb7cb7c072bcf33dae2589a4.tar.gz",
.hash = "z2d-0.6.2-j5P_HjzpCgBdWm_1K6nob_MIb5YQqW5zyUCX9B5QnUeZ",
},
.@"any+" = .{
.url = "http://gitlab.midstall.com/common/any-plus/-/archive/15e70210f0525fa619bfed533c1205ff57ac2100/any-plus-15e70210f0525fa619bfed533c1205ff57ac2100.tar.gz",
.hash = "12209b041a839e89ece510c07dbe62ad53b045ff0e6c44645cd1a3ea38f3b42905b9",
.@"zig-wayland" = .{
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
},
},
.fingerprint = 0x6896f6aeaa10b7f9,
}
Loading