Skip to content

Commit

Permalink
feat: static link mupdf (#56)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
freref authored Feb 26, 2025
1 parent 89c9e83 commit e789ba3
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 77 deletions.
23 changes: 3 additions & 20 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "deps/mupdf"]
path = deps/mupdf
url = https://github.com/ArtifexSoftware/mupdf.git
45 changes: 13 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand All @@ -112,8 +93,8 @@ mv zig-out/bin/fancy-cat /usr/local/bin/
### Run

```
zig build run -- <path-to-pdf> <optional-page-number>
```sh
zig build -Dprefix=$HOME/.local run -- <path-to-pdf> <optional-page-number>
```

## Features
Expand Down
61 changes: 38 additions & 23 deletions build.zig
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
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();
}

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 = .{
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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 = .{
Expand Down
1 change: 1 addition & 0 deletions deps/mupdf
Submodule mupdf added at 2b0b59

0 comments on commit e789ba3

Please sign in to comment.