diff --git a/build.zig b/build.zig index 3e64566..b76548a 100644 --- a/build.zig +++ b/build.zig @@ -214,13 +214,13 @@ pub fn build(b: *Build) !void { const ldc = try ldcBuildStep(b, .{ .name = example, .artifact = sokol, - .sources = &.{b.fmt("{s}/src/examples/{s}.d", .{ rootPath(), example })}, - .d_packages = &.{ + .sources = &[_][]const u8{b.fmt("{s}/src/examples/{s}.d", .{ rootPath(), example })}, + .d_packages = &[_][]const u8{ b.dependency("automem", .{}).path("source").getPath(b), b.dependency("ikod_containers", .{}).path("source").getPath(b), }, .betterC = enable_betterC, - .dflags = &.{ + .dflags = &[_][]const u8{ "-w", // warnings as error // more info: ldc2 -preview=help (list all specs) "-preview=all", @@ -236,15 +236,13 @@ pub fn build(b: *Build) !void { // build tests // fixme: not building on Windows libsokol w/ kind test (missing cc [??]) - if (target.result.os.tag != .windows) { - _ = try ldcBuildStep(b, .{ - .name = "test-math", - .kind = .@"test", - .target = b.host, - .sources = &.{b.fmt("{s}/src/handmade/math.d", .{rootPath()})}, - .dflags = &.{}, - }); - } + _ = try ldcBuildStep(b, .{ + .name = "test-math", + .kind = .@"test", + .target = b.host, + .sources = &.{b.fmt("{s}/src/handmade/math.d", .{rootPath()})}, + .dflags = &.{}, + }); } // Use LDC2 (https://github.com/ldc-developers/ldc) to compile the D examples @@ -269,9 +267,8 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { try cmds.append("-unittest"); try cmds.append("-main"); }, - .lib => {}, .obj => try cmds.append("-c"), - .exe => {}, + else => {}, } if (options.kind == .lib) { @@ -293,6 +290,15 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { try cmds.append(dflag); } + if (options.ldflags) |ldflags| { + for (ldflags) |ldflag| { + if (ldflag[0] == '-') { + @panic("ldflags: add library name only!"); + } + try cmds.append(b.fmt("-L-l{s}", .{ldflag})); + } + } + // betterC disable druntime and phobos if (options.betterC) try cmds.append("--betterC"); @@ -332,8 +338,10 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { // object file output (zig-cache/o/{hash_id}/*.o) if (b.cache_root.path) |path| { - try cmds.append(b.fmt("-od={s}", .{b.pathJoin(&.{ path, "o", b.cache.hash.peek()[0..] })})); - try cmds.append(b.fmt("-cache={s}", .{b.pathJoin(&.{ path, "o", b.cache.hash.peek()[0..] })})); + // immutable state hash + try cmds.append(b.fmt("-od={s}", .{b.pathJoin(&.{ path, "o", &b.cache.hash.peek() })})); + // mutable state hash + try cmds.append(b.fmt("-cache={s}", .{b.pathJoin(&.{ path, "o", &b.cache.hash.final() })})); } // name object files uniquely (so the files don't collide) try cmds.append("--oq"); @@ -348,7 +356,6 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { // keep all function bodies in .di files try cmds.append("--Hkeep-all-bodies"); - // Include imported modules in the compilation // automatically finds needed library files and builds try cmds.append("-i"); @@ -362,7 +369,7 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { } } - // example D file + // D Source files for (options.sources) |src| { try cmds.append(src); } @@ -383,9 +390,7 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { try cmds.append("-Xcc=-v"); } - if (options.artifact) |sokol| { - const lib_sokol = sokol; - + if (options.artifact) |lib_sokol| { if (lib_sokol.linkage == .dynamic or options.linkage == .dynamic) { // linking the druntime/Phobos as dynamic libraries try cmds.append("-link-defaultlib-shared"); @@ -412,6 +417,7 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { try cmds.append(b.fmt("--Xcc={s}", .{flag})); break; } + // C defines for (lib_sokol.root_module.c_macros.items) |cdefine| { if (cdefine.len > 0) // skip empty cdefines try cmds.append(b.fmt("--Xcc=-D{s}", .{cdefine})); @@ -430,14 +436,16 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*RunStep { } } - if (lib_sokol.root_module.sanitize_thread) |tsan| + if (lib_sokol.root_module.sanitize_thread) |tsan| { if (tsan) try cmds.append("--fsanitize=thread"); + } // zig enable sanitize=undefined by default - if (lib_sokol.root_module.sanitize_c) |ubsan| + if (lib_sokol.root_module.sanitize_c) |ubsan| { if (ubsan) try cmds.append("--fsanitize=address"); + } if (lib_sokol.root_module.omit_frame_pointer) |enabled| { if (enabled) @@ -502,20 +510,17 @@ pub const DCompileStep = struct { betterC: bool = false, sources: []const []const u8, dflags: []const []const u8, + ldflags: ?[]const []const u8 = null, name: []const u8, zig_cc: bool = false, d_packages: ?[]const []const u8 = null, artifact: ?*Build.Step.Compile = null, }; -fn packagePath(b: *Build, package: *Build.Dependency) []const u8 { - return package.path("").getPath(b); -} - // -------------------------- Others Configuration -------------------------- // zig-cc wrapper for ldc2 -fn buildZigCC(b: *Build) *CompileStep { +pub fn buildZigCC(b: *Build) *CompileStep { const exe = b.addExecutable(.{ .name = "zcc", .target = b.host, diff --git a/src/examples/user-data.d b/src/examples/user-data.d index b7ba55d..2450820 100644 --- a/src/examples/user-data.d +++ b/src/examples/user-data.d @@ -34,12 +34,11 @@ void frame_userdata(scope void* userdata) @trusted if (state.data % 12 == 0 && state.data % 15 == 0) { state.map.clear(); } - version(D_BetterC){ - import core.stdc.stdio; - printf("ExampleUserData[%d:%d, %d]\n", state.map.length, state.data, state.map.fetch(state.data).value); - } else { - import std.stdio; - writeln(*state); + debug { + import std.stdio : writeln; + try { + writeln(*state); + } catch (Exception) {} } sg.PassAction pass_action = {}; diff --git a/src/hashmap.d b/src/hashmap.d deleted file mode 100644 index f2afad3..0000000 --- a/src/hashmap.d +++ /dev/null @@ -1,28 +0,0 @@ -import std.range; -import std.algorithm; -import ikod.containers.hashmap; - -static string[] words = -[ - "hello", "this", "simple", "example", "should", "succeed", "or", "it", - "should", "fail" -]; - -void main() @safe @nogc -{ - HashMap!(string, int) counter; - // count words, simplest and fastest way - foreach (word; words) { - counter[word] = counter.getOrAdd(word, 0) + 1; // getOrAdd() return the value from the table or add it to the table - } - assert(counter.fetch("hello").ok); // fetch() is a replacement to "in": you get "ok" if the key exists in the table - assert(counter.fetch("hello").value == 1); // and the value itself - debug assert(counter["hello"] == 1); // opIndex is not @nogc - debug assert(counter["should"] == 2); // opIndex is not @nogc - assert(counter.contains("hello")); // checks the key existence - assert(counter.length == words.length - 1); // because "should" counts only once - // iterators - assert(counter.byKey.count == counter.byValue.count); - assert(words.all!(w => counter.contains(w))); // all words in table - assert(counter.byValue.sum == words.length); // sum of counters must equal to the number of words -} \ No newline at end of file