build.zig 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. const std = @import("std");
  2. const builtin = @import("builtin");
  3. pub fn build(b: *std.Build) !void {
  4. const target = b.standardTargetOptions(.{});
  5. const optimize = b.standardOptimizeOption(.{});
  6. const zigup_exe_native = blk: {
  7. const exe = addZigupExe(b, target, optimize);
  8. b.installArtifact(exe);
  9. const run_cmd = b.addRunArtifact(exe);
  10. run_cmd.step.dependOn(b.getInstallStep());
  11. const run_step = b.step("run", "Run the app");
  12. run_step.dependOn(&run_cmd.step);
  13. if (b.args) |args| {
  14. run_cmd.addArgs(args);
  15. }
  16. break :blk exe;
  17. };
  18. const test_step = b.step("test", "test the executable");
  19. {
  20. const exe = b.addExecutable(.{
  21. .name = "test",
  22. .root_source_file = b.path("test.zig"),
  23. .target = target,
  24. .optimize = optimize,
  25. });
  26. const run_cmd = b.addRunArtifact(exe);
  27. run_cmd.addArtifactArg(zigup_exe_native);
  28. run_cmd.addDirectoryArg(b.path("scratch/native"));
  29. test_step.dependOn(&run_cmd.step);
  30. }
  31. const unzip_step = b.step(
  32. "unzip",
  33. "Build/install the unzip cmdline tool",
  34. );
  35. {
  36. const unzip = b.addExecutable(.{
  37. .name = "unzip",
  38. .root_source_file = b.path("unzip.zig"),
  39. .target = target,
  40. .optimize = optimize,
  41. });
  42. const install = b.addInstallArtifact(unzip, .{});
  43. unzip_step.dependOn(&install.step);
  44. }
  45. const zip_step = b.step(
  46. "zip",
  47. "Build/install the zip cmdline tool",
  48. );
  49. {
  50. const zip = b.addExecutable(.{
  51. .name = "zip",
  52. .root_source_file = b.path("zip.zig"),
  53. .target = target,
  54. .optimize = optimize,
  55. });
  56. const install = b.addInstallArtifact(zip, .{});
  57. zip_step.dependOn(&install.step);
  58. }
  59. const host_zip_exe = b.addExecutable(.{
  60. .name = "zip",
  61. .root_source_file = b.path("zip.zig"),
  62. .target = b.host,
  63. });
  64. const ci_step = b.step("ci", "The build/test step to run on the CI");
  65. ci_step.dependOn(b.getInstallStep());
  66. ci_step.dependOn(test_step);
  67. ci_step.dependOn(unzip_step);
  68. ci_step.dependOn(zip_step);
  69. try ci(b, ci_step, test_step, host_zip_exe);
  70. }
  71. fn addZigupExe(
  72. b: *std.Build,
  73. target: std.Build.ResolvedTarget,
  74. optimize: std.builtin.Mode,
  75. ) *std.Build.Step.Compile {
  76. const win32exelink_mod: ?*std.Build.Module = blk: {
  77. if (target.result.os.tag == .windows) {
  78. const exe = b.addExecutable(.{
  79. .name = "win32exelink",
  80. .root_source_file = b.path("win32exelink.zig"),
  81. .target = target,
  82. .optimize = optimize,
  83. });
  84. break :blk b.createModule(.{
  85. .root_source_file = exe.getEmittedBin(),
  86. });
  87. }
  88. break :blk null;
  89. };
  90. const exe = b.addExecutable(.{
  91. .name = "zigup",
  92. .root_source_file = b.path("zigup.zig"),
  93. .target = target,
  94. .optimize = optimize,
  95. });
  96. if (target.result.os.tag == .windows) {
  97. exe.root_module.addImport("win32exelink", win32exelink_mod.?);
  98. }
  99. return exe;
  100. }
  101. fn ci(
  102. b: *std.Build,
  103. ci_step: *std.Build.Step,
  104. test_step: *std.Build.Step,
  105. host_zip_exe: *std.Build.Step.Compile,
  106. ) !void {
  107. const ci_targets = [_][]const u8{
  108. "x86_64-linux",
  109. "x86_64-macos",
  110. "x86_64-windows",
  111. "aarch64-linux",
  112. "aarch64-macos",
  113. "aarch64-windows",
  114. "arm-linux",
  115. "riscv64-linux",
  116. "powerpc-linux",
  117. "powerpc64le-linux",
  118. };
  119. const make_archive_step = b.step("archive", "Create CI archives");
  120. ci_step.dependOn(make_archive_step);
  121. var previous_test_step = test_step;
  122. for (ci_targets) |ci_target_str| {
  123. const target = b.resolveTargetQuery(try std.Target.Query.parse(
  124. .{ .arch_os_abi = ci_target_str },
  125. ));
  126. const optimize: std.builtin.OptimizeMode =
  127. // Compile in ReleaseSafe on Windows for faster extraction
  128. if (target.result.os.tag == .windows) .ReleaseSafe else .Debug;
  129. const zigup_exe = addZigupExe(b, target, optimize);
  130. const zigup_exe_install = b.addInstallArtifact(zigup_exe, .{
  131. .dest_dir = .{ .override = .{ .custom = ci_target_str } },
  132. });
  133. ci_step.dependOn(&zigup_exe_install.step);
  134. const test_exe = b.addExecutable(.{
  135. .name = b.fmt("test-{s}", .{ci_target_str}),
  136. .root_source_file = b.path("test.zig"),
  137. .target = target,
  138. .optimize = optimize,
  139. });
  140. const run_cmd = b.addRunArtifact(test_exe);
  141. run_cmd.addArtifactArg(zigup_exe);
  142. run_cmd.addDirectoryArg(b.path(b.fmt("scratch/{s}", .{ci_target_str})));
  143. // This doesn't seem to be working, so I've added a pre-check below
  144. run_cmd.failing_to_execute_foreign_is_an_error = false;
  145. const os_compatible = (builtin.os.tag == target.result.os.tag);
  146. const arch_compatible = (builtin.cpu.arch == target.result.cpu.arch);
  147. if (os_compatible and arch_compatible) {
  148. ci_step.dependOn(&run_cmd.step);
  149. // prevent tests from running at the same time so their output
  150. // doesn't mangle each other.
  151. run_cmd.step.dependOn(previous_test_step);
  152. previous_test_step = &run_cmd.step;
  153. }
  154. if (builtin.os.tag == .linux) {
  155. make_archive_step.dependOn(makeCiArchiveStep(b, ci_target_str, target.result, zigup_exe_install, host_zip_exe));
  156. }
  157. }
  158. }
  159. fn makeCiArchiveStep(
  160. b: *std.Build,
  161. ci_target_str: []const u8,
  162. target: std.Target,
  163. exe_install: *std.Build.Step.InstallArtifact,
  164. host_zip_exe: *std.Build.Step.Compile,
  165. ) *std.Build.Step {
  166. const install_path = b.getInstallPath(.prefix, ".");
  167. if (target.os.tag == .windows) {
  168. const out_zip_file = b.pathJoin(&.{
  169. install_path,
  170. b.fmt("zigup-{s}.zip", .{ci_target_str}),
  171. });
  172. const zip = b.addRunArtifact(host_zip_exe);
  173. zip.addArg(out_zip_file);
  174. zip.addArg("zigup.exe");
  175. zip.addArg("zigup.pdb");
  176. zip.cwd = .{ .cwd_relative = b.getInstallPath(
  177. exe_install.dest_dir.?,
  178. ".",
  179. ) };
  180. zip.step.dependOn(&exe_install.step);
  181. return &zip.step;
  182. }
  183. const targz = b.pathJoin(&.{
  184. install_path,
  185. b.fmt("zigup-{s}.tar.gz", .{ci_target_str}),
  186. });
  187. const tar = b.addSystemCommand(&.{
  188. "tar",
  189. "-czf",
  190. targz,
  191. "zigup",
  192. });
  193. tar.cwd = .{ .cwd_relative = b.getInstallPath(
  194. exe_install.dest_dir.?,
  195. ".",
  196. ) };
  197. tar.step.dependOn(&exe_install.step);
  198. return &tar.step;
  199. }