build.zig: Fix various issues around -Dconfig
This commit is contained in:
parent
dc5e6e0ad0
commit
d53cf3f6b4
|
|
@ -86,12 +86,34 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
||||
});
|
||||
if (options.config.len > 0) {
|
||||
const file = b.pathJoin(&.{ srcDir(b), "config.h" });
|
||||
const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize));
|
||||
defer b.allocator.free(content);
|
||||
// Note: Both this and the commented out code immediately below should behave the same.
|
||||
// `@embedFile` probably captures the intent better, but has the unfortunate consequence of
|
||||
// bloating up the size of a binary. The performance of a build system probably isn't vital.
|
||||
// It should also be possible to get the list of configs needed from `src/config.h` at
|
||||
// comptime such that this cost can be ignored AND simplify the logic.
|
||||
const content = @embedFile("config.h");
|
||||
// Note: Usage of `std.build.pathFromRoot` is disadvised according to its documentation
|
||||
//const file = b.pathFromRoot(b.pathJoin(&.{ srcDir(b), "config.h" }));
|
||||
//const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize));
|
||||
|
||||
// Sets a flag indiciating the use of a custom `config.h`
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
|
||||
// Splits a space-separated list of config flags into multiple flags
|
||||
//
|
||||
// Note: This means certain flags like `-x c++` won't be processed properly.
|
||||
// `-xc++` or similar should be used when possible
|
||||
var config_iter = std.mem.tokenizeScalar(u8, options.config, ' ');
|
||||
|
||||
// Append config flags supplied by user to compile flags
|
||||
while (config_iter.next()) |config_flag|
|
||||
try raylib_flags_arr.append(b.allocator, config_flag);
|
||||
|
||||
// Apply all relevant configs from `src/config.h` *except* the user-specified ones
|
||||
var lines = std.mem.tokenizeScalar(u8, content, '\n');
|
||||
outer: while (lines.next()) |line| {
|
||||
config_iter.reset();
|
||||
|
||||
var lines = std.mem.splitScalar(u8, content, '\n');
|
||||
while (lines.next()) |line| {
|
||||
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||
if (std.mem.startsWith(u8, line, "#if")) continue;
|
||||
|
|
@ -100,19 +122,23 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
||||
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
||||
flag = try std.fmt.allocPrint(b.allocator, "-D{s}", .{flag}); // Prepend with -D
|
||||
flag = b.fmt("-D{s}", .{flag}); // Prepend with -D
|
||||
|
||||
// If user specifies the flag skip it
|
||||
if (std.mem.containsAtLeast(u8, options.config, 1, flag)) continue;
|
||||
// If a user already specified the flag, skip it
|
||||
//
|
||||
// Note: Currently using a suboptimal `O(m*n)` time algorithm where:
|
||||
// `m` corresponds to the number of lines in `src/config.h`
|
||||
// `n` corresponds to the number of user-specified flags
|
||||
while (config_iter.next()) |config_flag| {
|
||||
// For a user-specified flag to match, it must share the same prefix and have the
|
||||
// same length or be followed by an equals sign
|
||||
if (!std.mem.startsWith(u8, config_flag, flag)) continue;
|
||||
if (config_flag.len == flag.len or config_flag[flag.len] == '=') continue :outer;
|
||||
}
|
||||
|
||||
// Append default value from config.h to compile flags
|
||||
try raylib_flags_arr.append(b.allocator, flag);
|
||||
}
|
||||
|
||||
// Append config flags supplied by user to compile flags
|
||||
try raylib_flags_arr.append(b.allocator, options.config);
|
||||
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
}
|
||||
|
||||
if (options.shared) {
|
||||
|
|
@ -319,10 +345,28 @@ pub const Options = struct {
|
|||
shared: bool = false,
|
||||
linux_display_backend: LinuxDisplayBackend = .Both,
|
||||
opengl_version: OpenglVersion = .auto,
|
||||
/// config should be a list of cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
|
||||
/// config should be a list of space-separated cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
|
||||
config: []const u8 = &.{},
|
||||
|
||||
raygui_dependency_name: []const u8 = "raygui",
|
||||
|
||||
const defaults = Options{};
|
||||
|
||||
fn getOptions(b: *std.Build) Options {
|
||||
return .{
|
||||
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
|
||||
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||
.raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui,
|
||||
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
|
||||
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
|
||||
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
||||
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
||||
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
||||
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const OpenglVersion = enum {
|
||||
|
|
@ -371,22 +415,7 @@ pub fn build(b: *std.Build) !void {
|
|||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const defaults = Options{};
|
||||
const options = Options{
|
||||
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
|
||||
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||
.raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui,
|
||||
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
|
||||
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
|
||||
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
||||
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
||||
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
||||
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
|
||||
};
|
||||
|
||||
const lib = try compileRaylib(b, target, optimize, options);
|
||||
const lib = try compileRaylib(b, target, optimize, Options.getOptions(b));
|
||||
|
||||
lib.installHeader(b.path(b.pathJoin(&.{ srcDir(b), "raylib.h" })), "raylib.h");
|
||||
lib.installHeader(b.path(b.pathJoin(&.{ srcDir(b), "raymath.h" })), "raymath.h");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user