authorgravatar for galaxyshard.tech@proton.meGalaxyShard <galaxyshard.tech@proton.me> 2024-10-09 01:27:42-04:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-27 09:47:42+01:00
logb5a5260546ddd8953e493f75c5ee12c5a853263b
tree4da4f332b4077ad7d28af72635e6cf5fd60e7c7b
parentfb188c3d18a744cb98fc361aeeb8e8796066868b

std.Build: implement addEmbedPath for adding C #embed search directories


8 files changed, 67 insertions(+), 1 deletions(-)

lib/compiler/build_runner.zig+1
...@@ -1496,6 +1496,7 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void {...@@ -1496,6 +1496,7 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void {
1496 .path_after,1496 .path_after,
1497 .framework_path,1497 .framework_path,
1498 .framework_path_system,1498 .framework_path_system,
1499 .embed_path,
1499 => |lp| lp.addStepDependencies(step),1500 => |lp| lp.addStepDependencies(step),
15001501
1501 .other_step => |other| {1502 .other_step => |other| {
lib/std/Build/Module.zig+9
...@@ -164,6 +164,7 @@ pub const IncludeDir = union(enum) {...@@ -164,6 +164,7 @@ pub const IncludeDir = union(enum) {
164 framework_path_system: LazyPath,164 framework_path_system: LazyPath,
165 other_step: *Step.Compile,165 other_step: *Step.Compile,
166 config_header_step: *Step.ConfigHeader,166 config_header_step: *Step.ConfigHeader,
167 embed_path: LazyPath,
167168
168 pub fn appendZigProcessFlags(169 pub fn appendZigProcessFlags(
169 include_dir: IncludeDir,170 include_dir: IncludeDir,
...@@ -200,6 +201,9 @@ pub const IncludeDir = union(enum) {...@@ -200,6 +201,9 @@ pub const IncludeDir = union(enum) {
200 const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];201 const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];
201 try zig_args.appendSlice(&.{ "-I", header_dir_path });202 try zig_args.appendSlice(&.{ "-I", header_dir_path });
202 },203 },
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 },
203 }207 }
204 }208 }
205};209};
...@@ -511,6 +515,11 @@ pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {...@@ -511,6 +515,11 @@ pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {
511 @panic("OOM");515 @panic("OOM");
512}516}
513517
518pub 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
514pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {523pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {
515 const b = m.owner;524 const b = m.owner;
516 m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");525 m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");
lib/std/Build/Step/Compile.zig+4
...@@ -943,6 +943,10 @@ pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) voi...@@ -943,6 +943,10 @@ pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) voi
943 compile.root_module.addConfigHeader(config_header);943 compile.root_module.addConfigHeader(config_header);
944}944}
945945
946pub fn addEmbedPath(compile: *Compile, lazy_path: LazyPath) void {
947 compile.root_module.addEmbedPath(lazy_path);
948}
949
946pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void {950pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void {
947 compile.root_module.addLibraryPath(directory_path);951 compile.root_module.addLibraryPath(directory_path);
948}952}
src/main.zig+9-1
...@@ -541,6 +541,7 @@ const usage_build_generic =...@@ -541,6 +541,7 @@ const usage_build_generic =
541 \\ -idirafter [dir] Add directory to AFTER include search path541 \\ -idirafter [dir] Add directory to AFTER include search path
542 \\ -isystem [dir] Add directory to SYSTEM include search path542 \\ -isystem [dir] Add directory to SYSTEM include search path
543 \\ -I[dir] Add directory to include search path543 \\ -I[dir] Add directory to include search path
544 \\ --embed-dir=[dir] Add directory to embed search path
544 \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted)545 \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted)
545 \\ -cflags [flags] -- Set extra flags for the next positional C source files546 \\ -cflags [flags] -- Set extra flags for the next positional C source files
546 \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files547 \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files
...@@ -1287,6 +1288,8 @@ fn buildOutputType(...@@ -1287,6 +1288,8 @@ fn buildOutputType(
1287 try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });1288 try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });
1288 } else if (mem.eql(u8, arg, "-I")) {1289 } else if (mem.eql(u8, arg, "-I")) {
1289 try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false);1290 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);
1290 } else if (mem.eql(u8, arg, "-isystem")) {1293 } else if (mem.eql(u8, arg, "-isystem")) {
1291 try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);1294 try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);
1292 } else if (mem.eql(u8, arg, "-iwithsysroot")) {1295 } else if (mem.eql(u8, arg, "-iwithsysroot")) {
...@@ -6974,13 +6977,17 @@ const ClangSearchSanitizer = struct {...@@ -6974,13 +6977,17 @@ const ClangSearchSanitizer = struct {
6974 m.iframeworkwithsysroot = true;6977 m.iframeworkwithsysroot = true;
6975 if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });6978 if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
6976 },6979 },
6980 .embed_dir => {
6981 if (m.embed_dir) return;
6982 m.embed_dir = true;
6983 },
6977 }6984 }
6978 try argv.ensureUnusedCapacity(ally, 2);6985 try argv.ensureUnusedCapacity(ally, 2);
6979 argv.appendAssumeCapacity(arg);6986 argv.appendAssumeCapacity(arg);
6980 if (!joined) argv.appendAssumeCapacity(dir);6987 if (!joined) argv.appendAssumeCapacity(dir);
6981 }6988 }
69826989
6983 const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot };6990 const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot, embed_dir };
69846991
6985 const Membership = packed struct {6992 const Membership = packed struct {
6986 I: bool = false,6993 I: bool = false,
...@@ -6989,6 +6996,7 @@ const ClangSearchSanitizer = struct {...@@ -6989,6 +6996,7 @@ const ClangSearchSanitizer = struct {
6989 idirafter: bool = false,6996 idirafter: bool = false,
6990 iframework: bool = false,6997 iframework: bool = false,
6991 iframeworkwithsysroot: bool = false,6998 iframeworkwithsysroot: bool = false,
6999 embed_dir: bool = false,
6992 };7000 };
6993};7001};
69947002
test/standalone/build.zig.zon+3
...@@ -126,6 +126,9 @@...@@ -126,6 +126,9 @@
126 .c_compiler = .{126 .c_compiler = .{
127 .path = "c_compiler",127 .path = "c_compiler",
128 },128 },
129 .c_embed_path = .{
130 .path = "c_embed_path",
131 },
129 .pie = .{132 .pie = .{
130 .path = "pie",133 .path = "pie",
131 },134 },
test/standalone/c_embed_path/build.zig created+25
...@@ -0,0 +1,25 @@
1const std = @import("std");
2
3pub 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}
test/standalone/c_embed_path/data/foo.data created+1
...@@ -0,0 +1 @@
1This text is the contents of foo.data
\ No newline at end of file
test/standalone/c_embed_path/test.c created+15
...@@ -0,0 +1,15 @@
1
2#include <stdlib.h>
3#include <string.h>
4int 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}