Ninja requires all produced files to be listed as explicit outputs of
custom commands. The zig build produces a .lib import library alongside
the DLL, but it was not listed in the OUTPUT directive. This causes
Ninja to fail with "missing and no known rule to make it" when
IMPORTED_IMPLIB references the .lib file.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three issues when linking the static library with the MSVC linker:
Use the LLVM backend on Windows to produce valid COFF objects.
The self-hosted backend generates compiler_rt objects with invalid
COMDAT sections that the MSVC linker rejects (LNK1143).
Disable bundling ubsan_rt on Windows. Zig's ubsan runtime emits
/exclude-symbols linker directives that MSVC does not understand
(LNK4229).
Add ntdll and kernel32 as transitive link dependencies for the
static library on Windows. The Zig standard library uses NT API
functions (NtClose, NtCreateSection, etc.) that consumers must
link.
The cmake examples were failing at runtime on Windows CI for two
reasons.
The static library was installed as "libghostty-vt.a" on all
platforms, but on Windows the DLL import library is also placed in
zig-out/lib/ as "ghostty-vt.lib". The CMakeLists.txt expected the
platform-native name "ghostty-vt.lib" for the static lib, so it
picked up the tiny DLL import lib instead, silently producing a
dynamically-linked executable. That executable then failed at
runtime because the DLL was not on PATH.
Fix this by installing the static library as "ghostty-vt-static.lib"
on Windows to avoid the name collision, and updating CMakeLists.txt
to match. For the shared (DLL) example, add zig-out/bin to PATH in
the CI run step so the DLL can be found at runtime.
On Windows, shared libraries (DLLs) require an import library (.lib)
for linking, and the DLL itself is placed in bin/ rather than lib/ by
the Zig build. The CMake wrapper was missing IMPORTED_IMPLIB on the
shared imported target, causing link failures, and assumed the shared
library was always in lib/.
Add GHOSTTY_VT_IMPLIB for the import library name, set IMPORTED_IMPLIB
on the ghostty-vt target, and fix the shared library path to use bin/
on Windows. Install the DLL and PDB to bin/ and the import library to
lib/ following standard Windows conventions. Apply the same fixes to
ghostty-vt-config.cmake.in for the find_package path.
Expose both shared and static libraries as separate CMake imported
targets (ghostty-vt and ghostty-vt-static) rather than toggling
between them with BUILD_SHARED_LIBS. The zig build already produces
both in a single invocation, so both are always available.
The find_package config template is updated to export both targets
as ghostty-vt::ghostty-vt and ghostty-vt::ghostty-vt-static.
Add a c-vt-cmake-static example that demonstrates linking the static
library via FetchContent with -Dsimd=false to avoid C++ runtime
dependencies.
Remove the dedicated `zig build lib-vt` step and replace it with a
`-Demit-lib-vt` build option. This fixes two problems:
1. We can default XCFramework, app, etc. steps to false if emit-lib-vt
is true, so that the lib-vt build doesn't pull in unrelated
artifacts. **Most importantly, lib-vt alone can be build without
full Xcode installations.**
2. We can build lib-vt as part of a bundle with other artifacts if we
really want.
Map CMake release build types (Release, MinSizeRel, RelWithDebInfo)
to -Doptimize=ReleaseFast so that zig build automatically produces
optimized builds when CMake is configured for a release variant.
Debug builds remain unaffected, letting Zig use its default Debug
optimization level.
Add a top-level CMakeLists.txt that wraps `zig build lib-vt` so that
CMake-based downstream projects can consume libghostty-vt without
needing to interact with the Zig build system directly. A custom
command triggers the zig build during `cmake --build`, and the
resulting shared library is exposed as an IMPORTED target.
Downstream projects can pull in the library via FetchContent, which
fetches the source and builds it as part of their own CMake build, or
via find_package after a manual install step. The package config
template in dist/cmake/ sets up the ghostty-vt::ghostty-vt target
with proper include paths and macOS rpath handling.
A c-vt-cmake example demonstrates the FetchContent workflow, creating
a terminal, writing VT sequences, and formatting the output as plain
text. CI is updated to auto-discover and build CMake-based examples
alongside the existing Zig-based ones.