1
1
const std = @import ("std" );
2
+ const EmbedFile = @This ();
2
3
3
- pub const EmbedFile = @import ("src/EmbedFile.zig" );
4
+ wf : * std.Build.Step.WriteFile ,
5
+ contents : std .ArrayListUnmanaged (u8 ),
6
+ module : * std.Build.Module ,
7
+ named_wfs : std .ArrayListUnmanaged (* std .Build .Step .WriteFile ),
8
+
9
+ /// creates a new EmbedFile step
10
+ pub fn create (owner : * std.Build ) * EmbedFile {
11
+ const embed_file = owner .allocator .create (EmbedFile ) catch @panic ("OOM" );
12
+ embed_file .* = .{
13
+ .wf = std .Build .Step .WriteFile .create (owner ),
14
+ .module = owner .createModule (.{}),
15
+ .contents = .{},
16
+ .named_wfs = .{},
17
+ };
18
+ const canonicalize = owner .addSystemCommand (&.{ owner .graph .zig_exe , "fmt" , "--stdin" });
19
+ canonicalize .setStdIn (.{ .lazy_path = embed_file .wf .getDirectory ().path (owner , "module.zig" ) });
20
+ const module_file = canonicalize .captureStdOut ();
21
+ embed_file .module .root_source_file = module_file ;
22
+ embed_file .contents .appendSlice (owner .allocator ,
23
+ \\//! This file is automatically generated by EmbedFile.zig!
24
+ \\//! EmbedFile.zig is NOT an official part of the Zig build system;
25
+ \\//! please report any issues at https://github.com/robbielyman/EmbedFile.zig
26
+ \\
27
+ \\
28
+ ) catch @panic ("OOM" );
29
+ embed_file .updateContents ();
30
+ return embed_file ;
31
+ }
4
32
5
33
pub fn addEmbedFiles (b : * std.Build ) * EmbedFile {
6
34
return EmbedFile .create (b );
@@ -9,47 +37,138 @@ pub fn addEmbedFiles(b: *std.Build) *EmbedFile {
9
37
pub fn addEmbedFile (b : * std.Build , name : []const u8 , bytes : []const u8 , alignment : ? u29 ) * EmbedFile {
10
38
const ret = EmbedFile .create (b );
11
39
ret .add (name , bytes , alignment );
12
- ret .step .name = b .fmt ("EmbedFile {s}" , .{name });
13
40
return ret ;
14
41
}
15
42
16
- pub fn build (b : * std.Build ) void {
17
- const target = b .standardTargetOptions (.{});
18
- const optimize = b .standardOptimizeOption (.{});
19
- _ = b .addModule ("EmbedFile" , .{
20
- .root_source_file = b .path ("src/EmbedFile.zig" ),
21
- .target = target ,
22
- .optimize = optimize ,
23
- });
24
-
25
- const test_step = b .step ("test" , "test EmbedFile" );
26
- test_step .dependOn (tests (b ));
43
+ fn updateContents (embed_file : * EmbedFile ) void {
44
+ if (embed_file .wf .files .items .len == 0 ) {
45
+ _ = embed_file .wf .add ("module.zig" , embed_file .contents .items );
46
+ return ;
47
+ }
48
+ embed_file .wf .files .items [0 ].contents = .{ .bytes = embed_file .contents .items };
27
49
}
28
50
29
- fn tests (b : * std.Build ) * std.Build.Step {
30
- const test_module = b .addTest (.{
31
- .root_source_file = b .path ("src/test.zig" ),
51
+ const Kind = enum { file , directory };
52
+
53
+ fn addImport (
54
+ embed_file : * EmbedFile ,
55
+ b : * std.Build ,
56
+ write_file : * std.Build.Step.WriteFile ,
57
+ name : []const u8 ,
58
+ kind : Kind ,
59
+ alignment : ? u29 ,
60
+ ) void {
61
+ const this_dep = b .dependencyFromBuildZig (@This (), .{
62
+ .target = b .graph .host ,
63
+ .optimize = .Debug ,
32
64
});
65
+ const exe = this_dep .artifact ("embed-file" );
66
+ const run = b .addRunArtifact (exe );
67
+ switch (kind ) {
68
+ .file = > run .addFileArg (write_file .getDirectory ().path (b , name )),
69
+ .directory = > run .addDirectoryArg (write_file .getDirectory ().path (b , name )),
70
+ }
71
+ if (alignment ) | a | run .addArg (b .fmt ("{d}" , .{a }));
72
+ run .step .dependOn (& write_file .step );
73
+ const input = run .captureStdOut ();
74
+ const fmt = b .addSystemCommand (&.{ b .graph .zig_exe , "fmt" , "--stdin" });
75
+ fmt .setStdIn (.{ .lazy_path = input });
76
+ const output = fmt .captureStdOut ();
77
+ const copy_file = b .addWriteFiles ();
78
+ const module_file = copy_file .addCopyFile (output , "module.zig" );
79
+ _ = copy_file .addCopyDirectory (write_file .getDirectory (), "" , .{});
80
+ for (embed_file .named_wfs .items ) | wf | {
81
+ _ = wf .addCopyDirectory (copy_file .getDirectory (), name , .{});
82
+ }
83
+ const import_module = b .createModule (.{
84
+ .root_source_file = module_file ,
85
+ });
86
+ embed_file .module .addImport (name , import_module );
87
+ switch (kind ) {
88
+ .file = > embed_file .contents .writer (b .allocator ).print (
89
+ \\pub const @"{s}" = @import("{s}").@"{s}";
90
+ \\
91
+ , .{ name , name , name }) catch @panic ("OOM" ),
92
+ .directory = > embed_file .contents .writer (b .allocator ).print (
93
+ \\pub const @"{s}" = @import("{s}");
94
+ \\
95
+ , .{ name , name }) catch @panic ("OOM" ),
96
+ }
97
+ embed_file .updateContents ();
98
+ }
33
99
100
+ /// adds a declaration by name, contents and alignment directly
101
+ pub fn add (embed_file : * EmbedFile , name : []const u8 , bytes : []const u8 , alignment : ? u29 ) void {
102
+ const b = embed_file .module .owner ;
103
+ const write_file = b .addWriteFile (name , bytes );
104
+ embed_file .addImport (b , write_file , name , .file , alignment );
105
+ }
106
+
107
+ /// name is the eventual declaration name to be used,
108
+ /// while source is the path as it exists on the file system
109
+ pub fn addFile (
110
+ embed_file : * EmbedFile ,
111
+ source : std.Build.LazyPath ,
112
+ name : []const u8 ,
113
+ alignment : ? u29 ,
114
+ ) void {
115
+ const b = embed_file .module .owner ;
34
116
const write_file = b .addWriteFiles ();
35
- _ = write_file .add ("a.include" , "a.a" );
36
- _ = write_file .add ("b.include" , "a.b" );
37
- _ = write_file .add ("c" ++ std .fs .path .sep_str ++ "a.include" , "a.c.a" );
38
- _ = write_file .add ("d.exclude" , "a.d" );
117
+ _ = write_file .addCopyFile (source , name );
118
+ embed_file .addImport (b , write_file , name , .file , alignment );
119
+ }
39
120
40
- const second_write_file = b .addWriteFile ("path.txt" , "this is to test addFile" );
121
+ /// name is the eventual declaration name to be used as a namespace,
122
+ /// while source is the path as it exists on the file system
123
+ /// files matching the Directory.Options specification
124
+ /// are made available as declarations namespaced under "name";
125
+ /// the filename (minus any extension) is used as the declaration name
126
+ /// alignment, if non-null, is used as the alignment for all sub-declarations
127
+ pub fn addDirectory (
128
+ embed_file : * EmbedFile ,
129
+ source : std.Build.LazyPath ,
130
+ options : std.Build.Step.WriteFile.Directory.Options ,
131
+ name : []const u8 ,
132
+ alignment : ? u29 ,
133
+ ) void {
134
+ const b = embed_file .module .owner ;
135
+ const write_file = b .addWriteFiles ();
136
+ _ = write_file .addCopyDirectory (source , name , options );
137
+ embed_file .addImport (b , write_file , name , .directory , alignment );
138
+ }
41
139
42
- const embed_file = addEmbedFile (b , "name with spaces" , "names can have spaces" , null );
43
- embed_file .addDirectory (write_file .getDirectory (), "" , .{ .exclude_extensions = &.{".exclude" }, .include_extensions = &.{".include" } }, "a" , 16 );
44
- embed_file .addFile (second_write_file .getDirectory (), "path.txt" , "other" , null );
140
+ /// returns a `LazyPath` representing the Zig source file generated from this `EmbedFile`
141
+ pub fn getSource (embed_file : * EmbedFile ) std.Build.LazyPath {
142
+ return embed_file .module .root_source_file .? ;
143
+ }
45
144
46
- embed_file .step .dependOn (& write_file .step );
145
+ /// adds a named WriteFile step that collects all of this EmbedFile's dependencies to write out
146
+ pub fn writeSources (embed_file : * EmbedFile , name : []const u8 ) * std.Build.Step.WriteFile {
147
+ const owner = embed_file .module .owner ;
148
+ const gpa = owner .allocator ;
149
+ const new_wf = owner .addNamedWriteFiles (name );
150
+ // collect all currently existing dependencies
151
+ // addImport will add the rest
152
+ var it = embed_file .module .iterateDependencies (null , false );
153
+ while (it .next ()) | item | if (std .mem .eql (u8 , item .name , "root" )) {
154
+ _ = new_wf .addCopyFile (item .module .root_source_file .? , "module.zig" );
155
+ } else {
156
+ _ = new_wf .addCopyDirectory (item .module .root_source_file .? .dirname (), item .name , .{});
157
+ };
47
158
48
- test_module .root_module .addImport ("assets" , embed_file .createModule ());
159
+ embed_file .named_wfs .append (gpa , new_wf ) catch @panic ("OOM" );
160
+ return new_wf ;
161
+ }
49
162
50
- const install_output_file = b .addInstallFileWithDir (embed_file .getSource (), .{ .custom = "test-output" }, "module.zig" );
163
+ pub fn build (b : * std.Build ) void {
164
+ const target = b .standardTargetOptions (.{});
165
+ const optimize = b .standardOptimizeOption (.{});
51
166
52
- const run_tests = b .addRunArtifact (test_module );
53
- run_tests .step .dependOn (& install_output_file .step );
54
- return & run_tests .step ;
167
+ const exe = b .addExecutable (.{
168
+ .name = "embed-file" ,
169
+ .target = target ,
170
+ .optimize = optimize ,
171
+ .root_source_file = b .path ("src/main.zig" ),
172
+ });
173
+ b .installArtifact (exe );
55
174
}
0 commit comments