clipboard/build.zig
Emil Lerch e4849bcd13
partial windows support/external curl
zfetch (or iguana) is triggering some Crowdstrike heuristic
simply from the inclusion of the library, so we need to add
an option to compile with included zfetch or with external
curl
2022-01-05 17:46:08 -08:00

153 lines
6.1 KiB
Zig

const std = @import("std");
const GitRepoStep = @import("GitRepoStep.zig");
pub fn build(b: *std.build.Builder) void {
const zfetch_repo = GitRepoStep.create(b, .{
.url = "https://github.com/truemedian/zfetch",
// .branch = "0.1.10", // branch also takes tags. Tag 0.1.10 isn't quite new enough
.sha = "271cab5da4d12c8f08e67aa0cd5268da100e52f1",
});
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const uploadexe = switch (target.getOs().tag) {
.linux => b.addExecutable("clipboard-upload", "src/main-linux.zig"),
.windows => b.addExecutable("clipboard-upload", "src/main-windows.zig"),
else => std.os.exit(1),
};
const path = if (b.option(bool, "curl", "use external curl command") orelse false)
"config/curl.zig"
else
"config/nocurl.zig";
configureExe(uploadexe, b, target, mode, zfetch_repo, path);
const run_cmd = uploadexe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app (uplaods clipboard contents)");
run_step.dependOn(&run_cmd.step);
const downloadexe = b.addExecutable("clipboard-download", "src/download.zig");
configureExe(downloadexe, b, target, mode, zfetch_repo, path);
const run_download_cmd = downloadexe.run();
run_download_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_download_cmd.addArgs(args);
}
const run_download_step = b.step("run-down", "Run the app (downloads clipboard contents)");
run_download_step.dependOn(&run_download_cmd.step);
}
fn configureExe(exe: *std.build.LibExeObjStep, b: *std.build.Builder, target: std.zig.CrossTarget, mode: std.builtin.Mode, zfetch_repo: anytype, config_path: []const u8) void {
exe.setTarget(target);
exe.setBuildMode(mode);
if (target.getOs().tag == .linux) {
exe.linkLibC();
// LibX11 1.7.2: https://gitlab.freedesktop.org/xorg/lib/libx11/-/archive/libX11-1.7.2/libx11-libX11-1.7.2.tar.gz
// LibXfixes 5.0.3: https://gitlab.freedesktop.org/xorg/lib/libxfixes/-/archive/libXfixes-5.0.3/libxfixes-libXfixes-5.0.3.tar.gz
// XOrg Proto: https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/archive/xorgproto-2021.5/xorgproto-xorgproto-2021.5.tar.gz
// We can download the above by taking each url and processing in a
// command e.g.:
// curl <url> | tar xz --wildcards '*.h'
exe.addIncludeDir("libx11-libX11-1.7.2/include");
exe.addIncludeDir("libxfixes-libXfixes-5.0.3/include");
exe.addIncludeDir("xorgproto-xorgproto-2021.5/include");
// More than a little messy. We're grabbing libX11 and libXfixes from
// the host, while using downloaded headers. This assumes debian
// bullseye host, and also means you can't cross-compile from Windows.
// TODO: Make this better
const dependent_objects = .{
"/usr/lib/x86_64-linux-gnu/libX11.so.6",
"/usr/lib/x86_64-linux-gnu/libXfixes.so.3",
};
inline for (dependent_objects) |obj|
exe.addObjectFile(obj);
}
if (target.getOs().tag == .windows) {
// woah...we don't actually need libc!
exe.linkSystemLibrary("user32");
exe.linkSystemLibrary("kernel32");
exe.linkSystemLibrary("shell32");
}
const copy_deps = std.build.RunStep.create(b, "copy zfetch deps");
copy_deps.addArgs(&[_][]const u8{
"cp",
"zfetch_deps.zig",
"libs/zfetch/deps.zig",
});
copy_deps.step.dependOn(&zfetch_repo.step);
// exe.step.dependOn(&zfetch_repo.step);
exe.step.dependOn(&copy_deps.step);
// This import won't work unless we're already cloned. The way around
// this is to have a multi-stage build process, but that's a lot of work.
// Instead, I've copied the addPackage and tweaked it for the build prefix
// so we'll have to keep that in sync with upstream
// const zfetch = @import("libs/zfetch/build.zig");
const zpkg = getZfetchPackage(b, "libs/zfetch") catch unreachable;
exe.addPackage(zpkg);
exe.addPackage(.{
.name = "iguanaTLS",
.path = .{ .path = "libs/zfetch/libs/iguanaTLS/src/main.zig" },
});
exe.addPackage(.{
.name = "config",
.path = .{ .path = config_path },
});
exe.install();
}
fn getDependency(comptime lib_prefix: []const u8, comptime name: []const u8, comptime root: []const u8) !std.build.Pkg {
const path = lib_prefix ++ "/libs/" ++ name ++ "/" ++ root;
// We don't actually care if the dependency has been checked out, as
// GitRepoStep will handle that for us
// Make sure that the dependency has been checked out.
// std.fs.cwd().access(path, .{}) catch |err| switch (err) {
// error.FileNotFound => {
// std.log.err("zfetch: dependency '{s}' not checked out", .{name});
//
// return err;
// },
// else => return err,
// };
return std.build.Pkg{
.name = name,
.path = .{ .path = path },
};
}
pub fn getZfetchPackage(b: *std.build.Builder, comptime lib_prefix: []const u8) !std.build.Pkg {
var dependencies = b.allocator.alloc(std.build.Pkg, 4) catch unreachable;
dependencies[0] = try getDependency(lib_prefix, "iguanaTLS", "src/main.zig");
dependencies[1] = try getDependency(lib_prefix, "network", "network.zig");
dependencies[2] = try getDependency(lib_prefix, "uri", "uri.zig");
dependencies[3] = try getDependency(lib_prefix, "hzzp", "src/main.zig");
return std.build.Pkg{
.name = "zfetch",
.path = .{ .path = lib_prefix ++ "/src/main.zig" },
.dependencies = dependencies,
};
}