From e789ba363ccd36d1d838987cdd6c8c062306b8f7 Mon Sep 17 00:00:00 2001 From: freref <35976402+freref@users.noreply.github.com> Date: Wed, 26 Feb 2025 18:52:37 +0100 Subject: [PATCH] feat: static link mupdf (#56) * feature: static linking * readme: update build instructions * adjust: gh actions * remove: sudo * fix: path * fix: yml indent * fix: ubuntu build * fmt: build * readme: update * readme: run * readme: add sh highlighting * readme: fmt * rename: submodule dir * deps: tag * fix: bin size * undo: perms * undo: more perms * undo: even more perms * ignore: warnings * readme: build instructions * deps: update mupdf --- .github/workflows/test.yml | 23 ++------------ .gitignore | 2 +- .gitmodules | 3 ++ README.md | 45 ++++++++-------------------- build.zig | 61 ++++++++++++++++++++++++-------------- build.zig.zon | 2 +- deps/mupdf | 1 + 7 files changed, 60 insertions(+), 77 deletions(-) create mode 100644 .gitmodules mode change 100644 => 100755 build.zig mode change 100644 => 100755 build.zig.zon create mode 160000 deps/mupdf diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 78a344d..b0120f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,31 +16,14 @@ jobs: steps: - uses: actions/checkout@v4 + with: + submodules: recursive - uses: mlugg/setup-zig@v1 with: version: 0.13.0 - - name: Install MuPDF (Ubuntu) - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - sudo apt-get install -y libmupdf-dev \ - libharfbuzz-dev \ - libfreetype6-dev \ - libjbig2dec0-dev \ - libjpeg-dev \ - libopenjp2-7-dev \ - libgumbo-dev \ - libmujs-dev \ - zlib1g-dev - - - name: Install MuPDF (macOS) - if: matrix.os == 'macos-latest' - run: brew install mupdf - - - run: zig build - + - run: zig build -Dprefix=$HOME/.local lint: runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index 38013cb..260156c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ zig-out/ # releases to make it less annoying to work with multiple branches. zig-cache/ -example.pdf +*.pdf *.typst target/ *.jpg diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b89b699 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "deps/mupdf"] + path = deps/mupdf + url = https://github.com/ArtifexSoftware/mupdf.git diff --git a/README.md b/README.md index 5b731d4..821e867 100644 --- a/README.md +++ b/README.md @@ -52,56 +52,37 @@ Available as a Nix package [here](https://github.com/freref/fancy-cat-nix). - Zig version `0.13.0` - Terminal emulator with the Kitty image protocol (e.g. Kitty, Ghostty, WezTerm, etc.) -- [MuPDF](https://mupdf.readthedocs.io/en/latest/quick-start-guide.html) -#### MacOS - -```sh -brew install mupdf -``` +### Build -#### Linux +1. Fetch submodules: -```sh -apt install \ - libmupdf-dev \ - libharfbuzz-dev \ - libfreetype6-dev \ - libjbig2dec0-dev \ - libjpeg-dev \ - libopenjp2-7-dev \ - libgumbo-dev \ - libmujs-dev \ - zlib1g-dev +``` +git submodule update --init --recursive ``` -> [!NOTE] -> On some Linux distributions (e.g., Fedora, Arch), replace `mupdf-third` with `mupdf` in `build.zig` to compile successfully. - -### Build - -1. Fetch dependencies: +2. Fetch dependencies: ```sh zig build --fetch ``` -2. Build the project: +3. Build the project: ```sh -zig build --release=fast +zig build -Dprefix=$HOME/.local --release=small ``` > [!NOTE] > There is a [known issue](https://github.com/freref/fancy-cat/issues/18) with some processors; if the build fails on step 7/10 with the error `LLVM ERROR: Do not know how to expand the result of this operator!` then try the command below instead: > -> ``` -> zig build --release=fast -Dcpu="skylake" +> ```sh +> zig build -Dprefix=$HOME/.local -Dcpu="skylake" --release=small > ``` -3. Install: +4. Install: -``` +```sh # Add to your PATH # Linux mv zig-out/bin/fancy-cat ~/.local/bin/ @@ -112,8 +93,8 @@ mv zig-out/bin/fancy-cat /usr/local/bin/ ### Run -``` -zig build run -- +```sh +zig build -Dprefix=$HOME/.local run -- ``` ## Features diff --git a/build.zig b/build.zig old mode 100644 new mode 100755 index d9c6ff3..9da068a --- a/build.zig +++ b/build.zig @@ -1,26 +1,12 @@ const std = @import("std"); -fn addMupdfDeps(exe: *std.Build.Step.Compile, target: std.Target) void { - if (target.os.tag == .macos and target.cpu.arch == .aarch64) { - exe.addIncludePath(.{ .cwd_relative = "/opt/homebrew/include" }); - exe.addLibraryPath(.{ .cwd_relative = "/opt/homebrew/lib" }); - } else if (target.os.tag == .macos and target.cpu.arch == .x86_64) { - exe.addIncludePath(.{ .cwd_relative = "/usr/local/include" }); - exe.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" }); - } else if (target.os.tag == .linux) { - exe.addIncludePath(.{ .cwd_relative = "/home/linuxbrew/.linuxbrew/include" }); - exe.addLibraryPath(.{ .cwd_relative = "/home/linuxbrew/.linuxbrew/lib" }); - - const linux_libs = [_][]const u8{ - "mupdf-third", "harfbuzz", - "freetype", "jbig2dec", - "jpeg", "openjp2", - "gumbo", "mujs", - }; - for (linux_libs) |lib| exe.linkSystemLibrary(lib); - } - exe.linkSystemLibrary("mupdf"); - exe.linkSystemLibrary("z"); +fn addMupdfDeps(exe: *std.Build.Step.Compile, b: *std.Build, prefix: []const u8) void { + exe.addIncludePath(.{ .cwd_relative = b.fmt("{s}/include", .{prefix}) }); + exe.addLibraryPath(.{ .cwd_relative = b.fmt("{s}/lib", .{prefix}) }); + + exe.addObjectFile(.{ .cwd_relative = b.fmt("{s}/lib/libmupdf.a", .{prefix}) }); + exe.addObjectFile(.{ .cwd_relative = b.fmt("{s}/lib/libmupdf-third.a", .{prefix}) }); + exe.linkLibC(); } @@ -28,13 +14,38 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const prefix = b.option([]const u8, "prefix", "Installation prefix") orelse "./local"; + + var make_args = std.ArrayList([]const u8).init(b.allocator); + defer make_args.deinit(); + + make_args.append("make") catch unreachable; + make_args.append("-C") catch unreachable; + make_args.append("deps/mupdf") catch unreachable; + + if (target.result.os.tag == .linux) { + make_args.append("HAVE_X11=no") catch unreachable; + make_args.append("HAVE_GLUT=no") catch unreachable; + } + + make_args.append("XCFLAGS=-w -DTOFU -DTOFU_CJK -DFZ_ENABLE_PDF=1 " ++ + "-DFZ_ENABLE_XPS=0 -DFZ_ENABLE_SVG=0 -DFZ_ENABLE_CBZ=0 " ++ + "-DFZ_ENABLE_IMG=0 -DFZ_ENABLE_HTML=0 -DFZ_ENABLE_EPUB=0") catch unreachable; + make_args.append("tools=no") catch unreachable; + make_args.append("apps=no") catch unreachable; + + const prefix_arg = b.fmt("prefix={s}", .{prefix}); + make_args.append(prefix_arg) catch unreachable; + make_args.append("install") catch unreachable; + + const mupdf_build_step = b.addSystemCommand(make_args.items); + const exe = b.addExecutable(.{ .name = "fancy-cat", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); - exe.headerpad_max_install_names = true; const deps = .{ @@ -47,8 +58,12 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("vaxis", deps.vaxis.module("vaxis")); exe.root_module.addImport("fzwatch", deps.fzwatch.module("fzwatch")); - addMupdfDeps(exe, target.result); + exe.step.dependOn(&mupdf_build_step.step); + + addMupdfDeps(exe, b, prefix); + b.installArtifact(exe); + b.getInstallStep().dependOn(&mupdf_build_step.step); const run_cmd = b.addRunArtifact(exe); if (b.args) |args| run_cmd.addArgs(args); diff --git a/build.zig.zon b/build.zig.zon old mode 100644 new mode 100755 index 3056f5a..b8b2278 --- a/build.zig.zon +++ b/build.zig.zon @@ -8,7 +8,7 @@ .hash = "122098b207673eb55bf51b9981b7b7f5c852149dac82d49d70f07c7227323f8c0617", }, .fzwatch = .{ - .url = "https://github.com/freref/fzwatch/archive/refs/tags/v0.2.1.tar.gz", + .url = "https://github.com/freref/fzwatch/archive/refs/heads/master.tar.gz", .hash = "1220a6181ec8374f37e49914204b98ff4cc326bfca1a46594364886fe962f998c9dd", }, .fastb64z = .{ diff --git a/deps/mupdf b/deps/mupdf new file mode 160000 index 0000000..2b0b591 --- /dev/null +++ b/deps/mupdf @@ -0,0 +1 @@ +Subproject commit 2b0b591153b50a06e64c5a7dd7a33bff8cdc61dc