diff --git a/build.zig b/build.zig index ed1f2296..6c870a02 100644 --- a/build.zig +++ b/build.zig @@ -1,14 +1,15 @@ const std = @import("std"); const fs = std.fs; const log = std.log; -const tests = @import("test/test.zig"); +// const tests = @import("test/test.zig"); const Allocator = std.mem.Allocator; -pub fn build(b: *std.Build.Builder) void { +pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const mode = b.standardOptimizeOption(.{}); + const strip = b.option(bool, "strip", "Omit debug information"); const enable_logging = b.option(bool, "log", "Whether to enable logging") orelse (mode == .Debug); const enable_tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source"); @@ -27,12 +28,13 @@ pub fn build(b: *std.Build.Builder) void { .target = target, .optimize = mode, }); - exe.addModule("yaml", yaml.module("yaml")); - exe.addModule("dis_x86_64", dis_x86_64.module("dis_x86_64")); + exe.root_module.addImport("yaml", yaml.module("yaml")); + exe.root_module.addImport("dis_x86_64", dis_x86_64.module("dis_x86_64")); + exe.root_module.strip = strip; exe.linkLibC(); const exe_opts = b.addOptions(); - exe.addOptions("build_options", exe_opts); + exe.root_module.addOptions("build_options", exe_opts); exe_opts.addOption(bool, "enable_logging", enable_logging); exe_opts.addOption(bool, "enable_tracy", enable_tracy != null); @@ -43,19 +45,16 @@ pub fn build(b: *std.Build.Builder) void { ) catch unreachable; // On mingw, we need to opt into windows 7+ to get some features required by tracy. - const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu) + const tracy_c_flags: []const []const u8 = if (target.result.os.tag == .windows and target.result.abi == .gnu) &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" } else &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" }; exe.addIncludePath(.{ .cwd_relative = tracy_path }); - // TODO: upstream bug - exe.addSystemIncludePath(.{ .path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" }); exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); - exe.linkSystemLibraryName("c++"); - exe.strip = false; + exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no }); - if (target.isWindows()) { + if (target.result.os.tag == .windows) { exe.linkSystemLibrary("dbghelp"); exe.linkSystemLibrary("ws2_32"); } @@ -69,37 +68,37 @@ pub fn build(b: *std.Build.Builder) void { }); symlinks.step.dependOn(&install.step); - const system_compiler = b.option(tests.SystemCompiler, "system-compiler", "System compiler we are utilizing for tests: gcc, clang"); - const has_static = b.option(bool, "has-static", "Whether the system compiler supports '-static' flag") orelse false; - const has_zig = b.option(bool, "has-zig", "Whether the Zig compiler is in path") orelse false; - const is_musl = b.option(bool, "musl", "Whether the tests are linked against musl libc") orelse false; - - const unit_tests = b.addTest(.{ - .root_source_file = .{ .path = "src/Zld.zig" }, - .target = target, - .optimize = mode, - }); - const unit_tests_opts = b.addOptions(); - unit_tests.addOptions("build_options", unit_tests_opts); - unit_tests_opts.addOption(bool, "enable_logging", enable_logging); - unit_tests_opts.addOption(bool, "enable_tracy", enable_tracy != null); - unit_tests.addModule("yaml", yaml.module("yaml")); - unit_tests.addModule("dis_x86_64", dis_x86_64.module("dis_x86_64")); - unit_tests.linkLibC(); - - const test_step = b.step("test", "Run tests"); - test_step.dependOn(&b.addRunArtifact(unit_tests).step); - test_step.dependOn(tests.addTests(b, exe, .{ - .system_compiler = system_compiler, - .has_static = has_static, - .has_zig = has_zig, - .is_musl = is_musl, - })); + // const system_compiler = b.option(tests.SystemCompiler, "system-compiler", "System compiler we are utilizing for tests: gcc, clang"); + // const has_static = b.option(bool, "has-static", "Whether the system compiler supports '-static' flag") orelse false; + // const has_zig = b.option(bool, "has-zig", "Whether the Zig compiler is in path") orelse false; + // const is_musl = b.option(bool, "musl", "Whether the tests are linked against musl libc") orelse false; + + // const unit_tests = b.addTest(.{ + // .root_source_file = .{ .path = "src/Zld.zig" }, + // .target = target, + // .optimize = mode, + // }); + // const unit_tests_opts = b.addOptions(); + // unit_tests.root_module.addOptions("build_options", unit_tests_opts); + // unit_tests_opts.addOption(bool, "enable_logging", enable_logging); + // unit_tests_opts.addOption(bool, "enable_tracy", enable_tracy != null); + // unit_tests.root_module.addImport("yaml", yaml.module("yaml")); + // unit_tests.root_module.addImport("dis_x86_64", dis_x86_64.module("dis_x86_64")); + // unit_tests.linkLibC(); + + // const test_step = b.step("test", "Run tests"); + // test_step.dependOn(&b.addRunArtifact(unit_tests).step); + // test_step.dependOn(tests.addTests(b, exe, .{ + // .system_compiler = system_compiler, + // .has_static = has_static, + // .has_zig = has_zig, + // .is_musl = is_musl, + // })); } fn addSymlinks( - builder: *std.Build.Builder, - install: *std.Build.InstallArtifactStep, + builder: *std.Build, + install: *std.Build.Step.InstallArtifact, names: []const []const u8, ) *CreateSymlinksStep { const step = CreateSymlinksStep.create(builder, install, names); @@ -111,13 +110,13 @@ const CreateSymlinksStep = struct { pub const base_id = .custom; step: std.Build.Step, - builder: *std.Build.Builder, - install: *std.Build.InstallArtifactStep, + builder: *std.Build, + install: *std.Build.Step.InstallArtifact, targets: []const []const u8, pub fn create( - builder: *std.Build.Builder, - install: *std.Build.InstallArtifactStep, + builder: *std.Build, + install: *std.Build.Step.InstallArtifact, targets: []const []const u8, ) *CreateSymlinksStep { const self = builder.allocator.create(CreateSymlinksStep) catch unreachable; @@ -137,7 +136,7 @@ const CreateSymlinksStep = struct { fn make(step: *std.Build.Step, prog_node: *std.Progress.Node) anyerror!void { const self = @fieldParentPtr(CreateSymlinksStep, "step", step); - const install_path = self.install.artifact.getOutputSource().getPath(self.builder); + const install_path = self.install.artifact.getEmittedBin().getPath(self.builder); const rel_source = fs.path.basename(install_path); var node = prog_node.start("creating symlinks", self.targets.len); diff --git a/build.zig.zon b/build.zig.zon index 622d1bb8..1e22afbc 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,12 +4,12 @@ .dependencies = .{ .@"zig-yaml" = .{ - .url = "https://github.com/kubkon/zig-yaml/archive/1ed4925bed911b73a189526a6ad82bd8c5c2079a.tar.gz", - .hash = "1220f56d186377820d7ad62ee03987acdd53bc24da83e8f6dff571bc7343f789f69a", + .url = "https://github.com/kubkon/zig-yaml/archive/953bf8e9a10386eb3756d3fc722df634d0d634a9.tar.gz", + .hash = "1220b174728272a3e4b38c27a37bd76e9749fad1668c24538cd8110353e87306360b", }, .@"zig-dis-x86_64" = .{ - .url = "https://github.com/kubkon/zig-dis-x86_64/archive/a9155631990aa6d56fa06fddef304cabb94a0681.tar.gz", - .hash = "1220a4d63ba372f6b5a0fc262f863572dc119727b469f6ccf527ad91790e353bb0f0", + .url = "https://github.com/kubkon/zig-dis-x86_64/archive/752655a8feca210880abb8f1be5acad8e7f4961a.tar.gz", + .hash = "1220591498890a10351d6cadc52cf07a594baeabd7eef7fe3e7a7f43960a3398edea", }, }, diff --git a/src/Elf.zig b/src/Elf.zig index 6e775df5..09d30de8 100644 --- a/src/Elf.zig +++ b/src/Elf.zig @@ -2322,7 +2322,7 @@ fn writeHeader(self: *Elf) !void { .e_shstrndx = self.shstrtab_sect_index.?, }; // Magic - mem.copy(u8, header.e_ident[0..4], "\x7fELF"); + @memcpy(header.e_ident[0..4], "\x7fELF"); // Class header.e_ident[4] = elf.ELFCLASS64; // Endianness diff --git a/src/Elf/relocatable.zig b/src/Elf/relocatable.zig index 7aa92561..8c183810 100644 --- a/src/Elf/relocatable.zig +++ b/src/Elf/relocatable.zig @@ -337,7 +337,7 @@ fn writeHeader(elf_file: *Elf) !void { .e_shstrndx = elf_file.shstrtab_sect_index.?, }; // Magic - mem.copy(u8, header.e_ident[0..4], "\x7fELF"); + @memcpy(header.e_ident[0..4], "\x7fELF"); // Class header.e_ident[4] = elf.ELFCLASS64; // Endianness diff --git a/src/MachO.zig b/src/MachO.zig index 8709fcee..756a3ea9 100644 --- a/src/MachO.zig +++ b/src/MachO.zig @@ -3538,7 +3538,7 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void { pub fn makeStaticString(bytes: []const u8) [16]u8 { var buf = [_]u8{0} ** 16; assert(bytes.len <= buf.len); - mem.copy(u8, &buf, bytes); + @memcpy(buf[0..bytes.len], bytes); return buf; } diff --git a/src/MachO/CodeSignature.zig b/src/MachO/CodeSignature.zig index 695e2a71..ce142b43 100644 --- a/src/MachO/CodeSignature.zig +++ b/src/MachO/CodeSignature.zig @@ -99,7 +99,7 @@ const CodeDirectory = struct { fn addSpecialHash(self: *CodeDirectory, index: u32, hash: [hash_size]u8) void { assert(index > 0); self.inner.nSpecialSlots = @max(self.inner.nSpecialSlots, index); - mem.copy(u8, &self.special_slots[index - 1], &hash); + @memcpy(&self.special_slots[index - 1], &hash); } fn slotType(self: CodeDirectory) u32 { diff --git a/src/MachO/uuid.zig b/src/MachO/uuid.zig index c6dc700a..e7af4dc2 100644 --- a/src/MachO/uuid.zig +++ b/src/MachO/uuid.zig @@ -37,7 +37,7 @@ pub fn calcUuid( defer allocator.free(final_buffer); for (hashes, 0..) |hash, i| { - mem.copy(u8, final_buffer[i * Md5.digest_length ..][0..Md5.digest_length], &hash); + @memcpy(final_buffer[i * Md5.digest_length ..][0..Md5.digest_length], &hash); } Md5.hash(final_buffer, out, .{}); diff --git a/test/test.zig b/test/test.zig index 1191b79d..ed0de02d 100644 --- a/test/test.zig +++ b/test/test.zig @@ -18,9 +18,7 @@ pub fn addTests(b: *Build, comp: *Compile, build_opts: struct { error.InvalidUtf8 => @panic("InvalidUtf8"), error.OutOfMemory => @panic("OOM"), }; - - const zld = FileSourceWithDir.fromFileSource(b, comp.getOutputSource(), "ld"); - + const zld = WriteFile.create(b).addCopyFile(comp.getEmittedBin(), "ld"); const opts: Options = .{ .zld = zld, .system_compiler = system_compiler, @@ -42,7 +40,7 @@ pub const SystemCompiler = enum { }; pub const Options = struct { - zld: FileSourceWithDir, + zld: LazyPath, system_compiler: SystemCompiler, has_static: bool = false, has_zig: bool = false, @@ -51,10 +49,10 @@ pub const Options = struct { }; /// A system command that tracks the command itself via `cmd` Step.Run and output file -/// via `out` FileSource. +/// via `out` LazyPath. pub const SysCmd = struct { cmd: *Run, - out: FileSource, + out: LazyPath, pub fn addArg(sys_cmd: SysCmd, arg: []const u8) void { sys_cmd.cmd.addArg(arg); @@ -64,19 +62,19 @@ pub const SysCmd = struct { sys_cmd.cmd.addArgs(args); } - pub fn addFileSource(sys_cmd: SysCmd, file: FileSource) void { - sys_cmd.cmd.addFileSourceArg(file); + pub fn addFileSource(sys_cmd: SysCmd, file: LazyPath) void { + sys_cmd.cmd.addFileArg(file); } - pub fn addPrefixedFileSource(sys_cmd: SysCmd, prefix: []const u8, file: FileSource) void { - sys_cmd.cmd.addPrefixedFileSourceArg(prefix, file); + pub fn addPrefixedFileSource(sys_cmd: SysCmd, prefix: []const u8, file: LazyPath) void { + sys_cmd.cmd.addPrefixedFileArg(prefix, file); } - pub fn addDirectorySource(sys_cmd: SysCmd, dir: FileSource) void { + pub fn addDirectorySource(sys_cmd: SysCmd, dir: LazyPath) void { sys_cmd.cmd.addDirectorySourceArg(dir); } - pub fn addPrefixedDirectorySource(sys_cmd: SysCmd, prefix: []const u8, dir: FileSource) void { + pub fn addPrefixedDirectorySource(sys_cmd: SysCmd, prefix: []const u8, dir: LazyPath) void { sys_cmd.cmd.addPrefixedDirectorySourceArg(prefix, dir); } @@ -96,11 +94,16 @@ pub const SysCmd = struct { return sys_cmd.addSourceBytes(bytes, .zig); } + pub inline fn addObjCSource(sys_cmd: SysCmd, bytes: []const u8) void { + return sys_cmd.addSourceBytes(bytes, .objc); + } + pub const FileType = enum { c, cpp, @"asm", zig, + objc, }; pub fn addSourceBytes(sys_cmd: SysCmd, bytes: []const u8, @"type": FileType) void { @@ -111,8 +114,9 @@ pub const SysCmd = struct { .cpp => "a.cpp", .@"asm" => "a.s", .zig => "a.zig", + .objc => "a.m", }, bytes); - sys_cmd.cmd.addFileSourceArg(file); + sys_cmd.cmd.addFileArg(file); } pub inline fn addEmptyMain(sys_cmd: SysCmd) void { @@ -133,8 +137,12 @@ pub const SysCmd = struct { ); } - pub fn saveOutputAs(sys_cmd: SysCmd, basename: []const u8) FileSourceWithDir { - return FileSourceWithDir.fromFileSource(sys_cmd.cmd.step.owner, sys_cmd.out, basename); + pub inline fn getFile(sys_cmd: SysCmd) LazyPath { + return sys_cmd.out; + } + + pub inline fn getDir(sys_cmd: SysCmd) LazyPath { + return sys_cmd.out.dirname(); } pub fn check(sys_cmd: SysCmd) *CheckObject { @@ -147,7 +155,7 @@ pub const SysCmd = struct { pub fn run(sys_cmd: SysCmd) RunSysCmd { const b = sys_cmd.cmd.step.owner; const r = Run.create(b, "exec"); - r.addFileSourceArg(sys_cmd.out); + r.addFileArg(sys_cmd.out); r.step.dependOn(&sys_cmd.cmd.step); return .{ .run = r }; } @@ -164,40 +172,36 @@ pub const RunSysCmd = struct { rsc.run.expectStdOutEqual(exp); } - pub inline fn expectExitCode(rsc: RunSysCmd, code: u8) void { - rsc.run.expectExitCode(code); + pub fn expectStdOutFuzzy(rsc: RunSysCmd, exp: []const u8) void { + rsc.run.addCheck(.{ + .expect_stdout_match = rsc.run.step.owner.dupe(exp), + }); } - pub inline fn step(rsc: RunSysCmd) *Step { - return &rsc.run.step; + pub inline fn expectStdErrEqual(rsc: RunSysCmd, exp: []const u8) void { + rsc.run.expectStdErrEqual(exp); } -}; -/// When going over different linking scenarios, we usually want to save a file -/// at a particular location however we do not specify the path to file explicitly -/// on the linker line. Instead, we specify its basename like `-la` and provide -/// the search directory with a matching companion flag `-L.`. -/// This abstraction tie the full path of a file with its immediate directory to make -/// the above scenario possible. -pub const FileSourceWithDir = struct { - dir: FileSource, - file: FileSource, - - pub fn fromFileSource(b: *Build, in_file: FileSource, basename: []const u8) FileSourceWithDir { - const wf = WriteFile.create(b); - const dir = wf.getDirectorySource(); - const file = wf.addCopyFile(in_file, basename); - return .{ .dir = dir, .file = file }; + pub fn expectStdErrFuzzy(rsc: RunSysCmd, exp: []const u8) void { + rsc.run.addCheck(.{ + .expect_stderr_match = rsc.run.step.owner.dupe(exp), + }); } - pub fn fromBytes(b: *Build, bytes: []const u8, basename: []const u8) FileSourceWithDir { - const wf = WriteFile.create(b); - const dir = wf.getDirectorySource(); - const file = wf.add(basename, bytes); - return .{ .dir = dir, .file = file }; + pub fn expectExitCode(rsc: RunSysCmd, code: u8) void { + rsc.run.expectExitCode(code); + } + + pub inline fn step(rsc: RunSysCmd) *Step { + return &rsc.run.step; } }; +pub fn saveBytesToFile(b: *Build, name: []const u8, bytes: []const u8) LazyPath { + const wf = WriteFile.create(b); + return wf.add(name, bytes); +} + pub const SkipTestStep = struct { pub const base_id = .custom; @@ -239,7 +243,7 @@ const macho = @import("macho.zig"); const Build = std.Build; const CheckObject = Step.CheckObject; const Compile = Step.Compile; -const FileSource = Build.FileSource; +const LazyPath = Build.LazyPath; const Run = Step.Run; const Step = Build.Step; const WriteFile = Step.WriteFile;