|
1 | 1 | const std = @import("std");
|
2 |
| -const metap = @import("metaplus").@"meta+"; |
3 | 2 |
|
4 |
| -pub const Sdk = @import("src/phantom/sdk.zig"); |
| 3 | +const WaylandScanner = @import("zig-wayland").Scanner; |
5 | 4 |
|
6 |
| -pub const DisplayBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/display/backends.zig")), Sdk.TypeFor(.displays)); |
7 |
| -pub const FontBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/fonts/backends.zig")), Sdk.TypeFor(.fonts)); |
8 |
| -pub const PlatformBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/platform/backends.zig")), Sdk.TypeFor(.platforms)); |
9 |
| -pub const SceneBackendType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/scene/backends.zig")), Sdk.TypeFor(.scenes)); |
10 |
| -pub const ImageFormatType = metap.enums.fields.mix(metap.enums.fromDecls(@import("src/phantom/painting/image/formats.zig")), Sdk.TypeFor(.imageFormats)); |
11 |
| - |
12 |
| -fn addSourceFiles( |
13 |
| - b: *std.Build, |
14 |
| - fileOverrides: *std.StringHashMap([]const u8), |
15 |
| - rootSource: *[]const u8, |
16 |
| - phantomSource: *std.Build.Step.WriteFile, |
17 |
| - rootPath: []const u8, |
18 |
| -) !void { |
19 |
| - var depSourceRoot = try std.fs.openDirAbsolute(b.pathJoin(&.{ rootPath, "phantom" }), .{ .iterate = true }); |
20 |
| - defer depSourceRoot.close(); |
21 |
| - |
22 |
| - var walker = try depSourceRoot.walk(b.allocator); |
23 |
| - defer walker.deinit(); |
24 |
| - |
25 |
| - while (try walker.next()) |entry| { |
26 |
| - if (entry.kind == .directory) continue; |
27 |
| - |
28 |
| - const entryPath = b.pathJoin(&.{ rootPath, "phantom", entry.path }); |
29 |
| - var entrySource = try Sdk.readAll(b.allocator, entryPath); |
30 |
| - errdefer b.allocator.free(entrySource); |
31 |
| - |
32 |
| - const entrypointRel = try std.fs.path.relative(b.allocator, std.fs.path.dirname(entryPath).?, b.pathJoin(&.{ rootPath, "phantom.zig" })); |
33 |
| - defer b.allocator.free(entrypointRel); |
34 |
| - |
35 |
| - const entrySourceOrig = entrySource; |
36 |
| - entrySource = try std.mem.replaceOwned(u8, b.allocator, entrySourceOrig, "@import(\"phantom\")", b.fmt("@import(\"{s}\")", .{entrypointRel})); |
37 |
| - b.allocator.free(entrySourceOrig); |
38 |
| - |
39 |
| - if (fileOverrides.getPtr(entry.path)) |sourceptr| { |
40 |
| - const fullSource = try Sdk.updateSource(b.allocator, sourceptr.*, entrySource); |
41 |
| - errdefer b.allocator.free(fullSource); |
42 |
| - |
43 |
| - b.allocator.free(sourceptr.*); |
44 |
| - sourceptr.* = fullSource; |
45 |
| - } else { |
46 |
| - const origPath = b.pathFromRoot(b.pathJoin(&.{ "src/phantom", entry.path })); |
47 |
| - if (Sdk.readAll(b.allocator, origPath) catch null) |origSource| { |
48 |
| - defer b.allocator.free(origSource); |
49 |
| - |
50 |
| - const fullSource = try Sdk.updateSource(b.allocator, origSource, entrySource); |
51 |
| - errdefer b.allocator.free(fullSource); |
52 |
| - |
53 |
| - try fileOverrides.put(try b.allocator.dupe(u8, entry.path), fullSource); |
54 |
| - b.allocator.free(entrySource); |
55 |
| - } else { |
56 |
| - _ = phantomSource.add(b.pathJoin(&.{ "phantom", entry.path }), entrySource); |
57 |
| - } |
58 |
| - } |
59 |
| - } |
60 |
| - |
61 |
| - const src = try Sdk.readAll(b.allocator, b.pathJoin(&.{ rootPath, "phantom.zig" })); |
62 |
| - defer b.allocator.free(src); |
| 5 | +pub fn build(b: *std.Build) void { |
| 6 | + const target = b.standardTargetOptions(.{}); |
| 7 | + const optimize = b.standardOptimizeOption(.{}); |
| 8 | + const linkage = b.option(std.builtin.LinkMode, "linkage", "Whether to link as a static or dynamic binary"); |
63 | 9 |
|
64 |
| - const fullSource = try Sdk.updateSource(b.allocator, rootSource.*, src); |
65 |
| - errdefer b.allocator.free(fullSource); |
| 10 | + const fsys_default = linkage == .dynamic and switch (target.result.os.tag) { |
| 11 | + .linux, .windows, .macos => true, |
| 12 | + else => false, |
| 13 | + }; |
66 | 14 |
|
67 |
| - b.allocator.free(rootSource.*); |
68 |
| - rootSource.* = fullSource; |
69 |
| -} |
| 15 | + const fsys_cairo = b.systemIntegrationOption("cairo", .{ |
| 16 | + .default = fsys_default, |
| 17 | + }); |
70 | 18 |
|
71 |
| -pub fn build(b: *std.Build) !void { |
72 |
| - const target = b.standardTargetOptions(.{}); |
73 |
| - const optimize = b.standardOptimizeOption(.{}); |
74 |
| - const no_docs = b.option(bool, "no-docs", "skip installing documentation") orelse false; |
75 |
| - const no_importer = b.option(bool, "no-importer", "disables the import system (not recommended)") orelse false; |
76 |
| - const display_backend = b.option(DisplayBackendType, "display-backend", "The display backend to use for the example") orelse .headless; |
77 |
| - const platform_backend = b.option(PlatformBackendType, "platform-backend", "The display backend to use for the example") orelse .std; |
78 |
| - const scene_backend = b.option(SceneBackendType, "scene-backend", "The scene backend to use for the example") orelse .headless; |
| 19 | + const fsys_wayland = b.systemIntegrationOption("wayland", .{ |
| 20 | + .default = fsys_default, |
| 21 | + }); |
79 | 22 |
|
80 |
| - const vizops = b.dependency("vizops", .{ |
| 23 | + const zigimg = b.dependency("zigimg", .{ |
81 | 24 | .target = target,
|
82 | 25 | .optimize = optimize,
|
83 | 26 | });
|
84 | 27 |
|
85 |
| - const metaplus = b.dependency("metaplus", .{ |
| 28 | + const z2d = b.dependency("z2d", .{ |
86 | 29 | .target = target,
|
87 | 30 | .optimize = optimize,
|
88 | 31 | });
|
89 | 32 |
|
90 |
| - const anyplus = b.dependency("any+", .{ |
| 33 | + const module = b.addModule("phantom", .{ |
| 34 | + .root_source_file = b.path("src/phantom.zig"), |
91 | 35 | .target = target,
|
92 | 36 | .optimize = optimize,
|
| 37 | + .imports = &.{ |
| 38 | + .{ |
| 39 | + .name = "zigimg", |
| 40 | + .module = zigimg.module("zigimg"), |
| 41 | + }, |
| 42 | + .{ |
| 43 | + .name = "z2d", |
| 44 | + .module = z2d.module("z2d"), |
| 45 | + }, |
| 46 | + }, |
93 | 47 | });
|
94 | 48 |
|
95 |
| - const phantomOptions = b.addOptions(); |
96 |
| - phantomOptions.addOption(bool, "no_importer", no_importer); |
97 |
| - |
98 |
| - var phantomDeps = std.ArrayList(std.Build.Module.Import).init(b.allocator); |
99 |
| - errdefer phantomDeps.deinit(); |
100 |
| - |
101 |
| - try phantomDeps.append(.{ |
102 |
| - .name = "vizops", |
103 |
| - .module = vizops.module("vizops"), |
104 |
| - }); |
105 |
| - |
106 |
| - try phantomDeps.append(.{ |
107 |
| - .name = "meta+", |
108 |
| - .module = metaplus.module("meta+"), |
109 |
| - }); |
110 |
| - |
111 |
| - try phantomDeps.append(.{ |
112 |
| - .name = "any+", |
113 |
| - .module = anyplus.module("any+"), |
114 |
| - }); |
115 |
| - |
116 |
| - try phantomDeps.append(.{ |
117 |
| - .name = "phantom.options", |
118 |
| - .module = phantomOptions.createModule(), |
119 |
| - }); |
120 |
| - |
121 |
| - const phantomSource = b.addWriteFiles(); |
122 |
| - |
123 |
| - var fileOverrides = std.StringHashMap([]const u8).init(b.allocator); |
124 |
| - defer fileOverrides.deinit(); |
125 |
| - |
126 |
| - var rootSource = try Sdk.readAll(b.allocator, b.pathFromRoot("src/phantom.zig")); |
127 |
| - defer b.allocator.free(rootSource); |
| 49 | + const options = b.addOptions(); |
| 50 | + options.addOption(bool, "cairo", fsys_cairo); |
| 51 | + options.addOption(bool, "wayland", fsys_wayland); |
128 | 52 |
|
129 |
| - if (!no_importer) { |
130 |
| - inline for (Sdk.availableDepenencies) |dep| { |
131 |
| - const pkg = @field(@import("root").dependencies.packages, dep[1]); |
132 |
| - const pkgdep = b.dependencyInner(dep[0], pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg.deps, .{ |
133 |
| - .target = target, |
134 |
| - .optimize = optimize, |
135 |
| - .@"no-importer" = true, |
136 |
| - }); |
137 |
| - |
138 |
| - const depSourceRootPath = b.pathJoin(&.{ pkg.build_root, "src" }); |
139 |
| - try addSourceFiles(b, &fileOverrides, &rootSource, phantomSource, depSourceRootPath); |
140 |
| - |
141 |
| - var iter = pkgdep.module(dep[0]).import_table.iterator(); |
142 |
| - while (iter.next()) |entry| { |
143 |
| - var alreadyExists = false; |
144 |
| - for (phantomDeps.items) |i| { |
145 |
| - if (std.mem.eql(u8, i.name, entry.key_ptr.*)) { |
146 |
| - alreadyExists = true; |
147 |
| - break; |
148 |
| - } |
149 |
| - } |
| 53 | + if (fsys_cairo) { |
| 54 | + module.linkSystemLibrary("cairo", .{ |
| 55 | + .needed = true, |
| 56 | + .preferred_link_mode = linkage orelse .dynamic, |
| 57 | + }); |
150 | 58 |
|
151 |
| - if (!alreadyExists or !std.mem.eql(u8, entry.key_ptr.*, "phantom")) { |
152 |
| - try phantomDeps.append(.{ |
153 |
| - .name = entry.key_ptr.*, |
154 |
| - .module = entry.value_ptr.*, |
155 |
| - }); |
156 |
| - } |
157 |
| - } |
158 |
| - } |
| 59 | + module.link_libc = true; |
159 | 60 | }
|
160 | 61 |
|
161 |
| - if (b.option([]const u8, "import-module", "inject a module to be imported")) |importModuleString| { |
162 |
| - const modulePathLen = std.mem.indexOf(u8, importModuleString, ":") orelse importModuleString.len; |
163 |
| - const modulePath = importModuleString[0..modulePathLen]; |
| 62 | + if (fsys_wayland) { |
| 63 | + const scanner = WaylandScanner.create(b, .{}); |
164 | 64 |
|
165 |
| - try addSourceFiles(b, &fileOverrides, &rootSource, phantomSource, modulePath); |
| 65 | + scanner.generate("wl_compositor", 1); |
| 66 | + scanner.generate("wl_output", 1); |
| 67 | + scanner.generate("wl_shm", 1); |
166 | 68 |
|
167 |
| - if (modulePathLen < importModuleString.len) { |
168 |
| - const imports = try Sdk.ModuleImport.decode(b.allocator, importModuleString[(modulePathLen + 1)..]); |
169 |
| - defer imports.deinit(); |
| 69 | + const wayland = b.createModule(.{ .root_source_file = scanner.result }); |
170 | 70 |
|
171 |
| - for (imports.value) |dep| { |
172 |
| - var alreadyExists = false; |
173 |
| - for (phantomDeps.items) |i| { |
174 |
| - if (std.mem.eql(u8, i.name, dep.name)) { |
175 |
| - alreadyExists = true; |
176 |
| - break; |
177 |
| - } |
| 71 | + module.addImport("wayland", wayland); |
178 | 72 |
|
179 |
| - if (!alreadyExists or !std.mem.eql(u8, dep.name, "phantom")) { |
180 |
| - try phantomDeps.append(.{ |
181 |
| - .name = dep.name, |
182 |
| - .module = try dep.createModule(b, target, optimize), |
183 |
| - }); |
184 |
| - } |
185 |
| - } |
186 |
| - } |
187 |
| - } |
188 |
| - } |
189 |
| - |
190 |
| - var phantomSourceRoot = try std.fs.openDirAbsolute(b.pathFromRoot("src/phantom"), .{ .iterate = true }); |
191 |
| - defer phantomSourceRoot.close(); |
192 |
| - |
193 |
| - var walker = try phantomSourceRoot.walk(b.allocator); |
194 |
| - defer walker.deinit(); |
195 |
| - |
196 |
| - while (try walker.next()) |entry| { |
197 |
| - if (entry.kind == .directory) continue; |
| 73 | + module.linkSystemLibrary("wayland-client", .{ |
| 74 | + .needed = true, |
| 75 | + .preferred_link_mode = linkage orelse .dynamic, |
| 76 | + }); |
198 | 77 |
|
199 |
| - const entryPath = b.pathJoin(&.{ "phantom", entry.path }); |
| 78 | + module.linkSystemLibrary("wayland-server", .{ |
| 79 | + .needed = true, |
| 80 | + .preferred_link_mode = linkage orelse .dynamic, |
| 81 | + }); |
200 | 82 |
|
201 |
| - if (fileOverrides.get(entry.path)) |source| { |
202 |
| - _ = phantomSource.add(entryPath, source); |
203 |
| - } else { |
204 |
| - _ = phantomSource.addCopyFile(.{ |
205 |
| - .path = b.pathFromRoot(b.pathJoin(&.{ "src/phantom", entry.path })), |
206 |
| - }, entryPath); |
207 |
| - } |
| 83 | + module.link_libc = true; |
208 | 84 | }
|
209 | 85 |
|
210 |
| - const phantom = b.addModule("phantom", .{ |
211 |
| - .root_source_file = phantomSource.add("phantom.zig", rootSource), |
212 |
| - .imports = phantomDeps.items, |
213 |
| - }); |
214 |
| - |
215 |
| - const step_test = b.step("test", "Run all unit tests"); |
| 86 | + module.addOptions("options", options); |
216 | 87 |
|
217 |
| - const unit_tests = b.addTest(.{ |
218 |
| - .root_source_file = phantom.root_source_file.?, |
219 |
| - .target = target, |
220 |
| - .optimize = optimize, |
| 88 | + const autodoc_test = b.addObject(.{ |
| 89 | + .name = "phantom", |
| 90 | + .root_module = module, |
221 | 91 | });
|
222 | 92 |
|
223 |
| - for (phantomDeps.items) |dep| { |
224 |
| - unit_tests.root_module.addImport(dep.name, dep.module); |
225 |
| - } |
226 |
| - |
227 |
| - const run_unit_tests = b.addRunArtifact(unit_tests); |
228 |
| - step_test.dependOn(&run_unit_tests.step); |
229 |
| - b.installArtifact(unit_tests); |
230 |
| - |
231 |
| - const exe_options = b.addOptions(); |
232 |
| - exe_options.addOption(DisplayBackendType, "display_backend", display_backend); |
233 |
| - exe_options.addOption(PlatformBackendType, "platform_backend", platform_backend); |
234 |
| - exe_options.addOption(SceneBackendType, "scene_backend", scene_backend); |
235 |
| - |
236 |
| - const sdk = try Sdk.get(b, platform_backend, phantom); |
237 |
| - defer sdk.deinit(); |
238 |
| - |
239 |
| - const pkg_example = sdk.addPackage(.{ |
240 |
| - .id = "dev.phantomui.example", |
241 |
| - .name = "example", |
242 |
| - .root_module = .{ |
243 |
| - .root_source_file = .{ |
244 |
| - .path = b.pathFromRoot("src/example.zig"), |
245 |
| - }, |
246 |
| - .target = target, |
247 |
| - .optimize = optimize, |
248 |
| - }, |
249 |
| - .kind = .application, |
250 |
| - .version = .{ |
251 |
| - .major = 0, |
252 |
| - .minor = 1, |
253 |
| - .patch = 0, |
254 |
| - }, |
| 93 | + const install_docs = b.addInstallDirectory(.{ |
| 94 | + .source_dir = autodoc_test.getEmittedDocs(), |
| 95 | + .install_dir = .prefix, |
| 96 | + .install_subdir = "doc/phantom", |
255 | 97 | });
|
256 | 98 |
|
257 |
| - pkg_example.root_module.addImport("vizops", vizops.module("vizops")); |
258 |
| - pkg_example.root_module.addImport("options", exe_options.createModule()); |
| 99 | + b.getInstallStep().dependOn(&install_docs.step); |
259 | 100 |
|
260 |
| - sdk.installPackage(pkg_example); |
| 101 | + const step_test = b.step("test", "Run unit tests"); |
261 | 102 |
|
262 |
| - if (!no_docs) { |
263 |
| - const docs = b.addInstallDirectory(.{ |
264 |
| - .source_dir = unit_tests.getEmittedDocs(), |
265 |
| - .install_dir = .prefix, |
266 |
| - .install_subdir = "docs", |
267 |
| - }); |
| 103 | + const test_exe = b.addTest(.{ |
| 104 | + .target = target, |
| 105 | + .optimize = optimize, |
| 106 | + .root_module = module, |
| 107 | + }); |
268 | 108 |
|
269 |
| - b.getInstallStep().dependOn(&docs.step); |
270 |
| - } |
| 109 | + const test_run = b.addRunArtifact(test_exe); |
| 110 | + step_test.dependOn(&test_run.step); |
271 | 111 | }
|
0 commit comments