1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# slosh for Windows — cross-compiled with zig from a mac or a Linux box.
#
# `compat/win` comes first on the include path: it holds stub <poll.h>,
# <sys/socket.h> and friends that redirect to include/compat_win.h, so the
# existing sources keep their POSIX includes and call sites unchanged.
#
# make -f Makefile.windows # ARCH=aarch64, the default
# make -f Makefile.windows ARCH=x86_64
#
ZIG ?= zig
ARCH ?= aarch64
TARGET := $(ARCH)-windows-gnu
CC := $(ZIG) cc -target $(TARGET)
VT := vendor/libghostty-vt
VT_OUT := $(VT)/zig-out-win-$(ARCH)
VT_LIB := $(VT_OUT)/lib/ghostty-vt-static.lib
VT_INC := $(VT_OUT)/include
VT_VERSION := $(shell sed -n 's/^[[:space:]]*\.version = "\([^"]*\)".*/\1/p' $(VT)/build.zig.zon | head -1)
OUT := build/win-$(ARCH)
VERSION := $(shell contrib/version 2>/dev/null || cat VERSION)
DIST ?= dist
STEM := slosh-$(VERSION)-windows-$(ARCH)
# The zip carries the same licensing paperwork as the linux tarballs
# (libghostty-vt and stb_image are linked in -- see THIRD-PARTY-LICENSES).
# The manpages are useless on Windows, so docs/windows.md rides along instead.
REL_DOCS := README.md LICENSE THIRD-PARTY-LICENSES docs/windows.md
CFLAGS := -std=c23 -O1 -g -Wall -Wextra -Wno-unused-parameter -MMD -MP \
-Icompat/win -I$(VT_INC) -Iinclude -I$(OUT) \
-DGHOSTTY_STATIC \
-include compat_win.h
LDFLAGS := -lws2_32 -lshlwapi -lkernel32 -luser32 -ladvapi32 -lole32
SRC := $(wildcard src/*.c)
OBJ := $(SRC:src/%.c=$(OUT)/%.o)
DEPS := $(OBJ:.o=.d)
BIN := $(OUT)/slosh.exe
V ?= 0
ifeq ($(V),0)
Q := @
say = @printf ' %-5s %s\n' '$(1)' '$(2)'
else
Q :=
say = @:
endif
.PHONY: all dist clean vendor-win FORCE
.DEFAULT_GOAL := all
all: $(BIN)
$(BIN): $(OBJ) $(VT_LIB)
$(call say,[LD],$@)
$(Q)$(CC) $(OBJ) $(VT_LIB) -o $@ $(LDFLAGS)
$(OUT)/%.o: src/%.c $(OUT)/version.h $(OUT)/logo.h $(VT_LIB) | $(OUT)
$(call say,[CC],$<)
$(Q)$(CC) $(CFLAGS) -c $< -o $@
$(OUT)/png.o: src/png.c $(OUT)/version.h $(VT_LIB) | $(OUT)
$(call say,[CC],$<)
$(Q)$(CC) $(CFLAGS) -I$(VT)/src/stb -Wno-unused-function -c $< -o $@
# The shim itself calls the real socket API, so it is built with the
# redirections switched off. Everything else sees the POSIX names.
$(OUT)/compat_win.o: src/compat_win.c $(OUT)/version.h | $(OUT)
$(call say,[CC],$<)
$(Q)$(CC) $(CFLAGS) -DSL_COMPAT_IMPL -c $< -o $@
$(OUT)/pty_win.o: src/pty_win.c $(OUT)/version.h $(VT_LIB) | $(OUT)
$(call say,[CC],$<)
$(Q)$(CC) $(CFLAGS) -DSL_COMPAT_IMPL -c $< -o $@
$(OUT):
@mkdir -p $(OUT)
# FORCE, not an order-only prerequisite: the value comes from git rather than
# from a file, so nothing on disk changes when it goes stale. Written only when
# it actually differs, so `make` after a commit rebuilds and `make` twice in a
# row does not.
$(OUT)/version.h: FORCE | $(OUT)
@printf '/* generated by Makefile.windows */\n#define SLOSH_VERSION "%s"\n' \
'$(VERSION)' > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
$(OUT)/logo.h: logo.txt | $(OUT)
$(Q){ printf '/* generated from logo.txt */\n'; \
printf 'static const char *const LOGO[] = {\n'; \
sed -e 's/\\\\/\\\\\\\\/g' -e 's/"/\\\\"/g' -e 's/^/ "/' -e 's/$$/",/' logo.txt; \
printf '};\n'; } > $@
# The release artifact: the binary plus the paperwork, as a zip, because a
# tarball is the wrong shape on the machine that will open it.
dist: $(BIN)
@mkdir -p $(DIST)
@rm -rf "$(DIST)/$(STEM)" "$(DIST)/$(STEM).zip"
@mkdir -p "$(DIST)/$(STEM)"
@cp "$(BIN)" "$(DIST)/$(STEM)/slosh.exe"
@cp $(REL_DOCS) "$(DIST)/$(STEM)/"
@(cd $(DIST) && zip -qr "$(STEM).zip" "$(STEM)")
@rm -rf "$(DIST)/$(STEM)"
$(call say,[ZIP],$(DIST)/$(STEM).zip)
$(VT_LIB): vendor-win
vendor-win:
cd $(VT) && $(ZIG) build -Demit-lib-vt -Demit-xcframework=false \
-Dversion-string=$(VT_VERSION) -Doptimize=ReleaseFast \
-Dtarget=$(TARGET) -p zig-out-win-$(ARCH)
clean:
rm -rf $(OUT)
-include $(DEPS)
|