From 2e6c01a5b23cefd7d37d514d3861dd6a0d59240e Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreply.github.com> Date: Sat, 20 Jul 2024 02:40:29 +1000 Subject: [PATCH 1/2] add default-dir build option --- build.zig | 19 ++++++++++++++++--- zigup.zig | 6 ++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/build.zig b/build.zig index 84ebe7f..62579c1 100644 --- a/build.zig +++ b/build.zig @@ -5,8 +5,17 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const default_dir = b.option( + []const u8, + "default-dir", + "Default compiler installation directory (default: zig)", + ) orelse "zig"; + + const build_options = b.addOptions(); + build_options.addOption([]const u8, "default_dir", default_dir); + const zigup_exe_native = blk: { - const exe = addZigupExe(b, target, optimize); + const exe = addZigupExe(b, target, optimize, build_options); b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); @@ -74,13 +83,14 @@ pub fn build(b: *std.Build) !void { ci_step.dependOn(test_step); ci_step.dependOn(unzip_step); ci_step.dependOn(zip_step); - try ci(b, ci_step, test_step, host_zip_exe); + try ci(b, ci_step, test_step, host_zip_exe, build_options); } fn addZigupExe( b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.Mode, + build_options: *std.Build.Step.Options, ) *std.Build.Step.Compile { const win32exelink_mod: ?*std.Build.Module = blk: { if (target.result.os.tag == .windows) { @@ -104,6 +114,8 @@ fn addZigupExe( .optimize = optimize, }); + exe.root_module.addOptions("build-options", build_options); + if (target.result.os.tag == .windows) { exe.root_module.addImport("win32exelink", win32exelink_mod.?); } @@ -115,6 +127,7 @@ fn ci( ci_step: *std.Build.Step, test_step: *std.Build.Step, host_zip_exe: *std.Build.Step.Compile, + build_options: *std.Build.Step.Options, ) !void { const ci_targets = [_][]const u8{ "x86_64-linux", @@ -141,7 +154,7 @@ fn ci( const optimize: std.builtin.OptimizeMode = // Compile in ReleaseSafe on Windows for faster extraction if (target.result.os.tag == .windows) .ReleaseSafe else .Debug; - const zigup_exe = addZigupExe(b, target, optimize); + const zigup_exe = addZigupExe(b, target, optimize, build_options); const zigup_exe_install = b.addInstallArtifact(zigup_exe, .{ .dest_dir = .{ .override = .{ .custom = ci_target_str } }, }); diff --git a/zigup.zig b/zigup.zig index f7a60b8..688001e 100644 --- a/zigup.zig +++ b/zigup.zig @@ -2,6 +2,8 @@ const std = @import("std"); const builtin = @import("builtin"); const mem = std.mem; +const build_options = @import("build-options"); + const ArrayList = std.ArrayList; const Allocator = mem.Allocator; @@ -131,14 +133,14 @@ fn allocInstallDirString(allocator: Allocator) ![]const u8 { if (builtin.os.tag == .windows) { const self_exe_dir = try std.fs.selfExeDirPathAlloc(allocator); defer allocator.free(self_exe_dir); - return std.fs.path.join(allocator, &.{ self_exe_dir, "zig" }); + return std.fs.path.join(allocator, &.{ self_exe_dir, build_options.default_dir }); } const home = try getHomeDir(); if (!std.fs.path.isAbsolute(home)) { std.log.err("$HOME environment variable '{s}' is not an absolute path", .{home}); return error.BadHomeEnvironmentVariable; } - return std.fs.path.join(allocator, &[_][]const u8{ home, "zig" }); + return std.fs.path.join(allocator, &[_][]const u8{ home, build_options.default_dir }); } const GetInstallDirOptions = struct { create: bool, From b460ca24aba5027def60e56effd87fce24d09e4b Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:05:31 +1000 Subject: [PATCH 2/2] add install-parent build option --- build.zig | 15 +++++++++++++++ zigup.zig | 48 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/build.zig b/build.zig index 62579c1..aaeaa7f 100644 --- a/build.zig +++ b/build.zig @@ -11,8 +11,23 @@ pub fn build(b: *std.Build) !void { "Default compiler installation directory (default: zig)", ) orelse "zig"; + const InstallParent = enum { home, @"exe-dir" }; + const install_parent: ?InstallParent = b.option( + InstallParent, + "install-parent", + "Parent of default installation directory, ignored if '-Ddefault-dir' is an absolute path", + ) orelse if (std.fs.path.isAbsolute(default_dir)) + null + else switch (target.result.os.tag) { + .windows => .@"exe-dir", + else => .home, + }; + const build_options = b.addOptions(); build_options.addOption([]const u8, "default_dir", default_dir); + if (install_parent) |dir| { + build_options.addOption(InstallParent, "install_parent", dir); + } const zigup_exe_native = blk: { const exe = addZigupExe(b, target, optimize, build_options); diff --git a/zigup.zig b/zigup.zig index 688001e..18a0c2d 100644 --- a/zigup.zig +++ b/zigup.zig @@ -120,27 +120,43 @@ fn ignoreHttpCallback(request: []const u8) void { _ = request; } -fn getHomeDir() ![]const u8 { - return std.posix.getenv("HOME") orelse { - std.log.err("cannot find install directory, $HOME environment variable is not set", .{}); - return error.MissingHomeEnvironmentVariable; - }; -} - fn allocInstallDirString(allocator: Allocator) ![]const u8 { // TODO: maybe support ZIG_INSTALL_DIR environment variable? // TODO: maybe support a file on the filesystem to configure install dir? - if (builtin.os.tag == .windows) { - const self_exe_dir = try std.fs.selfExeDirPathAlloc(allocator); - defer allocator.free(self_exe_dir); - return std.fs.path.join(allocator, &.{ self_exe_dir, build_options.default_dir }); + + if (comptime std.fs.path.isAbsolute(build_options.default_dir)) { + // copy wouldn't be needed, but makes calling code simpler + return allocator.dupe(u8, build_options.default_dir); } - const home = try getHomeDir(); - if (!std.fs.path.isAbsolute(home)) { - std.log.err("$HOME environment variable '{s}' is not an absolute path", .{home}); - return error.BadHomeEnvironmentVariable; + + switch (build_options.install_parent) { + .@"exe-dir" => { + const self_exe_dir = try std.fs.selfExeDirPathAlloc(allocator); + defer allocator.free(self_exe_dir); + return std.fs.path.join(allocator, &.{ self_exe_dir, build_options.default_dir }); + }, + .home => { + const home = switch (builtin.os.tag) { + .windows => std.process.getEnvVarOwned(allocator, "HOMEPATH") catch |e| switch (e) { + error.EnvironmentVariableNotFound => { + std.log.err("cannot find isntall directory %HOMEPATH% environment variable is not set", .{}); + return error.AlreadyReportedk; + }, + else => |err| return err, + }, + else => std.posix.getenv("HOME") orelse { + std.log.err("cannot find install directory, $HOME environment variable is not set", .{}); + return error.AlreadyReported; + }, + }; + const env = if (builtin.os.tag == .windows) "%HOMEPATH%" else "$HOME"; + if (!std.fs.path.isAbsolute(home)) { + std.log.err(env ++ " environment variable '{s}' is not an absolute path", .{home}); + return error.AlreadyReported; + } + return std.fs.path.join(allocator, &[_][]const u8{ home, build_options.default_dir }); + }, } - return std.fs.path.join(allocator, &[_][]const u8{ home, build_options.default_dir }); } const GetInstallDirOptions = struct { create: bool,