Skip to content

Commit b5a5260

Browse files
GalaxyShardalexrp
authored andcommitted
std.Build: implement addEmbedPath for adding C #embed search directories
1 parent fb188c3 commit b5a5260

File tree

8 files changed

+67
-1
lines changed

8 files changed

+67
-1
lines changed

lib/compiler/build_runner.zig

+1
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,7 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void {
14961496
.path_after,
14971497
.framework_path,
14981498
.framework_path_system,
1499+
.embed_path,
14991500
=> |lp| lp.addStepDependencies(step),
15001501

15011502
.other_step => |other| {

lib/std/Build/Module.zig

+9
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pub const IncludeDir = union(enum) {
164164
framework_path_system: LazyPath,
165165
other_step: *Step.Compile,
166166
config_header_step: *Step.ConfigHeader,
167+
embed_path: LazyPath,
167168

168169
pub fn appendZigProcessFlags(
169170
include_dir: IncludeDir,
@@ -200,6 +201,9 @@ pub const IncludeDir = union(enum) {
200201
const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];
201202
try zig_args.appendSlice(&.{ "-I", header_dir_path });
202203
},
204+
.embed_path => |embed_path| {
205+
try zig_args.append(try std.mem.concat(b.allocator, u8, &.{ "--embed-dir=", embed_path.getPath2(b, asking_step) }));
206+
},
203207
}
204208
}
205209
};
@@ -511,6 +515,11 @@ pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {
511515
@panic("OOM");
512516
}
513517

518+
pub fn addEmbedPath(m: *Module, lazy_path: LazyPath) void {
519+
const b = m.owner;
520+
m.include_dirs.append(b.allocator, .{ .embed_path = lazy_path.dupe(b) }) catch @panic("OOM");
521+
}
522+
514523
pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {
515524
const b = m.owner;
516525
m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");

lib/std/Build/Step/Compile.zig

+4
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,10 @@ pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) voi
943943
compile.root_module.addConfigHeader(config_header);
944944
}
945945

946+
pub fn addEmbedPath(compile: *Compile, lazy_path: LazyPath) void {
947+
compile.root_module.addEmbedPath(lazy_path);
948+
}
949+
946950
pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void {
947951
compile.root_module.addLibraryPath(directory_path);
948952
}

src/main.zig

+9-1
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ const usage_build_generic =
541541
\\ -idirafter [dir] Add directory to AFTER include search path
542542
\\ -isystem [dir] Add directory to SYSTEM include search path
543543
\\ -I[dir] Add directory to include search path
544+
\\ --embed-dir=[dir] Add directory to embed search path
544545
\\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted)
545546
\\ -cflags [flags] -- Set extra flags for the next positional C source files
546547
\\ -rcflags [flags] -- Set extra flags for the next positional .rc source files
@@ -1287,6 +1288,8 @@ fn buildOutputType(
12871288
try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });
12881289
} else if (mem.eql(u8, arg, "-I")) {
12891290
try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false);
1291+
} else if (mem.startsWith(u8, arg, "--embed-dir=")) {
1292+
try cssan.addIncludePath(arena, &cc_argv, .embed_dir, arg, arg["--embed-dir=".len..], true);
12901293
} else if (mem.eql(u8, arg, "-isystem")) {
12911294
try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);
12921295
} else if (mem.eql(u8, arg, "-iwithsysroot")) {
@@ -6974,13 +6977,17 @@ const ClangSearchSanitizer = struct {
69746977
m.iframeworkwithsysroot = true;
69756978
if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
69766979
},
6980+
.embed_dir => {
6981+
if (m.embed_dir) return;
6982+
m.embed_dir = true;
6983+
},
69776984
}
69786985
try argv.ensureUnusedCapacity(ally, 2);
69796986
argv.appendAssumeCapacity(arg);
69806987
if (!joined) argv.appendAssumeCapacity(dir);
69816988
}
69826989

6983-
const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot };
6990+
const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot, embed_dir };
69846991

69856992
const Membership = packed struct {
69866993
I: bool = false,
@@ -6989,6 +6996,7 @@ const ClangSearchSanitizer = struct {
69896996
idirafter: bool = false,
69906997
iframework: bool = false,
69916998
iframeworkwithsysroot: bool = false,
6999+
embed_dir: bool = false,
69927000
};
69937001
};
69947002

test/standalone/build.zig.zon

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
.c_compiler = .{
127127
.path = "c_compiler",
128128
},
129+
.c_embed_path = .{
130+
.path = "c_embed_path",
131+
},
129132
.pie = .{
130133
.path = "pie",
131134
},
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const std = @import("std");
2+
3+
pub fn build(b: *std.Build) void {
4+
const test_step = b.step("test", "Test it");
5+
b.default_step = test_step;
6+
7+
const optimize: std.builtin.OptimizeMode = .Debug;
8+
9+
const exe = b.addExecutable(.{
10+
.name = "test",
11+
.target = b.graph.host,
12+
.optimize = optimize,
13+
});
14+
exe.addCSourceFile(.{
15+
.file = b.path("test.c"),
16+
.flags = &.{"-std=c23"},
17+
});
18+
exe.linkLibC();
19+
exe.addEmbedPath(b.path("data"));
20+
21+
const run_c_cmd = b.addRunArtifact(exe);
22+
run_c_cmd.expectExitCode(0);
23+
run_c_cmd.skip_foreign_checks = true;
24+
test_step.dependOn(&run_c_cmd.step);
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This text is the contents of foo.data

test/standalone/c_embed_path/test.c

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
#include <stdlib.h>
3+
#include <string.h>
4+
int main(void) {
5+
// Raw bytes; not a C string
6+
const char data[] = {
7+
#embed <foo.data>
8+
};
9+
const char *expected = "This text is the contents of foo.data";
10+
if (sizeof data == strlen(expected) && memcmp(data, expected, sizeof data) == 0) {
11+
return EXIT_SUCCESS;
12+
} else {
13+
return EXIT_FAILURE;
14+
}
15+
}

0 commit comments

Comments
 (0)