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

This commit is contained in:
GalaxyShard 2024-10-09 01:27:42 -04:00 committed by Alex Rønne Petersen
parent fb188c3d18
commit b5a5260546
8 changed files with 67 additions and 1 deletions

View file

@ -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| {

View file

@ -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");

View file

@ -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);
}

View file

@ -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,
};
};

View file

@ -126,6 +126,9 @@
.c_compiler = .{
.path = "c_compiler",
},
.c_embed_path = .{
.path = "c_embed_path",
},
.pie = .{
.path = "pie",
},

View file

@ -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);
}

View file

@ -0,0 +1 @@
This text is the contents of foo.data

View file

@ -0,0 +1,15 @@
#include <stdlib.h>
#include <string.h>
int main(void) {
// Raw bytes; not a C string
const char data[] = {
#embed <foo.data>
};
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;
}
}