From ecf8353c7441b9b0b573592389ca4dacd3e9e1fb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 20 Aug 2022 14:53:53 -0700 Subject: [PATCH] support dynamic linking (not default) test in GH actions --- .github/workflows/test.yml | 12 ++-- build.zig | 112 ++++++++++++++++++++++--------------- nix/devshell.nix | 14 +++++ pkg/freetype/build.zig | 2 +- 4 files changed, 89 insertions(+), 51 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index de3bd7879..1e9b01889 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,10 +35,10 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable - # Run our go tests within the context of the dev shell from the flake. This - # will ensure we have all our dependencies. + # Cross-compile the binary. We always use static building for this + # because its the only way to access the headers. - name: Test Build - run: nix develop -c zig build -Dtarget=${{ matrix.target }} + run: nix develop -c zig build -Dstatic=true -Dtarget=${{ matrix.target }} test: strategy: @@ -57,7 +57,9 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable - # Run our go tests within the context of the dev shell from the flake. This - # will ensure we have all our dependencies. - name: test run: nix develop -c zig build test + + - name: Test Dynamic Build + run: nix develop -c zig build -Dstatic=false + diff --git a/build.zig b/build.zig index 7a60fcfc9..2ea696e7b 100644 --- a/build.zig +++ b/build.zig @@ -11,7 +11,7 @@ const zlib = @import("pkg/zlib/build.zig"); const tracylib = @import("pkg/tracy/build.zig"); const system_sdk = @import("vendor/mach/glfw/system_sdk.zig"); -/// A build that is set to true if Tracy integration should be built. +// Build options, see the build options help for more info. var tracy: bool = false; pub fn build(b: *std.build.Builder) !void { @@ -33,6 +33,12 @@ pub fn build(b: *std.build.Builder) !void { "Enable Tracy integration (default true in Debug on Linux)", ) orelse (mode == .Debug and target.isLinux()); + const static = b.option( + bool, + "static", + "Statically build as much as possible for the exe", + ) orelse true; + const conformance = b.option( []const u8, "conformance", @@ -52,7 +58,7 @@ pub fn build(b: *std.build.Builder) !void { exe.install(); // Add the shared dependencies - try addDeps(b, exe); + try addDeps(b, exe, static); } // term.wasm @@ -105,7 +111,7 @@ pub fn build(b: *std.build.Builder) !void { } main_test.setTarget(target); - try addDeps(b, main_test); + try addDeps(b, main_test, true); var before = b.addLog("\x1b[" ++ color_map.get("cyan").? ++ "\x1b[" ++ color_map.get("b").? ++ "[{s} tests]" ++ "\x1b[" ++ color_map.get("d").? ++ " ----" ++ "\x1b[0m", .{"ghostty"}); var after = b.addLog("\x1b[" ++ color_map.get("d").? ++ "–––---\n\n" ++ "\x1b[0m", .{}); @@ -123,7 +129,7 @@ pub fn build(b: *std.build.Builder) !void { var test_ = b.addTestSource(pkg.source); test_.setTarget(target); - try addDeps(b, test_); + try addDeps(b, test_, true); if (pkg.dependencies) |children| { test_.packages = std.ArrayList(std.build.Pkg).init(b.allocator); try test_.packages.appendSlice(children); @@ -142,57 +148,73 @@ pub fn build(b: *std.build.Builder) !void { fn addDeps( b: *std.build.Builder, step: *std.build.LibExeObjStep, + static: bool, ) !void { + // We always need the Zig packages + step.addPackage(freetype.pkg); + step.addPackage(glfw.pkg); + step.addPackage(libuv.pkg); + step.addPackage(utf8proc.pkg); + + // We always statically compile glad step.addIncludeDir("vendor/glad/include/"); step.addCSourceFile("vendor/glad/src/gl.c", &.{}); - // Dependencies of other dependencies - const zlib_step = try zlib.link(b, step); - const libpng_step = try libpng.link(b, step, .{ - .zlib = .{ - .step = zlib_step, - .include = &zlib.include_paths, - }, - }); - - // Freetype - step.addPackage(freetype.pkg); - _ = try freetype.link(b, step, .{ - .libpng = freetype.Options.Libpng{ - .enabled = true, - .step = libpng_step, - .include = &libpng.include_paths, - }, - - .zlib = .{ - .enabled = true, - .step = zlib_step, - .include = &zlib.include_paths, - }, - }); - - // Glfw - step.addPackage(glfw.pkg); - glfw.link(b, step, .{ - .metal = false, - .opengl = false, // Found at runtime - }); - - // Libuv - step.addPackage(libuv.pkg); - var libuv_step = try libuv.link(b, step); - system_sdk.include(b, libuv_step, .{}); - - // utf8proc - step.addPackage(utf8proc.pkg); - _ = try utf8proc.link(b, step); - // Tracy step.addPackage(tracylib.pkg); if (tracy) { var tracy_step = try tracylib.link(b, step); system_sdk.include(b, tracy_step, .{}); } + + // utf8proc + _ = try utf8proc.link(b, step); + + // Glfw + glfw.link(b, step, .{ + .metal = false, + .opengl = false, // Found at runtime + }); + + // Dynamic link + if (!static) { + step.addIncludePath(freetype.include_path_self); + step.linkSystemLibrary("bzip2"); + step.linkSystemLibrary("freetype2"); + step.linkSystemLibrary("libpng"); + step.linkSystemLibrary("libuv"); + step.linkSystemLibrary("zlib"); + } + + // Other dependencies, we may dynamically link + if (static) { + const zlib_step = try zlib.link(b, step); + const libpng_step = try libpng.link(b, step, .{ + .zlib = .{ + .step = zlib_step, + .include = &zlib.include_paths, + }, + }); + + // Freetype + _ = try freetype.link(b, step, .{ + .libpng = freetype.Options.Libpng{ + .enabled = true, + .step = libpng_step, + .include = &libpng.include_paths, + }, + + .zlib = .{ + .enabled = true, + .step = zlib_step, + .include = &zlib.include_paths, + }, + }); + + // Libuv + var libuv_step = try libuv.link(b, step); + system_sdk.include(b, libuv_step, .{}); + } } fn conformanceSteps( diff --git a/nix/devshell.nix b/nix/devshell.nix index b587e1915..1577471a9 100644 --- a/nix/devshell.nix +++ b/nix/devshell.nix @@ -19,18 +19,26 @@ , freetype , libpng , libGL +, libuv , libX11 , libXcursor , libXext , libXi , libXinerama , libXrandr +, zlib }: let # See package.nix. Keep in sync. rpathLibs = [ libGL ] ++ lib.optionals stdenv.isLinux [ + bzip2 + freetype + libpng + libuv + zlib + libX11 libXcursor libXi @@ -61,6 +69,12 @@ in mkShell rec { buildInputs = [ # TODO: non-linux ] ++ lib.optionals stdenv.isLinux [ + bzip2 + freetype + libpng + libuv + zlib + libX11 libXcursor libXext diff --git a/pkg/freetype/build.zig b/pkg/freetype/build.zig index b85bf4a7f..4e7816a59 100644 --- a/pkg/freetype/build.zig +++ b/pkg/freetype/build.zig @@ -3,7 +3,7 @@ const std = @import("std"); /// Directories with our includes. const root = thisDir() ++ "../../../vendor/freetype/"; const include_path = root ++ "include"; -const include_path_self = thisDir(); +pub const include_path_self = thisDir(); pub const pkg = std.build.Pkg{ .name = "freetype",