mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-19 22:10:29 +00:00
libghostty: add static library support (#11732)
Multiple changes:
* `zig build -Demit-lib-vt` now produces both shared and static
libraries by default
* Ghosty as a zig build dependency exports the static lib as
`dep.artifact("ghostty-vt-static")`
* CMake exports the static lib as `ghostty-vt-static`
Note that the static library is _not fat_. **If you enable SIMD you have
dependencies** and you need to manually link those: libc++, simdutf, and
highway. The `c-cmake-static` example disables SIMD.
This commit is contained in:
@@ -31,7 +31,8 @@
|
||||
# )
|
||||
# FetchContent_MakeAvailable(ghostty)
|
||||
#
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt)
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt) # shared
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt-static) # static
|
||||
#
|
||||
# To use a local checkout instead of fetching:
|
||||
#
|
||||
@@ -40,7 +41,8 @@
|
||||
# Option 2 — find_package (after installing to a prefix):
|
||||
#
|
||||
# find_package(ghostty-vt REQUIRED)
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt)
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt) # shared
|
||||
# target_link_libraries(myapp PRIVATE ghostty-vt::ghostty-vt-static) # static
|
||||
#
|
||||
# See dist/cmake/README.md for more details and example/c-vt-cmake/ for a
|
||||
# complete working example.
|
||||
@@ -71,7 +73,7 @@ message(STATUS "Found zig: ${ZIG_EXECUTABLE}")
|
||||
# The zig build installs into zig-out/ relative to the source tree.
|
||||
set(ZIG_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zig-out")
|
||||
|
||||
# The library file that zig build produces.
|
||||
# Shared library names (zig build produces both shared and static).
|
||||
if(APPLE)
|
||||
set(GHOSTTY_VT_LIBNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
set(GHOSTTY_VT_SONAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt.0${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
@@ -85,28 +87,35 @@ else()
|
||||
set(GHOSTTY_VT_REALNAME "${CMAKE_SHARED_LIBRARY_PREFIX}ghostty-vt${CMAKE_SHARED_LIBRARY_SUFFIX}.0.1.0")
|
||||
endif()
|
||||
|
||||
set(GHOSTTY_VT_LIBRARY "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_REALNAME}")
|
||||
set(GHOSTTY_VT_SHARED_LIBRARY "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_REALNAME}")
|
||||
|
||||
# Static library name.
|
||||
set(GHOSTTY_VT_STATIC_REALNAME "${CMAKE_STATIC_LIBRARY_PREFIX}ghostty-vt${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(GHOSTTY_VT_STATIC_LIBRARY "${ZIG_OUT_DIR}/lib/${GHOSTTY_VT_STATIC_REALNAME}")
|
||||
|
||||
# Ensure the output directories exist so CMake doesn't reject the
|
||||
# INTERFACE_INCLUDE_DIRECTORIES before the zig build has run.
|
||||
file(MAKE_DIRECTORY "${ZIG_OUT_DIR}/include")
|
||||
|
||||
# Custom command: run zig build -Demit-lib-vt
|
||||
# Custom command: run zig build -Demit-lib-vt (produces both shared and static)
|
||||
add_custom_command(
|
||||
OUTPUT "${GHOSTTY_VT_LIBRARY}"
|
||||
OUTPUT "${GHOSTTY_VT_SHARED_LIBRARY}" "${GHOSTTY_VT_STATIC_LIBRARY}"
|
||||
COMMAND "${ZIG_EXECUTABLE}" build -Demit-lib-vt ${GHOSTTY_ZIG_BUILD_FLAGS}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building libghostty-vt via zig build..."
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
add_custom_target(zig_build_lib_vt ALL DEPENDS "${GHOSTTY_VT_LIBRARY}")
|
||||
add_custom_target(zig_build_lib_vt ALL
|
||||
DEPENDS "${GHOSTTY_VT_SHARED_LIBRARY}" "${GHOSTTY_VT_STATIC_LIBRARY}"
|
||||
)
|
||||
|
||||
# --- IMPORTED library target --------------------------------------------------
|
||||
# --- IMPORTED library targets ------------------------------------------------
|
||||
|
||||
# Shared
|
||||
add_library(ghostty-vt SHARED IMPORTED GLOBAL)
|
||||
set_target_properties(ghostty-vt PROPERTIES
|
||||
IMPORTED_LOCATION "${GHOSTTY_VT_LIBRARY}"
|
||||
IMPORTED_LOCATION "${GHOSTTY_VT_SHARED_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ZIG_OUT_DIR}/include"
|
||||
)
|
||||
if(APPLE)
|
||||
@@ -118,15 +127,32 @@ elseif(NOT WIN32)
|
||||
IMPORTED_SONAME "${GHOSTTY_VT_SONAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_dependencies(ghostty-vt zig_build_lib_vt)
|
||||
|
||||
# Static
|
||||
#
|
||||
# When linking the static library, consumers must also link its transitive
|
||||
# dependencies. By default (with SIMD enabled), these are:
|
||||
# - libc
|
||||
# - libc++ (or libstdc++ on Linux)
|
||||
# - highway
|
||||
# - simdutf
|
||||
#
|
||||
# Building with -Dsimd=false removes the C++ / highway / simdutf
|
||||
# dependencies, leaving only libc.
|
||||
add_library(ghostty-vt-static STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(ghostty-vt-static PROPERTIES
|
||||
IMPORTED_LOCATION "${GHOSTTY_VT_STATIC_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${ZIG_OUT_DIR}/include"
|
||||
)
|
||||
add_dependencies(ghostty-vt-static zig_build_lib_vt)
|
||||
|
||||
# --- Install ------------------------------------------------------------------
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Install the library
|
||||
install(FILES "${GHOSTTY_VT_LIBRARY}" TYPE LIB)
|
||||
# Install shared library
|
||||
install(FILES "${GHOSTTY_VT_SHARED_LIBRARY}" TYPE LIB)
|
||||
if(NOT WIN32)
|
||||
# Install symlinks
|
||||
install(CODE "
|
||||
@@ -139,6 +165,9 @@ if(NOT WIN32)
|
||||
")
|
||||
endif()
|
||||
|
||||
# Install static library
|
||||
install(FILES "${GHOSTTY_VT_STATIC_LIBRARY}" TYPE LIB)
|
||||
|
||||
# Install headers
|
||||
install(DIRECTORY "${ZIG_OUT_DIR}/include/ghostty" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
|
||||
23
build.zig
23
build.zig
@@ -106,6 +106,29 @@ pub fn build(b: *std.Build) !void {
|
||||
};
|
||||
libghostty_vt_shared.install(b.getInstallStep());
|
||||
|
||||
// libghostty-vt static lib. We don't build this for wasm since wasm has
|
||||
// no concept of static vs shared and we put the wasm binary up in
|
||||
// our shared handling.
|
||||
if (!config.target.result.cpu.arch.isWasm()) {
|
||||
const libghostty_vt_static = try buildpkg.GhosttyLibVt.initStatic(
|
||||
b,
|
||||
&mod,
|
||||
);
|
||||
|
||||
if (config.is_dep) {
|
||||
// If we're a dependency, we need to install everything as-is
|
||||
// so that dep.artifact("ghostty-vt-static") works.
|
||||
libghostty_vt_static.install(b.getInstallStep());
|
||||
} else {
|
||||
// If we're not a dependency, we rename the static lib to
|
||||
// be idiomatic.
|
||||
b.getInstallStep().dependOn(&b.addInstallLibFile(
|
||||
libghostty_vt_static.output,
|
||||
"libghostty-vt.a",
|
||||
).step);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpgen
|
||||
if (config.emit_helpgen) deps.help_strings.install();
|
||||
|
||||
|
||||
24
dist/cmake/ghostty-vt-config.cmake.in
vendored
24
dist/cmake/ghostty-vt-config.cmake.in
vendored
@@ -2,11 +2,12 @@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
set(_ghostty_vt_libdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||
|
||||
# Shared library target
|
||||
if(NOT TARGET ghostty-vt::ghostty-vt)
|
||||
add_library(ghostty-vt::ghostty-vt SHARED IMPORTED)
|
||||
|
||||
set(_ghostty_vt_libdir "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||
|
||||
set_target_properties(ghostty-vt::ghostty-vt PROPERTIES
|
||||
IMPORTED_LOCATION "${_ghostty_vt_libdir}/@GHOSTTY_VT_REALNAME@"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@"
|
||||
@@ -26,8 +27,23 @@ if(NOT TARGET ghostty-vt::ghostty-vt)
|
||||
IMPORTED_SONAME "@GHOSTTY_VT_SONAME@"
|
||||
)
|
||||
endif()
|
||||
|
||||
unset(_ghostty_vt_libdir)
|
||||
endif()
|
||||
|
||||
# Static library target
|
||||
#
|
||||
# Consumers must link transitive dependencies themselves. By default (with
|
||||
# SIMD enabled): libc, libc++ (or libstdc++ on Linux), highway, and
|
||||
# simdutf. Building with -Dsimd=false removes the C++ / highway / simdutf
|
||||
# dependencies.
|
||||
if(NOT TARGET ghostty-vt::ghostty-vt-static)
|
||||
add_library(ghostty-vt::ghostty-vt-static STATIC IMPORTED)
|
||||
|
||||
set_target_properties(ghostty-vt::ghostty-vt-static PROPERTIES
|
||||
IMPORTED_LOCATION "${_ghostty_vt_libdir}/@GHOSTTY_VT_STATIC_REALNAME@"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@"
|
||||
)
|
||||
endif()
|
||||
|
||||
unset(_ghostty_vt_libdir)
|
||||
|
||||
check_required_components(ghostty-vt)
|
||||
|
||||
13
example/c-vt-cmake-static/CMakeLists.txt
Normal file
13
example/c-vt-cmake-static/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(c-vt-cmake-static LANGUAGES C)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(ghostty
|
||||
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
|
||||
GIT_TAG main
|
||||
)
|
||||
set(GHOSTTY_ZIG_BUILD_FLAGS "-Dsimd=false" CACHE STRING "" FORCE)
|
||||
FetchContent_MakeAvailable(ghostty)
|
||||
|
||||
add_executable(c_vt_cmake_static src/main.c)
|
||||
target_link_libraries(c_vt_cmake_static PRIVATE ghostty-vt-static)
|
||||
21
example/c-vt-cmake-static/README.md
Normal file
21
example/c-vt-cmake-static/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# c-vt-cmake-static
|
||||
|
||||
Demonstrates consuming libghostty-vt as a **static** library from a CMake
|
||||
project using `FetchContent`. Creates a terminal, writes VT sequences into
|
||||
it, and formats the screen contents as plain text.
|
||||
|
||||
## Building
|
||||
|
||||
```shell-session
|
||||
cd example/c-vt-cmake-static
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
./build/c_vt_cmake_static
|
||||
```
|
||||
|
||||
To build against a local checkout instead of fetching from GitHub:
|
||||
|
||||
```shell-session
|
||||
cmake -B build -DFETCHCONTENT_SOURCE_DIR_GHOSTTY=../..
|
||||
cmake --build build
|
||||
```
|
||||
52
example/c-vt-cmake-static/src/main.c
Normal file
52
example/c-vt-cmake-static/src/main.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
// Create a terminal with a small grid
|
||||
GhosttyTerminal terminal;
|
||||
GhosttyTerminalOptions opts = {
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 0,
|
||||
};
|
||||
GhosttyResult result = ghostty_terminal_new(NULL, &terminal, opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
// Write some VT-encoded content into the terminal
|
||||
const char *commands[] = {
|
||||
"Hello from a \033[1mCMake\033[0m-built program (static)!\r\n",
|
||||
"Line 2: \033[4munderlined\033[0m text\r\n",
|
||||
"Line 3: \033[31mred\033[0m \033[32mgreen\033[0m \033[34mblue\033[0m\r\n",
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
|
||||
ghostty_terminal_vt_write(terminal, (const uint8_t *)commands[i],
|
||||
strlen(commands[i]));
|
||||
}
|
||||
|
||||
// Format the terminal contents as plain text
|
||||
GhosttyFormatterTerminalOptions fmt_opts =
|
||||
GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
fmt_opts.trim = true;
|
||||
|
||||
GhosttyFormatter formatter;
|
||||
result = ghostty_formatter_terminal_new(NULL, &formatter, terminal, fmt_opts);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
uint8_t *buf = NULL;
|
||||
size_t len = 0;
|
||||
result = ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
|
||||
assert(result == GHOSTTY_SUCCESS);
|
||||
|
||||
printf("Plain text (%zu bytes):\n", len);
|
||||
fwrite(buf, 1, len, stdout);
|
||||
printf("\n");
|
||||
|
||||
free(buf);
|
||||
ghostty_formatter_free(formatter);
|
||||
ghostty_terminal_free(terminal);
|
||||
return 0;
|
||||
}
|
||||
18
example/c-vt-static/README.md
Normal file
18
example/c-vt-static/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Example: `ghostty-vt` Static Linking
|
||||
|
||||
This contains a simple example of how to statically link the `ghostty-vt`
|
||||
C library with a C program using the `ghostty-vt-static` artifact. It is
|
||||
otherwise identical to the `c-vt` example.
|
||||
|
||||
This uses a `build.zig` and `Zig` to build the C program so that we
|
||||
can reuse a lot of our build logic and depend directly on our source
|
||||
tree, but Ghostty emits a standard C library that can be used with any
|
||||
C tooling.
|
||||
|
||||
## Usage
|
||||
|
||||
Run the program:
|
||||
|
||||
```shell-session
|
||||
zig build run
|
||||
```
|
||||
44
example/c-vt-static/build.zig
Normal file
44
example/c-vt-static/build.zig
Normal file
@@ -0,0 +1,44 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
|
||||
const exe_mod = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe_mod.addCSourceFiles(.{
|
||||
.root = b.path("src"),
|
||||
.files = &.{"main.c"},
|
||||
});
|
||||
|
||||
// You'll want to use a lazy dependency here so that ghostty is only
|
||||
// downloaded if you actually need it.
|
||||
if (b.lazyDependency("ghostty", .{
|
||||
// Setting simd to false will force a pure static build that
|
||||
// doesn't even require libc, but it has a significant performance
|
||||
// penalty. If your embedding app requires libc anyway, you should
|
||||
// always keep simd enabled.
|
||||
// .simd = false,
|
||||
})) |dep| {
|
||||
// Use "ghostty-vt-static" for static linking instead of
|
||||
// "ghostty-vt" which provides a shared library.
|
||||
exe_mod.linkLibrary(dep.artifact("ghostty-vt-static"));
|
||||
}
|
||||
|
||||
// Exe
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "c_vt_static",
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
b.installArtifact(exe);
|
||||
|
||||
// Run
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
24
example/c-vt-static/build.zig.zon
Normal file
24
example/c-vt-static/build.zig.zon
Normal file
@@ -0,0 +1,24 @@
|
||||
.{
|
||||
.name = .c_vt_static,
|
||||
.version = "0.0.0",
|
||||
.fingerprint = 0xa592a9fdd5d87ed2,
|
||||
.minimum_zig_version = "0.15.1",
|
||||
.dependencies = .{
|
||||
// Ghostty dependency. In reality, you'd probably use a URL-based
|
||||
// dependency like the one showed (and commented out) below this one.
|
||||
// We use a path dependency here for simplicity and to ensure our
|
||||
// examples always test against the source they're bundled with.
|
||||
.ghostty = .{ .path = "../../" },
|
||||
|
||||
// Example of what a URL-based dependency looks like:
|
||||
// .ghostty = .{
|
||||
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
|
||||
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
|
||||
// },
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
},
|
||||
}
|
||||
36
example/c-vt-static/src/main.c
Normal file
36
example/c-vt-static/src/main.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ghostty/vt.h>
|
||||
|
||||
int main() {
|
||||
GhosttyOscParser parser;
|
||||
if (ghostty_osc_new(NULL, &parser) != GHOSTTY_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Setup change window title command to change the title to "hello"
|
||||
ghostty_osc_next(parser, '0');
|
||||
ghostty_osc_next(parser, ';');
|
||||
const char *title = "hello";
|
||||
for (size_t i = 0; i < strlen(title); i++) {
|
||||
ghostty_osc_next(parser, title[i]);
|
||||
}
|
||||
|
||||
// End parsing and get command
|
||||
GhosttyOscCommand command = ghostty_osc_end(parser, 0);
|
||||
|
||||
// Get and print command type
|
||||
GhosttyOscCommandType type = ghostty_osc_command_type(command);
|
||||
printf("Command type: %d\n", type);
|
||||
|
||||
// Extract and print the title
|
||||
if (ghostty_osc_command_data(command, GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR, &title)) {
|
||||
printf("Extracted title: %s\n", title);
|
||||
} else {
|
||||
printf("Failed to extract title\n");
|
||||
}
|
||||
|
||||
ghostty_osc_free(parser);
|
||||
return 0;
|
||||
}
|
||||
@@ -61,6 +61,10 @@ emit_xcframework: bool = false,
|
||||
emit_webdata: bool = false,
|
||||
emit_unicode_table_gen: bool = false,
|
||||
|
||||
/// True when Ghostty is being built as a dependency of another project
|
||||
/// rather than as the root project.
|
||||
is_dep: bool = false,
|
||||
|
||||
/// Environmental properties
|
||||
env: std.process.EnvMap,
|
||||
|
||||
@@ -88,6 +92,10 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config {
|
||||
break :target result;
|
||||
};
|
||||
|
||||
// Detect if Ghostty is a dependency of another project.
|
||||
// dep_prefix is non-empty when this build is running as a dependency.
|
||||
const is_dep = b.dep_prefix.len > 0;
|
||||
|
||||
// This is set to true when we're building a system package. For now
|
||||
// this is trivially detected using the "system_package_mode" bool
|
||||
// but we may want to make this more sophisticated in the future.
|
||||
@@ -110,6 +118,7 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config {
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
.wasm_target = wasm_target,
|
||||
.is_dep = is_dep,
|
||||
.env = env,
|
||||
};
|
||||
|
||||
@@ -221,9 +230,7 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config {
|
||||
const app_version = try std.SemanticVersion.parse(appVersion);
|
||||
|
||||
// Is ghostty a dependency? If so, skip git detection.
|
||||
// @src().file won't resolve from b.build_root unless ghostty
|
||||
// is the project being built.
|
||||
b.build_root.handle.access(@src().file, .{}) catch break :version .{
|
||||
if (is_dep) break :version .{
|
||||
.major = app_version.major,
|
||||
.minor = app_version.minor,
|
||||
.patch = app_version.patch,
|
||||
|
||||
@@ -12,11 +12,22 @@ step: *std.Build.Step,
|
||||
/// The artifact result
|
||||
artifact: *std.Build.Step.InstallArtifact,
|
||||
|
||||
/// The kind of library
|
||||
kind: Kind,
|
||||
|
||||
/// The final library file
|
||||
output: std.Build.LazyPath,
|
||||
dsym: ?std.Build.LazyPath,
|
||||
pkg_config: ?std.Build.LazyPath,
|
||||
|
||||
/// The kind of library being built. This is similar to LinkMode but
|
||||
/// also includes wasm which is an executable, not a library.
|
||||
const Kind = enum {
|
||||
wasm,
|
||||
shared,
|
||||
static,
|
||||
};
|
||||
|
||||
pub fn initWasm(
|
||||
b: *std.Build,
|
||||
zig: *const GhosttyZig,
|
||||
@@ -39,20 +50,40 @@ pub fn initWasm(
|
||||
return .{
|
||||
.step = &exe.step,
|
||||
.artifact = b.addInstallArtifact(exe, .{}),
|
||||
.kind = .wasm,
|
||||
.output = exe.getEmittedBin(),
|
||||
.dsym = null,
|
||||
.pkg_config = null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn initStatic(
|
||||
b: *std.Build,
|
||||
zig: *const GhosttyZig,
|
||||
) !GhosttyLibVt {
|
||||
return initLib(b, zig, .static);
|
||||
}
|
||||
|
||||
pub fn initShared(
|
||||
b: *std.Build,
|
||||
zig: *const GhosttyZig,
|
||||
) !GhosttyLibVt {
|
||||
return initLib(b, zig, .dynamic);
|
||||
}
|
||||
|
||||
fn initLib(
|
||||
b: *std.Build,
|
||||
zig: *const GhosttyZig,
|
||||
linkage: std.builtin.LinkMode,
|
||||
) !GhosttyLibVt {
|
||||
const kind: Kind = switch (linkage) {
|
||||
.static => .static,
|
||||
.dynamic => .shared,
|
||||
};
|
||||
const target = zig.vt.resolved_target.?;
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "ghostty-vt",
|
||||
.linkage = .dynamic,
|
||||
.name = if (kind == .static) "ghostty-vt-static" else "ghostty-vt",
|
||||
.linkage = linkage,
|
||||
.root_module = zig.vt_c,
|
||||
.version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 },
|
||||
});
|
||||
@@ -62,6 +93,19 @@ pub fn initShared(
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
if (kind == .static) {
|
||||
// These must be bundled since we're compiling into a static lib.
|
||||
// Otherwise, you get undefined symbol errors. This could cause
|
||||
// problems if you're linking multiple static Zig libraries but
|
||||
// we'll cross that bridge when we get to it.
|
||||
lib.bundle_compiler_rt = true;
|
||||
lib.bundle_ubsan_rt = true;
|
||||
|
||||
// Enable PIC so the static library can be linked into PIE
|
||||
// executables, which is the default on most Linux distributions.
|
||||
lib.root_module.pic = true;
|
||||
}
|
||||
|
||||
if (lib.rootModuleTarget().abi.isAndroid()) {
|
||||
// Support 16kb page sizes, required for Android 15+.
|
||||
lib.link_z_max_page_size = 16384; // 16kb
|
||||
@@ -82,11 +126,10 @@ pub fn initShared(
|
||||
if (builtin.os.tag.isDarwin()) try @import("apple_sdk").addPaths(b, lib);
|
||||
}
|
||||
|
||||
// Get our debug symbols
|
||||
// Get our debug symbols (only for shared libs; static libs aren't linked)
|
||||
const dsymutil: ?std.Build.LazyPath = dsymutil: {
|
||||
if (!target.result.os.tag.isDarwin()) {
|
||||
break :dsymutil null;
|
||||
}
|
||||
if (kind != .shared) break :dsymutil null;
|
||||
if (!target.result.os.tag.isDarwin()) break :dsymutil null;
|
||||
|
||||
const dsymutil = RunStep.create(b, "dsymutil");
|
||||
dsymutil.addArgs(&.{"dsymutil"});
|
||||
@@ -116,6 +159,7 @@ pub fn initShared(
|
||||
return .{
|
||||
.step = &lib.step,
|
||||
.artifact = b.addInstallArtifact(lib, .{}),
|
||||
.kind = kind,
|
||||
.output = lib.getEmittedBin(),
|
||||
.dsym = dsymutil,
|
||||
.pkg_config = pc,
|
||||
|
||||
Reference in New Issue
Block a user