|
root / base / usr / src / zyginit / Makefile
Makefile Makefile 190 lines 7.5 KB
  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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# usr/src/zyginit/Makefile — Hammerhead-side build for the vendored
# zyginit init system, zygctl admin CLI, and sysv-wrapper compat shim.
#
# zyginit ships the engine (binary + schema docs + man pages). Hammerhead
# owns the policy: 50 service.toml definitions, the enabled.d/ default-
# enable policy, and the example configs. The split was agreed with the
# zyginit team on 2026-05-21; before then, ~22 service definitions came
# from the upstream tarball and we layered a small overrides/ tree on
# top of them. That two-source model is gone — see docs/bugs/zyginit-
# 0.2-service-toml-paths.md for the motivating bug.
#
# Engine source comes from a tarball pinned in tools/vendored.conf,
# extracted by hh-build into ./source/. The Makefile here is the only
# committed build glue; ./source/ is gitignored.
#
# Three binaries land in /sbin/:
#   /sbin/zyginit          PID 1 init daemon (with /sbin/init -> zyginit)
#   /sbin/zygctl           admin CLI
#   /sbin/sysv-wrapper     legacy compat (halt/reboot/poweroff/telinit symlinks)
#
# Plus 50 service definitions installed under /etc/zyginit/services/<name>/,
# the enabled.d/ symlink set, examples, runtime dirs under /var/{log,run}/
# zyginit/, and three man pages.

# Always use the staged reefc from tools/bootstrap/root-hh/. bootstrap-hh.sh
# runs earlier in hh-build's build_toolchain; this is the version pinned
# by tools/bootstrap.conf and built fresh, never the system reefc.
HAMMERHEAD_ROOT = $(SRC)/../../..
REEFC = $(HAMMERHEAD_ROOT)/tools/bootstrap/root-hh/usr/bin/reefc

# Vendored source tree (extracted by hh-build, gitignored).
ZSRC = source

# Built binaries (paths inside ZSRC).
ZYGINIT_BIN = $(ZSRC)/build/zyginit
ZYGCTL_BIN  = $(ZSRC)/tools/zygctl/build/zygctl
SYSVW_BIN   = $(ZSRC)/tools/sysv-wrapper/sysv-wrapper

# Install destinations under proto.
ROOTSBIN                 = $(ROOT)/sbin
ROOTETC_ZYGINIT          = $(ROOT)/etc/zyginit
ROOTETC_ZYGINIT_ENABLED  = $(ROOT)/etc/zyginit/enabled.d
ROOTETC_ZYGINIT_EX       = $(ROOT)/etc/zyginit/examples
ROOTVAR_LOG              = $(ROOT)/var/log/zyginit
ROOTVAR_RUN              = $(ROOT)/var/run/zyginit
ROOTMAN5                 = $(ROOT)/usr/share/man/man5
ROOTMAN8                 = $(ROOT)/usr/share/man/man8

.PHONY: all install clean clobber _msg \
        check_source build_zyginit build_zygctl build_sysvwrapper \
        build_console_login_helper \
        install_bins install_init_link install_services \
        install_examples install_enabled_d install_man install_runtime_dirs

all: check_source build_zyginit build_zygctl build_sysvwrapper \
     build_console_login_helper

check_source:
	@if [ ! -d "$(ZSRC)" ]; then \
	    echo "ERROR: $(ZSRC)/ missing — hh-build's extract step did not run." >&2; \
	    echo "       Source comes from tools/vendored.conf via hh-build." >&2; \
	    exit 1; \
	fi
	@if [ ! -x "$(REEFC)" ]; then \
	    echo "ERROR: staged reefc missing at $(REEFC)" >&2; \
	    echo "       bootstrap-hh.sh build must run before zyginit." >&2; \
	    exit 1; \
	fi

# zyginit — PID 1 init daemon.
# helpers.c provides illumos-side syscall wrappers; zyginit links libcontract.
build_zyginit:
	@mkdir -p $(ZSRC)/build
	cd $(ZSRC) && \
	    gcc -c src/helpers.c -o build/helpers.o && \
	    $(REEFC) build -l contract --obj build/helpers.o

# zygctl — admin CLI.
# symlink_wrapper.c handles argv[0] dispatch for the multi-name binary.
build_zygctl:
	@mkdir -p $(ZSRC)/tools/zygctl/build
	cd $(ZSRC)/tools/zygctl && \
	    gcc -c src/symlink_wrapper.c -o build/symlink_wrapper.o && \
	    $(REEFC) build --obj build/symlink_wrapper.o

# sysv-wrapper — plain C shim with its own Makefile.
build_sysvwrapper:
	$(MAKE) -C $(ZSRC)/tools/sysv-wrapper

# Per-service compiled helpers shipped under ./services/<svc>/.
# Today only console-login has one (write_login_utmpx — writes a
# LOGIN_PROCESS utmpx entry before exec'ing ttymon; required for
# login(1) to find a matching ut_pid).
build_console_login_helper:
	gcc -O2 -Wall \
	    -o services/console-login/write_login_utmpx \
	    services/console-login/write_login_utmpx.c

install: all install_bins install_init_link install_services \
         install_examples install_enabled_d install_man install_runtime_dirs

install_bins:
	mkdir -p $(ROOTSBIN)
	# cp + chmod (not install(1) — illumos's /usr/sbin/install is a broken
	# shell script that needs a richer PATH than hh-build provides).
	cp $(ZYGINIT_BIN) $(ROOTSBIN)/zyginit
	cp $(ZYGCTL_BIN)  $(ROOTSBIN)/zygctl
	cp $(SYSVW_BIN)   $(ROOTSBIN)/sysv-wrapper
	chmod 0555 $(ROOTSBIN)/zyginit $(ROOTSBIN)/zygctl $(ROOTSBIN)/sysv-wrapper
	# legacy-name symlinks → sysv-wrapper
	ln -sf sysv-wrapper $(ROOTSBIN)/halt
	ln -sf sysv-wrapper $(ROOTSBIN)/reboot
	ln -sf sysv-wrapper $(ROOTSBIN)/poweroff
	ln -sf sysv-wrapper $(ROOTSBIN)/telinit

# /sbin/init -> /sbin/zyginit. The kernel exec's /sbin/init at boot,
# so this symlink is what makes zyginit PID 1.
install_init_link:
	rm -f $(ROOTSBIN)/init
	ln -sf zyginit $(ROOTSBIN)/init

# Service definitions are Hammerhead-owned (not from the zyginit
# tarball) as of 2026-05-21. zyginit ships only the engine binary +
# schema docs + a handful of representative examples; Hammerhead owns
# the policy: 50 services under ./services/<name>/ each containing a
# service.toml plus any helper scripts and helper-binary sources.
# Layout matches the runtime tree at /etc/zyginit/services/<name>/.
install_services:
	mkdir -p $(ROOTETC_ZYGINIT)/services
	@for d in services/*/; do \
	    [ -d "$$d" ] || continue; \
	    name=$$(basename $$d); \
	    dst=$(ROOTETC_ZYGINIT)/services/$$name; \
	    mkdir -p $$dst; \
	    for f in $$d*; do \
	        [ -e "$$f" ] || continue; \
	        base=$$(basename "$$f"); \
	        case "$$base" in \
	            *.c) continue ;; \
	        esac; \
	        cp "$$f" $$dst/; \
	    done; \
	    [ -f $$dst/service.toml ] && chmod 0644 $$dst/service.toml || true; \
	    find $$dst -type f -name '*.sh' -exec chmod 0755 {} \; ; \
	done
	# Per-service compiled helpers (e.g. write_login_utmpx).
	-find $(ROOTETC_ZYGINIT)/services -type f -name 'write_login_utmpx' -exec chmod 0755 {} \;

install_examples:
	mkdir -p $(ROOTETC_ZYGINIT_EX)
	-cp examples/* $(ROOTETC_ZYGINIT_EX)/ 2>/dev/null
	-chmod 0644 $(ROOTETC_ZYGINIT_EX)/* 2>/dev/null

# enabled.d/ policy comes from THIS directory (Hammerhead-side decision
# of which services run by default), NOT from the vendored tarball.
# Each entry in ./enabled.d/ is a symlink whose basename is the service
# name. With zyginit 0.2.x per-service-directory layout, the proto-side
# link points at ../services/<name>/ (the directory). The on-disk source
# symlinks may still target the old <name>.toml — we read only the
# basename and synthesize the new target, so we don't depend on the
# source symlink's literal target or on a base-system readlink(1).
install_enabled_d:
	mkdir -p $(ROOTETC_ZYGINIT_ENABLED)
	@for f in enabled.d/*; do \
	    [ -L "$$f" ] || continue; \
	    name=$$(basename "$$f"); \
	    rm -f $(ROOTETC_ZYGINIT_ENABLED)/$$name; \
	    ln -sf "../services/$$name" $(ROOTETC_ZYGINIT_ENABLED)/$$name; \
	done

install_man:
	mkdir -p $(ROOTMAN5) $(ROOTMAN8)
	cp $(ZSRC)/docs/man/man5/zyginit.5 $(ROOTMAN5)/zyginit.5
	cp $(ZSRC)/docs/man/man8/zyginit.8 $(ROOTMAN8)/zyginit.8
	cp $(ZSRC)/docs/man/man8/zygctl.8  $(ROOTMAN8)/zygctl.8
	chmod 0444 $(ROOTMAN5)/zyginit.5 $(ROOTMAN8)/zyginit.8 $(ROOTMAN8)/zygctl.8

install_runtime_dirs:
	mkdir -p $(ROOTVAR_LOG) $(ROOTVAR_RUN)

clean:
	rm -rf $(ZSRC)/build $(ZSRC)/tools/zygctl/build
	rm -f  $(ZSRC)/tools/sysv-wrapper/sysv-wrapper

clobber: clean
	rm -rf $(ZSRC)

# zyginit is not localized — no .po messages.
_msg: