diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 482c8cf..7d23181 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,6 +88,38 @@ jobs: - name: Run example run: nix develop -c go run ./examples/${{ matrix.example }}/ + cross: + strategy: + fail-fast: false + matrix: + target: + - linux-amd64 + - linux-arm64 + - macos-amd64 + - macos-arm64 + - windows-amd64 + - windows-arm64 + name: Cross ${{ matrix.target }} + runs-on: namespace-profile-ghostty-sm + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2 + with: + path: | + /nix + /zig + - name: Setup Nix + uses: cachix/install-nix-action@616559265b40713947b9c190a8ff4b507b5df49b # v31.10.4 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Cross-compile + run: nix develop -c make cross-${{ matrix.target }} + build-shared: runs-on: namespace-profile-ghostty-sm env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 108d7a8..a288c49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,3 +7,13 @@ FetchContent_Declare(ghostty GIT_TAG 2ed382a15566b267c32fae440b065f7844b15bfb ) FetchContent_MakeAvailable(ghostty) + +# Cross-compilation targets for CI and multi-platform builds. +# Each call produces ghostty-vt-static- and ghostty-vt- +# IMPORTED targets whose output lands under build/ghostty-/. +ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu) +ghostty_vt_add_target(NAME linux-arm64 ZIG_TARGET aarch64-linux-gnu) +ghostty_vt_add_target(NAME macos-amd64 ZIG_TARGET x86_64-macos) +ghostty_vt_add_target(NAME macos-arm64 ZIG_TARGET aarch64-macos) +ghostty_vt_add_target(NAME windows-amd64 ZIG_TARGET x86_64-windows-gnu) +ghostty_vt_add_target(NAME windows-arm64 ZIG_TARGET aarch64-windows-gnu) diff --git a/Makefile b/Makefile index 2a773a8..8a7c7ba 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,36 @@ LD_LIBRARY_PATH := $(GHOSTTY_ZIG_OUT)/lib # Stamp file to track whether the cmake build has run. STAMP := $(BUILD_DIR)/.ghostty-built -.PHONY: build test clean +# Cross-compilation target definitions. +# Each entry maps a make target suffix to GOOS, GOARCH, zig target triple, +# and the CC/CXX target flag for zig cc. +CROSS_TARGETS := linux-amd64 linux-arm64 macos-amd64 macos-arm64 windows-amd64 windows-arm64 + +linux-amd64_GOOS := linux +linux-amd64_GOARCH := amd64 +linux-amd64_ZIG := x86_64-linux-gnu + +linux-arm64_GOOS := linux +linux-arm64_GOARCH := arm64 +linux-arm64_ZIG := aarch64-linux-gnu + +macos-amd64_GOOS := darwin +macos-amd64_GOARCH := amd64 +macos-amd64_ZIG := x86_64-macos + +macos-arm64_GOOS := darwin +macos-arm64_GOARCH := arm64 +macos-arm64_ZIG := aarch64-macos + +windows-amd64_GOOS := windows +windows-amd64_GOARCH := amd64 +windows-amd64_ZIG := x86_64-windows-gnu + +windows-arm64_GOOS := windows +windows-arm64_GOARCH := arm64 +windows-arm64_ZIG := aarch64-windows-gnu + +.PHONY: build test clean cross $(addprefix cross-,$(CROSS_TARGETS)) $(STAMP): cmake -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=Release @@ -22,5 +51,24 @@ build: $(STAMP) test: $(STAMP) PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) DYLD_LIBRARY_PATH=$(DYLD_LIBRARY_PATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) go test ./... +# cross builds all cross-compilation targets. +cross: $(addprefix cross-,$(CROSS_TARGETS)) + +# cross- cross-compiles the Go package for the given target using +# zig cc and the libghostty-vt static library built by CMake. +define CROSS_RULE +cross-$(1): $(STAMP) + CGO_ENABLED=1 \ + CC="zig cc -target $$($(1)_ZIG)" \ + CXX="zig c++ -target $$($(1)_ZIG)" \ + GOOS=$$($(1)_GOOS) \ + GOARCH=$$($(1)_GOARCH) \ + CGO_CFLAGS="-I$(CURDIR)/$(BUILD_DIR)/ghostty-$(1)/include -DGHOSTTY_STATIC" \ + CGO_LDFLAGS="-L$(CURDIR)/$(BUILD_DIR)/ghostty-$(1)/lib -lghostty-vt" \ + go build . ./sys/... +endef + +$(foreach t,$(CROSS_TARGETS),$(eval $(call CROSS_RULE,$(t)))) + clean: rm -rf $(BUILD_DIR) diff --git a/README.md b/README.md index e30491a..17b1825 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,47 @@ go build -tags dynamic See the [Ghostty docs](https://ghostty.org/docs/install/build) for building `libghostty-vt` from source. +### Cross-Compilation + +Because `libghostty-vt` only depends on libc, cross-compilation is +straightforward using [Zig](https://ziglang.org/) as the C compiler. +Zig is already required to build `libghostty-vt`, so no extra tooling +is needed. You don't need to write any Zig code, we're just using +Zig as a C/C++ compiler. + +First, build `libghostty-vt` for your target (from the ghostty source tree): + +```shell +zig build -Demit-lib-vt -Dtarget=x86_64-linux-gnu --prefix /tmp/ghostty-linux-amd64 +``` + +Then cross-compile your Go project with `zig cc`: + +```shell +CGO_ENABLED=1 \ +GOOS=linux GOARCH=amd64 \ +CC="zig cc -target x86_64-linux-gnu" \ +CXX="zig c++ -target x86_64-linux-gnu" \ +CGO_CFLAGS="-I/tmp/ghostty-linux-amd64/include -DGHOSTTY_STATIC" \ +CGO_LDFLAGS="-L/tmp/ghostty-linux-amd64/lib -lghostty-vt" \ +go build ./... +``` + +Supported targets include `x86_64-linux-gnu`, `aarch64-linux-gnu`, +`x86_64-macos`, `aarch64-macos`, `x86_64-windows-gnu`, and +`aarch64-windows-gnu`. + +If you are using ghostty's CMake integration via `FetchContent`, the +`ghostty_vt_add_target()` function handles the zig build for you: + +```cmake +FetchContent_MakeAvailable(ghostty) +ghostty_vt_add_target(NAME linux-amd64 ZIG_TARGET x86_64-linux-gnu) +``` + +See the [ghostty CMakeLists.txt](https://github.com/ghostty-org/ghostty/blob/main/CMakeLists.txt) +for full documentation of `ghostty_vt_add_target()`. + ## Development CMake fetches and builds `libghostty-vt` automatically. CMake is only