Skip to content

build: add ghostty-internal pkg-config modules (shared + static) - #12214

Merged
mitchellh merged 5 commits into
ghostty-org:mainfrom
deblasis:build/libghostty-pkg-config-for-main
Apr 12, 2026
Merged

mitchellh merged 5 commits into
ghostty-org:mainfrom
deblasis:build/libghostty-pkg-config-for-main

Conversation

@deblasis

@deblasis deblasis commented Apr 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Mirror the libghostty-vt-static pkg-config pattern from #12210 for the internal library.

  • Add ghostty-internal.pc (shared, -lghostty) and ghostty-internal-static.pc (static, direct archive reference) so consumers can discover either variant via pkg-config
  • Named ghostty-internal to distinguish from the public libghostty-vt API
  • Static module points at the platform-correct archive name (ghostty-static.lib on Windows, libghostty.a elsewhere)
  • pkg-config files are generated during shared builds and installed via GhosttyLib.install()

Test plan

  • zig build succeeds (default target)
  • ghostty-internal.pc and ghostty-internal-static.pc appear in zig-out/share/pkgconfig/
  • Static .pc points at ghostty-static.lib (Windows) / libghostty.a (Unix)
  • Shared .pc uses standard -L -l flags
  • Existing libghostty-vt pkg-config files are unaffected

@deblasis

deblasis commented Apr 10, 2026 •

Copy link
Copy Markdown
Contributor Author

If this one lands, next one would be to create a "fat archive" for windows as well.
Like libtool does on darwin.

I will 90% hit a wall with NativeAOT on windows with winui3 but regardless, that's something MS is supposedly working on.
I might chime in to give a hand with repro/bugs etc.

Update

I hit the wall eventually but found workarounds and managed to get a single executable for Ghostty Windows!
32MB single exe with libghostty (and the other deps) baked in. No ghostty.dll needed.

I filed an issue upstream for anyone else bumping into the same problem: microsoft/WindowsAppSDK#6394

@mitchellh

Copy link
Copy Markdown
Contributor

Lets rename these to ghostty-internal and ghostty-internal-static because this version of "libghostty" is

  1. Not meant for external use
  2. Not libghostty and confuses people for it.

@mitchellh mitchellh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocked on some naming.

@deblasis
deblasis force-pushed the build/libghostty-pkg-config-for-main branch from b2935cb to 66ffe8f Compare April 10, 2026 14:04
@deblasis
deblasis force-pushed the build/libghostty-pkg-config-for-main branch from 66ffe8f to dd04856 Compare April 10, 2026 14:13
@deblasis
deblasis requested a review from mitchellh April 10, 2026 14:17
@deblasis deblasis changed the title build: add libghostty pkg-config modules (shared + static) build: add ghostty-internal pkg-config modules (shared + static) Apr 10, 2026
Comment thread src/build/GhosttyLib.zig Outdated
return if (os_tag == .windows)
"ghostty-static.lib"
else
"libghostty.a";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename this too. And anywhere else we write it out, let's use this PR to fix it up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope I didn't miss/mess up anything :)

Rename the internal library's install names to match the new
ghostty-internal pkg-config module convention:

  ghostty.dll          -> ghostty-internal.dll
  ghostty-static.lib   -> ghostty-internal-static.lib
  libghostty.so        -> ghostty-internal.so
  libghostty.a         -> ghostty-internal.a

This is the glue library between Ghostty's app shells and the GUI
core, historically (mis)named "libghostty". It is not the public
libghostty-vt API.
Switch the shared ghostty-internal.pc Libs: line from -lghostty to a
direct ${libdir}/<file> path, matching what the -static module already
does. The name-per-OS helpers now emit:

  shared:  ghostty-internal.dll (Windows) / ghostty-internal.so (other)
  static:  ghostty-internal-static.lib (Windows) / ghostty-internal.a

Direct paths sidestep the GNU-ld -l<name> search template, which
expects libghostty-internal.so/.a on Unix - we drop the lib prefix to
match the ghostty-internal pkg-config module name.

Also update the LipoStep out_name for the macOS universal static
archive to ghostty-internal.a for consistency.
The internal glue DLL was renamed from ghostty.dll to
ghostty-internal.dll. Update the LoadLibraryA call and the comment
block so this regression test still exercises the right artifact.
Match the dll filename rename so the copy/run instructions stay
accurate.
@deblasis
deblasis requested a review from mitchellh April 11, 2026 02:30
@mitchellh
mitchellh merged commit 94cd3da into ghostty-org:main Apr 12, 2026
89 checks passed
@mitchellh mitchellh added this to the 1.4.0 milestone Apr 12, 2026
mitchellh added a commit that referenced this pull request Apr 23, 2026
## Summary

> [!IMPORTANT]
> Stacked on #12214. Review that first. (i am targeting `main` so here
you will see the full changeset, including 12214

Two changes that make the static libghostty archive consumable by
external linkers (MSVC link.exe, .NET NativeAOT, Rust, Go, etc.):

**Fat static archive on all platforms**

The static archive previously only bundled vendored deps on macOS (via
libtool). On Windows and Linux the archive contained only the
Zig-compiled code, requiring consumers to find and link freetype,
harfbuzz, glslang, spirv-cross, simdutf, oniguruma, etc. separately.

Now all platforms produce a single fat archive:
- macOS: libtool (unchanged)
- Windows: zig ar qcL --format=coff (MSVC's lib.exe can't read
Zig-produced GNU-format archives, so we use the bundled LLVM archiver)
- Linux: ar -M with MRI scripts (same approach as libghostty-vt)

**MSVC ubsan suppression for C deps**

Zig's ubsan runtime can't be bundled on Windows (LNK4229), leaving
__ubsan_handle_* symbols unresolved. freetype, glslang, spirv-cross, and
highway already suppress ubsan. This adds MSVC-conditional suppression
to seven more: harfbuzz, libpng, dcimgui, wuffs, oniguruma, zlib, and
stb.

Gated on abi == .msvc so ubsan coverage is preserved on Linux/macOS.

## Test plan

- [x] zig build produces a fat ghostty-static.lib (~230MB) with ~200
object files
- [x] MSVC's lib /LIST can read the archive
- [x] .NET NativeAOT consumer resolves all symbols (0 unresolved)
- [x] Linux/macOS builds unaffected (ubsan remains enabled)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants