mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-23 21:30:19 +00:00
build: add ghostty-internal pkg-config modules (shared + static) (#12214)
## 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 - [x] `zig build` succeeds (default target) - [x] `ghostty-internal.pc` and `ghostty-internal-static.pc` appear in `zig-out/share/pkgconfig/` - [x] Static `.pc` points at `ghostty-static.lib` (Windows) / `libghostty.a` (Unix) - [x] Shared `.pc` uses standard `-L -l` flags - [x] Existing `libghostty-vt` pkg-config files are unaffected
This commit is contained in:
@@ -190,11 +190,11 @@ pub fn build(b: *std.Build) !void {
|
||||
if (!config.target.result.os.tag.isDarwin()) {
|
||||
lib_shared.installHeader(); // Only need one header
|
||||
if (config.target.result.os.tag == .windows) {
|
||||
lib_shared.install("ghostty.dll");
|
||||
lib_static.install("ghostty-static.lib");
|
||||
lib_shared.install("ghostty-internal.dll");
|
||||
lib_static.install("ghostty-internal-static.lib");
|
||||
} else {
|
||||
lib_shared.install("libghostty.so");
|
||||
lib_static.install("libghostty.a");
|
||||
lib_shared.install("ghostty-internal.so");
|
||||
lib_static.install("ghostty-internal.a");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ step: *std.Build.Step,
|
||||
/// The final static library file
|
||||
output: std.Build.LazyPath,
|
||||
dsym: ?std.Build.LazyPath,
|
||||
pkg_config: ?std.Build.LazyPath,
|
||||
pkg_config_static: ?std.Build.LazyPath,
|
||||
|
||||
pub fn initStatic(
|
||||
b: *std.Build,
|
||||
@@ -54,6 +56,8 @@ pub fn initStatic(
|
||||
.step = &lib.step,
|
||||
.output = lib.getEmittedBin(),
|
||||
.dsym = null,
|
||||
.pkg_config = null,
|
||||
.pkg_config_static = null,
|
||||
};
|
||||
|
||||
// Create a static lib that contains all our dependencies.
|
||||
@@ -70,6 +74,8 @@ pub fn initStatic(
|
||||
|
||||
// Static libraries cannot have dSYMs because they aren't linked.
|
||||
.dsym = null,
|
||||
.pkg_config = null,
|
||||
.pkg_config_static = null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -146,10 +152,20 @@ pub fn initShared(
|
||||
break :dsymutil output;
|
||||
};
|
||||
|
||||
// pkg-config
|
||||
//
|
||||
// pkg-config's --static only expands Libs.private / Requires.private;
|
||||
// it doesn't rewrite Libs: into an archive-only reference when both
|
||||
// shared and static libraries are installed. Install a dedicated
|
||||
// static module so consumers can request the archive explicitly.
|
||||
const pcs = pkgConfigFiles(b, deps);
|
||||
|
||||
return .{
|
||||
.step = &lib.step,
|
||||
.output = lib.getEmittedBin(),
|
||||
.dsym = dsymutil,
|
||||
.pkg_config = pcs.shared,
|
||||
.pkg_config_static = pcs.static,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -168,7 +184,7 @@ pub fn initMacOSUniversal(
|
||||
|
||||
const universal = LipoStep.create(b, .{
|
||||
.name = "ghostty",
|
||||
.out_name = "libghostty.a",
|
||||
.out_name = "ghostty-internal.a",
|
||||
.input_a = aarch64.output,
|
||||
.input_b = x86_64.output,
|
||||
});
|
||||
@@ -180,13 +196,31 @@ pub fn initMacOSUniversal(
|
||||
// You can't run dsymutil on a universal binary, you have to
|
||||
// do it on the individual binaries.
|
||||
.dsym = null,
|
||||
.pkg_config = null,
|
||||
.pkg_config_static = null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn install(self: *const GhosttyLib, name: []const u8) void {
|
||||
const b = self.step.owner;
|
||||
const step = b.getInstallStep();
|
||||
const lib_install = b.addInstallLibFile(self.output, name);
|
||||
b.getInstallStep().dependOn(&lib_install.step);
|
||||
step.dependOn(&lib_install.step);
|
||||
|
||||
if (self.pkg_config) |pc| {
|
||||
step.dependOn(&b.addInstallFileWithDir(
|
||||
pc,
|
||||
.prefix,
|
||||
"share/pkgconfig/ghostty-internal.pc",
|
||||
).step);
|
||||
}
|
||||
if (self.pkg_config_static) |pc| {
|
||||
step.dependOn(&b.addInstallFileWithDir(
|
||||
pc,
|
||||
.prefix,
|
||||
"share/pkgconfig/ghostty-internal-static.pc",
|
||||
).step);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn installHeader(self: *const GhosttyLib) void {
|
||||
@@ -197,3 +231,61 @@ pub fn installHeader(self: *const GhosttyLib) void {
|
||||
);
|
||||
b.getInstallStep().dependOn(&header_install.step);
|
||||
}
|
||||
|
||||
const PkgConfigFiles = struct {
|
||||
shared: std.Build.LazyPath,
|
||||
static: std.Build.LazyPath,
|
||||
};
|
||||
|
||||
fn pkgConfigFiles(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
) PkgConfigFiles {
|
||||
const os_tag = deps.config.target.result.os.tag;
|
||||
const wf = b.addWriteFiles();
|
||||
|
||||
return .{
|
||||
.shared = wf.add("ghostty-internal.pc", b.fmt(
|
||||
\\prefix={s}
|
||||
\\includedir=${{prefix}}/include
|
||||
\\libdir=${{prefix}}/lib
|
||||
\\
|
||||
\\Name: ghostty-internal
|
||||
\\URL: https://github.com/ghostty-org/ghostty
|
||||
\\Description: Ghostty internal library (not for external use)
|
||||
\\Version: {f}
|
||||
\\Cflags: -I${{includedir}}
|
||||
\\Libs: ${{libdir}}/{s}
|
||||
\\Libs.private:
|
||||
\\Requires.private:
|
||||
, .{ b.install_prefix, deps.config.version, sharedLibraryName(os_tag) })),
|
||||
.static = wf.add("ghostty-internal-static.pc", b.fmt(
|
||||
\\prefix={s}
|
||||
\\includedir=${{prefix}}/include
|
||||
\\libdir=${{prefix}}/lib
|
||||
\\
|
||||
\\Name: ghostty-internal-static
|
||||
\\URL: https://github.com/ghostty-org/ghostty
|
||||
\\Description: Ghostty internal library, static (not for external use)
|
||||
\\Version: {f}
|
||||
\\Cflags: -I${{includedir}}
|
||||
\\Libs: ${{libdir}}/{s}
|
||||
\\Libs.private:
|
||||
\\Requires.private:
|
||||
, .{ b.install_prefix, deps.config.version, staticLibraryName(os_tag) })),
|
||||
};
|
||||
}
|
||||
|
||||
fn sharedLibraryName(os_tag: std.Target.Os.Tag) []const u8 {
|
||||
return if (os_tag == .windows)
|
||||
"ghostty-internal.dll"
|
||||
else
|
||||
"ghostty-internal.so";
|
||||
}
|
||||
|
||||
fn staticLibraryName(os_tag: std.Target.Os.Tag) []const u8 {
|
||||
return if (os_tag == .windows)
|
||||
"ghostty-internal-static.lib"
|
||||
else
|
||||
"ghostty-internal.a";
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ Manual test programs for Windows-specific functionality.
|
||||
|
||||
## test_dll_init.c
|
||||
|
||||
Regression test for the DLL CRT initialization fix. Loads ghostty.dll
|
||||
at runtime and calls ghostty_info + ghostty_init to verify the MSVC C
|
||||
runtime is properly initialized.
|
||||
Regression test for the DLL CRT initialization fix. Loads
|
||||
ghostty-internal.dll at runtime and calls ghostty_info + ghostty_init to
|
||||
verify the MSVC C runtime is properly initialized.
|
||||
|
||||
### Build
|
||||
|
||||
First build ghostty.dll, then compile the test:
|
||||
First build ghostty-internal.dll, then compile the test:
|
||||
|
||||
```
|
||||
zig build -Dapp-runtime=none -Demit-exe=false
|
||||
@@ -22,7 +22,7 @@ zig cc test_dll_init.c -o test_dll_init.exe -target native-native-msvc
|
||||
From this directory:
|
||||
|
||||
```
|
||||
copy ..\..\zig-out\lib\ghostty.dll . && test_dll_init.exe
|
||||
copy ..\..\zig-out\lib\ghostty-internal.dll . && test_dll_init.exe
|
||||
```
|
||||
|
||||
Expected output (after the CRT fix):
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/*
|
||||
* Minimal reproducer for the libghostty DLL CRT initialization issue.
|
||||
* Minimal reproducer for the ghostty-internal DLL CRT initialization issue.
|
||||
*
|
||||
* Before the fix (DllMain calling __vcrt_initialize / __acrt_initialize),
|
||||
* loading ghostty.dll and calling any function that touches the C runtime
|
||||
* crashed with "access violation writing 0x0000000000000024" because Zig's
|
||||
* _DllMainCRTStartup does not initialize the MSVC C runtime for DLL targets.
|
||||
* loading ghostty-internal.dll and calling any function that touches the C
|
||||
* runtime crashed with "access violation writing 0x0000000000000024" because
|
||||
* Zig's _DllMainCRTStartup does not initialize the MSVC C runtime for DLL
|
||||
* targets.
|
||||
*
|
||||
* This test loads the DLL and calls ghostty_info, which exercises the CRT
|
||||
* (string handling, memory). If it returns a version string without
|
||||
* crashing, the CRT is properly initialized.
|
||||
*
|
||||
* Build: zig cc test_dll_init.c -o test_dll_init.exe -target native-native-msvc
|
||||
* Run: copy ..\..\zig-out\lib\ghostty.dll . && test_dll_init.exe
|
||||
* Run: copy ..\..\zig-out\lib\ghostty-internal.dll . && test_dll_init.exe
|
||||
*
|
||||
* Expected output (after fix):
|
||||
* ghostty_info: <version string>
|
||||
@@ -29,7 +30,7 @@ typedef struct {
|
||||
typedef ghostty_info_s (*ghostty_info_fn)(void);
|
||||
|
||||
int main(void) {
|
||||
HMODULE dll = LoadLibraryA("ghostty.dll");
|
||||
HMODULE dll = LoadLibraryA("ghostty-internal.dll");
|
||||
if (!dll) {
|
||||
fprintf(stderr, "LoadLibrary failed: %lu\n", GetLastError());
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user