From b5a5260546ddd8953e493f75c5ee12c5a853263b Mon Sep 17 00:00:00 2001 From: GalaxyShard Date: Wed, 9 Oct 2024 01:27:42 -0400 Subject: [PATCH] std.Build: implement addEmbedPath for adding C #embed search directories --- lib/compiler/build_runner.zig | 1 + lib/std/Build/Module.zig | 9 ++++++++ lib/std/Build/Step/Compile.zig | 4 ++++ src/main.zig | 10 ++++++++- test/standalone/build.zig.zon | 3 +++ test/standalone/c_embed_path/build.zig | 25 ++++++++++++++++++++++ test/standalone/c_embed_path/data/foo.data | 1 + test/standalone/c_embed_path/test.c | 15 +++++++++++++ 8 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/standalone/c_embed_path/build.zig create mode 100644 test/standalone/c_embed_path/data/foo.data create mode 100644 test/standalone/c_embed_path/test.c diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index aacd26b82d..6c68911e9b 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -1496,6 +1496,7 @@ fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { .path_after, .framework_path, .framework_path_system, + .embed_path, => |lp| lp.addStepDependencies(step), .other_step => |other| { diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig index f299946731..0bc77b0741 100644 --- a/lib/std/Build/Module.zig +++ b/lib/std/Build/Module.zig @@ -164,6 +164,7 @@ pub const IncludeDir = union(enum) { framework_path_system: LazyPath, other_step: *Step.Compile, config_header_step: *Step.ConfigHeader, + embed_path: LazyPath, pub fn appendZigProcessFlags( include_dir: IncludeDir, @@ -200,6 +201,9 @@ pub const IncludeDir = union(enum) { const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len]; try zig_args.appendSlice(&.{ "-I", header_dir_path }); }, + .embed_path => |embed_path| { + try zig_args.append(try std.mem.concat(b.allocator, u8, &.{ "--embed-dir=", embed_path.getPath2(b, asking_step) })); + }, } } }; @@ -511,6 +515,11 @@ pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void { @panic("OOM"); } +pub fn addEmbedPath(m: *Module, lazy_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .embed_path = lazy_path.dupe(b) }) catch @panic("OOM"); +} + pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void { const b = m.owner; m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM"); diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index c401a840ba..cbcb71304f 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -943,6 +943,10 @@ pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) voi compile.root_module.addConfigHeader(config_header); } +pub fn addEmbedPath(compile: *Compile, lazy_path: LazyPath) void { + compile.root_module.addEmbedPath(lazy_path); +} + pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void { compile.root_module.addLibraryPath(directory_path); } diff --git a/src/main.zig b/src/main.zig index 2687546e41..a377b38494 100644 --- a/src/main.zig +++ b/src/main.zig @@ -541,6 +541,7 @@ const usage_build_generic = \\ -idirafter [dir] Add directory to AFTER include search path \\ -isystem [dir] Add directory to SYSTEM include search path \\ -I[dir] Add directory to include search path + \\ --embed-dir=[dir] Add directory to embed search path \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted) \\ -cflags [flags] -- Set extra flags for the next positional C source files \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files @@ -1287,6 +1288,8 @@ fn buildOutputType( try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() }); } else if (mem.eql(u8, arg, "-I")) { try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false); + } else if (mem.startsWith(u8, arg, "--embed-dir=")) { + try cssan.addIncludePath(arena, &cc_argv, .embed_dir, arg, arg["--embed-dir=".len..], true); } else if (mem.eql(u8, arg, "-isystem")) { try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false); } else if (mem.eql(u8, arg, "-iwithsysroot")) { @@ -6974,13 +6977,17 @@ const ClangSearchSanitizer = struct { m.iframeworkwithsysroot = true; if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" }); }, + .embed_dir => { + if (m.embed_dir) return; + m.embed_dir = true; + }, } try argv.ensureUnusedCapacity(ally, 2); argv.appendAssumeCapacity(arg); if (!joined) argv.appendAssumeCapacity(dir); } - const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot }; + const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot, embed_dir }; const Membership = packed struct { I: bool = false, @@ -6989,6 +6996,7 @@ const ClangSearchSanitizer = struct { idirafter: bool = false, iframework: bool = false, iframeworkwithsysroot: bool = false, + embed_dir: bool = false, }; }; diff --git a/test/standalone/build.zig.zon b/test/standalone/build.zig.zon index db1c7125a7..5033a38ea4 100644 --- a/test/standalone/build.zig.zon +++ b/test/standalone/build.zig.zon @@ -126,6 +126,9 @@ .c_compiler = .{ .path = "c_compiler", }, + .c_embed_path = .{ + .path = "c_embed_path", + }, .pie = .{ .path = "pie", }, diff --git a/test/standalone/c_embed_path/build.zig b/test/standalone/c_embed_path/build.zig new file mode 100644 index 0000000000..0247c99a45 --- /dev/null +++ b/test/standalone/c_embed_path/build.zig @@ -0,0 +1,25 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + + const optimize: std.builtin.OptimizeMode = .Debug; + + const exe = b.addExecutable(.{ + .name = "test", + .target = b.graph.host, + .optimize = optimize, + }); + exe.addCSourceFile(.{ + .file = b.path("test.c"), + .flags = &.{"-std=c23"}, + }); + exe.linkLibC(); + exe.addEmbedPath(b.path("data")); + + const run_c_cmd = b.addRunArtifact(exe); + run_c_cmd.expectExitCode(0); + run_c_cmd.skip_foreign_checks = true; + test_step.dependOn(&run_c_cmd.step); +} diff --git a/test/standalone/c_embed_path/data/foo.data b/test/standalone/c_embed_path/data/foo.data new file mode 100644 index 0000000000..54794fe957 --- /dev/null +++ b/test/standalone/c_embed_path/data/foo.data @@ -0,0 +1 @@ +This text is the contents of foo.data \ No newline at end of file diff --git a/test/standalone/c_embed_path/test.c b/test/standalone/c_embed_path/test.c new file mode 100644 index 0000000000..b2dc2f6210 --- /dev/null +++ b/test/standalone/c_embed_path/test.c @@ -0,0 +1,15 @@ + +#include +#include +int main(void) { + // Raw bytes; not a C string + const char data[] = { +#embed + }; + const char *expected = "This text is the contents of foo.data"; + if (sizeof data == strlen(expected) && memcmp(data, expected, sizeof data) == 0) { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +}