[PATCH 2/4] Generate makefile file lists from a script

Demi Marie Obenour
2025-09-04T02:09:26Z

The script will always get them right, whereas humans (the author of
this commit included) generally will not.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Documentation/development/built-in-vms.adoc | 7 ++
host/rootfs/Makefile | 107 ++------------------------
host/rootfs/file-list.mk | 100 ++++++++++++++++++++++++
img/app/Makefile | 74 +++---------------
img/app/file-list.mk | 65 ++++++++++++++++
lib/common.mk | 1 +
scripts/genfiles.awk | 115 ++++++++++++++++++++++++++++
vm/sys/net/Makefile | 51 +++---------
vm/sys/net/file-list.mk | 41 ++++++++++
9 files changed, 357 insertions(+), 204 deletions(-)

diff --git a/Documentation/development/built-in-vms.adoc b/Documentation/development/built-in-vms.adoc
index e90009ee5a3c2c254a7ae11e36121576b819eee7..82d78705a6020bbdb06fbc123a32dbdd6fd50085 100644
--- a/Documentation/development/built-in-vms.adoc
+++ b/Documentation/development/built-in-vms.adoc
@@ -44,6 +44,13 @@ NOTE: As a special convenience, it's not necessary to run `make clean`
if the only change to the Nix files is modifying the packages
installed in the VM.

+The list of files used for the VM image is stored in a separate file,
+`file-lists.mk`. You can edit it manually when developing. However,
+after each commit that adds or removes files from it, you should run
+`make update-file-list`, which will regenerate it from the output of
+`git ls-files`. Any changes you made will be lost. This ensures
+that the file lists are always in sync with the git repository.
+
By default, `make run` runs the VM in Cloud Hypervisor, to match the
Spectrum environment. You can also add `VMM=crosvm` or `VMM=qemu` to
your command line to run the VM in a different VMM. One reason to do
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 3e77bb8c9ff0dfe8c9325c470fb1c632876c3dc3..3560707d21bcf53e4f3ad5e916d21e8be56cc3a1 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -4,67 +4,10 @@
.POSIX:

include ../../lib/common.mk
+include file-list.mk

dest = build/rootfs.erofs

-FILES = \
- etc/fonts/fonts.conf \
- etc/fstab \
- etc/group \
- etc/init \
- etc/login \
- etc/mdev.conf \
- etc/mdev/listen \
- etc/mdev/net/add \
- etc/mdev/wait \
- etc/parse-devname \
- etc/passwd \
- etc/s6-linux-init/env/WAYLAND_DISPLAY \
- etc/s6-linux-init/env/XDG_RUNTIME_DIR \
- etc/s6-linux-init/run-image/service/dbus/notification-fd \
- etc/s6-linux-init/run-image/service/dbus/run \
- etc/s6-linux-init/run-image/service/dbus/template/notification-fd \
- etc/s6-linux-init/run-image/service/dbus/template/run \
- etc/s6-linux-init/run-image/service/getty-tty1/run \
- etc/s6-linux-init/run-image/service/getty-tty2/run \
- etc/s6-linux-init/run-image/service/getty-tty3/run \
- etc/s6-linux-init/run-image/service/getty-tty4/run \
- etc/s6-linux-init/run-image/service/s6-svscan-log/notification-fd \
- etc/s6-linux-init/run-image/service/s6-svscan-log/run \
- etc/s6-linux-init/run-image/service/serial-getty-generator/run \
- etc/s6-linux-init/run-image/service/serial-getty/notification-fd \
- etc/s6-linux-init/run-image/service/serial-getty/run \
- etc/s6-linux-init/run-image/service/serial-getty/template/run \
- etc/s6-linux-init/run-image/service/vhost-user-fs/notification-fd \
- etc/s6-linux-init/run-image/service/vhost-user-fs/run \
- etc/s6-linux-init/run-image/service/vhost-user-fs/template/notification-fd \
- etc/s6-linux-init/run-image/service/vhost-user-fs/template/run \
- etc/s6-linux-init/run-image/service/vhost-user-gpu/notification-fd \
- etc/s6-linux-init/run-image/service/vhost-user-gpu/run \
- etc/s6-linux-init/run-image/service/vhost-user-gpu/template/data/check \
- etc/s6-linux-init/run-image/service/vhost-user-gpu/template/notification-fd \
- etc/s6-linux-init/run-image/service/vhost-user-gpu/template/run \
- etc/s6-linux-init/run-image/service/vmm/notification-fd \
- etc/s6-linux-init/run-image/service/vmm/run \
- etc/s6-linux-init/run-image/service/vmm/template/notification-fd \
- etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/notification-fd \
- etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/run \
- etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/notification-fd \
- etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/run \
- etc/s6-linux-init/scripts/rc.init \
- etc/xdg/weston/autolaunch \
- etc/xdg/weston/weston.ini \
- usr/share/dbus-1/services/org.freedesktop.portal.Documents.service \
- usr/bin/assign-devices \
- usr/bin/create-vm-dependencies \
- usr/bin/run-appimage \
- usr/bin/run-vmm \
- usr/bin/vm-console \
- usr/bin/vm-import \
- usr/bin/vm-start \
- usr/bin/vm-stop \
- usr/bin/xdg-open
-
DIRS = \
dev \
etc/s6-linux-init/env \
@@ -101,18 +44,9 @@ DIRS = \

FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo

-# These are separate because they need to be included, but putting
-# them as make dependencies would confuse make.
-LINKS = \
- bin \
- etc/s6-linux-init/run-image/opengl-driver \
- etc/s6-linux-init/run-image/service/vmm/template/run \
- lib \
- sbin
-
BUILD_FILES = build/etc/s6-rc

-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(FILES)) $(BUILD_FILES) build/empty build/fifo
+$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(FILES)) $(BUILD_FILES) build/empty build/fifo file-list.mk
( \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf 'image/%s\n%s\n' $$file $$file; done ;\
@@ -128,36 +62,6 @@ build/fifo:
build/empty:
mkdir -p $@

-S6_RC_FILES = \
- etc/s6-rc/card0/type \
- etc/s6-rc/card0/up \
- etc/s6-rc/core/type \
- etc/s6-rc/core/up \
- etc/s6-rc/kvm/timeout-up \
- etc/s6-rc/kvm/type \
- etc/s6-rc/kvm/up \
- etc/s6-rc/mdevd-coldplug/dependencies \
- etc/s6-rc/mdevd-coldplug/type \
- etc/s6-rc/mdevd-coldplug/up \
- etc/s6-rc/mdevd/notification-fd \
- etc/s6-rc/mdevd/run \
- etc/s6-rc/mdevd/type \
- etc/s6-rc/ok-all/contents \
- etc/s6-rc/ok-all/type \
- etc/s6-rc/static-nodes/type \
- etc/s6-rc/static-nodes/up \
- etc/s6-rc/sys-vmms/dependencies \
- etc/s6-rc/sys-vmms/type \
- etc/s6-rc/sys-vmms/up \
- etc/s6-rc/vm-env/contents \
- etc/s6-rc/vm-env/type \
- etc/s6-rc/vmm-env/contents \
- etc/s6-rc/vmm-env/type \
- etc/s6-rc/weston/dependencies \
- etc/s6-rc/weston/notification-fd \
- etc/s6-rc/weston/type \
- etc/s6-rc/weston/run
-
# s6-rc-compile's input is a directory, but that doesn't play nice
# with Make, because it won't know to update if some file in the
# directory is changed, or a file is created or removed in a
@@ -165,7 +69,7 @@ S6_RC_FILES = \
# including files that aren't intended to be part of the input, like
# temporary editor files or .license files. So for all these reasons,
# only explicitly listed files are made available to s6-rc-compile.
-build/etc/s6-rc: $(addprefix image/,$(S6_RC_FILES))
+build/etc/s6-rc: $(addprefix image/,$(S6_RC_FILES)) file-list.mk
mkdir -p $$(dirname $@)
rm -rf $@

@@ -207,6 +111,11 @@ debug:
$(VMLINUX)
.PHONY: debug

+update-file-list:
+ ../../scripts/genfiles.awk image > file-list.mk
+
+.PHONY: update-file-list
+
run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
diff --git a/host/rootfs/file-list.mk b/host/rootfs/file-list.mk
new file mode 100644
index 0000000000000000000000000000000000000000..0817887d0bb25ab47e777f6a130a3b6214b25f0f
--- /dev/null
+++ b/host/rootfs/file-list.mk
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyRightText: Not Copyrightable (machine-written)
+# Generated by scripts/genfile.awk, DO NOT EDIT!
+override FILES ::= \
+ etc/fonts/fonts.conf \
+ etc/fstab \
+ etc/group \
+ etc/init \
+ etc/login \
+ etc/mdev.conf \
+ etc/mdev/listen \
+ etc/mdev/net/add \
+ etc/mdev/wait \
+ etc/parse-devname \
+ etc/passwd \
+ etc/s6-linux-init/env/WAYLAND_DISPLAY \
+ etc/s6-linux-init/env/XDG_RUNTIME_DIR \
+ etc/s6-linux-init/run-image/service/dbus/notification-fd \
+ etc/s6-linux-init/run-image/service/dbus/run \
+ etc/s6-linux-init/run-image/service/dbus/template/notification-fd \
+ etc/s6-linux-init/run-image/service/dbus/template/run \
+ etc/s6-linux-init/run-image/service/getty-tty1/run \
+ etc/s6-linux-init/run-image/service/getty-tty2/run \
+ etc/s6-linux-init/run-image/service/getty-tty3/run \
+ etc/s6-linux-init/run-image/service/getty-tty4/run \
+ etc/s6-linux-init/run-image/service/s6-svscan-log/notification-fd \
+ etc/s6-linux-init/run-image/service/s6-svscan-log/run \
+ etc/s6-linux-init/run-image/service/serial-getty-generator/run \
+ etc/s6-linux-init/run-image/service/serial-getty/notification-fd \
+ etc/s6-linux-init/run-image/service/serial-getty/run \
+ etc/s6-linux-init/run-image/service/serial-getty/template/run \
+ etc/s6-linux-init/run-image/service/vhost-user-fs/notification-fd \
+ etc/s6-linux-init/run-image/service/vhost-user-fs/run \
+ etc/s6-linux-init/run-image/service/vhost-user-fs/template/notification-fd \
+ etc/s6-linux-init/run-image/service/vhost-user-fs/template/run \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/notification-fd \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/run \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/template/data/check \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/template/notification-fd \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/template/run \
+ etc/s6-linux-init/run-image/service/vhost-user-gpu/template/type \
+ etc/s6-linux-init/run-image/service/vmm/notification-fd \
+ etc/s6-linux-init/run-image/service/vmm/run \
+ etc/s6-linux-init/run-image/service/vmm/template/notification-fd \
+ etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/notification-fd \
+ etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/run \
+ etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/notification-fd \
+ etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/run \
+ etc/s6-linux-init/scripts/rc.init \
+ etc/xdg/weston/autolaunch \
+ etc/xdg/weston/weston.ini \
+ usr/bin/assign-devices \
+ usr/bin/create-vm-dependencies \
+ usr/bin/run-appimage \
+ usr/bin/run-vmm \
+ usr/bin/vm-console \
+ usr/bin/vm-import \
+ usr/bin/vm-start \
+ usr/bin/vm-stop \
+ usr/bin/xdg-open \
+ usr/share/dbus-1/services/org.freedesktop.portal.Documents.service
+
+# These are separate because they need to be included, but putting
+# them as make dependencies would confuse make.
+override LINKS ::= \
+ bin \
+ etc/s6-linux-init/run-image/opengl-driver \
+ etc/s6-linux-init/run-image/service/vmm/template/run \
+ lib \
+ sbin
+
+override S6_RC_FILES ::= \
+ etc/s6-rc/card0/type \
+ etc/s6-rc/card0/up \
+ etc/s6-rc/core/type \
+ etc/s6-rc/core/up \
+ etc/s6-rc/kvm/timeout-up \
+ etc/s6-rc/kvm/type \
+ etc/s6-rc/kvm/up \
+ etc/s6-rc/mdevd-coldplug/dependencies \
+ etc/s6-rc/mdevd-coldplug/type \
+ etc/s6-rc/mdevd-coldplug/up \
+ etc/s6-rc/mdevd/notification-fd \
+ etc/s6-rc/mdevd/run \
+ etc/s6-rc/mdevd/type \
+ etc/s6-rc/ok-all/contents \
+ etc/s6-rc/ok-all/type \
+ etc/s6-rc/static-nodes/type \
+ etc/s6-rc/static-nodes/up \
+ etc/s6-rc/sys-vmms/dependencies \
+ etc/s6-rc/sys-vmms/type \
+ etc/s6-rc/sys-vmms/up \
+ etc/s6-rc/vm-env/contents \
+ etc/s6-rc/vm-env/type \
+ etc/s6-rc/vmm-env/contents \
+ etc/s6-rc/vmm-env/type \
+ etc/s6-rc/weston/dependencies \
+ etc/s6-rc/weston/notification-fd \
+ etc/s6-rc/weston/run \
+ etc/s6-rc/weston/type
diff --git a/img/app/Makefile b/img/app/Makefile
index e3bee305339a84ae2cc7f1b6c12c50ff7eafb051..5bb1a6a2f9acd13aba95abb0e918a7f21943b230 100644
--- a/img/app/Makefile
+++ b/img/app/Makefile
@@ -5,6 +5,7 @@
.POSIX:

include ../../lib/common.mk
+include file-list.mk

prefix = build/host
libdir = $(prefix)/lib
@@ -29,44 +30,12 @@ $(imgdir)/appvm/blk/root.img: ../../scripts/make-gpt.sh ../../scripts/sfdisk-fie
build/rootfs.erofs:root:5460386f-2203-4911-8694-91400125c604:root
mv $@.tmp $@

-VM_FILES = \
- etc/dbus-1/session.conf \
- etc/fonts/fonts.conf \
- etc/fstab \
- etc/init \
- etc/mdev.conf \
- etc/mdev/iface \
- etc/mdev/listen \
- etc/mdev/virtiofs \
- etc/mdev/wait \
- etc/passwd \
- etc/pipewire/pipewire.conf \
- etc/resolv.conf \
- etc/s6-linux-init/env/DBUS_SESSION_BUS_ADDRESS \
- etc/s6-linux-init/env/DISPLAY \
- etc/s6-linux-init/env/GTK_USE_PORTAL \
- etc/s6-linux-init/env/NIX_XDG_DESKTOP_PORTAL_DIR \
- etc/s6-linux-init/env/WAYLAND_DISPLAY \
- etc/s6-linux-init/env/XDG_RUNTIME_DIR \
- etc/s6-linux-init/run-image/service/getty-hvc0/run \
- etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/notification-fd \
- etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/run \
- etc/s6-linux-init/scripts/rc.init \
- etc/s6-linux-init/scripts/rc.shutdown \
- etc/s6-linux-init/scripts/rc.shutdown.final \
- etc/wireplumber/wireplumber.conf.d/99_spectrum.conf \
- etc/xdg/xdg-desktop-portal/portals.conf
-
VM_DIRS = dev run proc sys tmp \
etc/s6-linux-init/run-image/service \
etc/s6-linux-init/run-image/user \
etc/s6-linux-init/run-image/wait
VM_FIFOS = etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/fifo

-# These are separate because they need to be included, but putting
-# them as make dependencies would confuse make.
-VM_LINKS = bin etc/ssl/certs/ca-certificates.crt sbin
-
VM_BUILD_FILES = build/etc/s6-rc

build/fifo:
@@ -76,49 +45,21 @@ build/fifo:
build/empty:
mkdir -p $@

-build/rootfs.erofs: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(VM_FILES)) $(VM_BUILD_FILES) build/empty build/fifo
+build/rootfs.erofs: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(FILES)) $(VM_BUILD_FILES) build/empty build/fifo file-list.mk
( \
cat $(PACKAGES_FILE) ;\
- for file in $(VM_FILES) $(VM_LINKS); do printf 'image/%s\n%s\n' $$file $$file; done ;\
+ for file in $(FILES) $(LINKS); do printf 'image/%s\n%s\n' $$file $$file; done ;\
for file in $(VM_BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(VM_DIRS) ;\
printf 'build/fifo\n%s\n' $(VM_FIFOS) ;\
) | ../../scripts/make-erofs.sh $@

-VM_S6_RC_FILES = \
- etc/s6-rc/app/dependencies.d/dbus \
- etc/s6-rc/app/dependencies.d/pipewire \
- etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl \
- etc/s6-rc/app/run \
- etc/s6-rc/app/type \
- etc/s6-rc/dbus/notification-fd \
- etc/s6-rc/dbus/run \
- etc/s6-rc/dbus/type \
- etc/s6-rc/mdevd-coldplug/dependencies \
- etc/s6-rc/mdevd-coldplug/type \
- etc/s6-rc/mdevd-coldplug/up \
- etc/s6-rc/mdevd/notification-fd \
- etc/s6-rc/mdevd/run \
- etc/s6-rc/mdevd/type \
- etc/s6-rc/ok-all/contents \
- etc/s6-rc/ok-all/type \
- etc/s6-rc/pipewire/notification-fd \
- etc/s6-rc/pipewire/run \
- etc/s6-rc/pipewire/type \
- etc/s6-rc/wayland-proxy-virtwl/notification-fd \
- etc/s6-rc/wayland-proxy-virtwl/run \
- etc/s6-rc/wayland-proxy-virtwl/type \
- etc/s6-rc/wireplumber/dependencies.d/dbus \
- etc/s6-rc/wireplumber/dependencies.d/pipewire \
- etc/s6-rc/wireplumber/run \
- etc/s6-rc/wireplumber/type
-
-build/etc/s6-rc: $(addprefix image/,$(VM_S6_RC_FILES))
+build/etc/s6-rc: $(addprefix image/,$(S6_RC_FILES)) file-list.mk
mkdir -p $$(dirname $@)
rm -rf $@

dir=$$(mktemp -d) && \
- tar -C image -c $(VM_S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \
+ tar -C image -c $(S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \
s6-rc-compile $@ $$dir; \
exit=$$?; rm -r $$dir; exit $$exit

@@ -197,6 +138,11 @@ run-crosvm: $(imgdir)/appvm/blk/root.img start-vhost-user-gpu start-virtiofsd
$(KERNEL)
.PHONY: run-crosvm

+update-file-list:
+ ../../scripts/genfiles.awk image > file-list.mk
+
+.PHONY: update-file-list
+
run: run-$(VMM)
.PHONY: run

diff --git a/img/app/file-list.mk b/img/app/file-list.mk
new file mode 100644
index 0000000000000000000000000000000000000000..f689ef55c530dfbe456eef1a9239ca671ddc6f49
--- /dev/null
+++ b/img/app/file-list.mk
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyRightText: Not Copyrightable (machine-written)
+# Generated by scripts/genfile.awk, DO NOT EDIT!
+override FILES ::= \
+ etc/dbus-1/session.conf \
+ etc/fonts/fonts.conf \
+ etc/fstab \
+ etc/init \
+ etc/mdev.conf \
+ etc/mdev/iface \
+ etc/mdev/listen \
+ etc/mdev/virtiofs \
+ etc/mdev/wait \
+ etc/passwd \
+ etc/pipewire/pipewire.conf \
+ etc/resolv.conf \
+ etc/s6-linux-init/env/DBUS_SESSION_BUS_ADDRESS \
+ etc/s6-linux-init/env/DISPLAY \
+ etc/s6-linux-init/env/GTK_USE_PORTAL \
+ etc/s6-linux-init/env/NIX_XDG_DESKTOP_PORTAL_DIR \
+ etc/s6-linux-init/env/WAYLAND_DISPLAY \
+ etc/s6-linux-init/env/XDG_RUNTIME_DIR \
+ etc/s6-linux-init/run-image/service/getty-hvc0/run \
+ etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/notification-fd \
+ etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/run \
+ etc/s6-linux-init/scripts/rc.init \
+ etc/s6-linux-init/scripts/rc.shutdown \
+ etc/s6-linux-init/scripts/rc.shutdown.final \
+ etc/wireplumber/wireplumber.conf.d/99_spectrum.conf \
+ etc/xdg/xdg-desktop-portal/portals.conf
+
+# These are separate because they need to be included, but putting
+# them as make dependencies would confuse make.
+override LINKS ::= \
+ bin \
+ etc/ssl/certs/ca-certificates.crt \
+ sbin
+
+override S6_RC_FILES ::= \
+ etc/s6-rc/app/dependencies.d/dbus \
+ etc/s6-rc/app/dependencies.d/pipewire \
+ etc/s6-rc/app/dependencies.d/wayland-proxy-virtwl \
+ etc/s6-rc/app/run \
+ etc/s6-rc/app/type \
+ etc/s6-rc/dbus/notification-fd \
+ etc/s6-rc/dbus/run \
+ etc/s6-rc/dbus/type \
+ etc/s6-rc/mdevd-coldplug/dependencies \
+ etc/s6-rc/mdevd-coldplug/type \
+ etc/s6-rc/mdevd-coldplug/up \
+ etc/s6-rc/mdevd/notification-fd \
+ etc/s6-rc/mdevd/run \
+ etc/s6-rc/mdevd/type \
+ etc/s6-rc/ok-all/contents \
+ etc/s6-rc/ok-all/type \
+ etc/s6-rc/pipewire/notification-fd \
+ etc/s6-rc/pipewire/run \
+ etc/s6-rc/pipewire/type \
+ etc/s6-rc/wayland-proxy-virtwl/notification-fd \
+ etc/s6-rc/wayland-proxy-virtwl/run \
+ etc/s6-rc/wayland-proxy-virtwl/type \
+ etc/s6-rc/wireplumber/dependencies.d/dbus \
+ etc/s6-rc/wireplumber/dependencies.d/pipewire \
+ etc/s6-rc/wireplumber/run \
+ etc/s6-rc/wireplumber/type
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..0a03ff440cc671264d2b859a2ae048db9252d047 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2021, 2023, 2025 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>

BACKGROUND = background
CPIO = cpio
diff --git a/scripts/genfiles.awk b/scripts/genfiles.awk
new file mode 100755
index 0000000000000000000000000000000000000000..62863e78f157f1d9a0f6dbdb0f4380db9c9d48cb
--- /dev/null
+++ b/scripts/genfiles.awk
@@ -0,0 +1,115 @@
+#!/usr/bin/env -S LC_ALL=C LANGUAGE=C awk -E
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+function check_status(status) {
+ if (status < 0) {
+ printf "FATAL: getline: %s\n", status > "/dev/stderr";
+ exit 1;
+ }
+ return status;
+}
+
+function check_close(value, status) {
+ status = check_status(close(value));
+ if (status != 0) {
+ printf "FATAL: command exited with status %d\n", status > "/dev/stderr";
+ exit status;
+ }
+}
+
+function shell_quote(command) {
+ gsub(/'/, "'\\\\&'", command);
+ return ("'" command "'");
+}
+
+function get(command, line, path, array_index, inode_type, mode, modes, symlink_count, symlinks, file_count, files, rc_count, rc_files, is_license, is_rc) {
+ file_count = 0;
+ symlink_count = 0;
+ rc_count = 0;
+ modes["120000"] = "symlink";
+ modes["040644"] = "directory";
+ modes["040755"] = "directory";
+ modes["100644"] = "regular";
+ modes["100755"] = "regular";
+ print "# SPDX-License-Identifier: CC0-1.0";
+ print "# SPDX-FileCopyRightText: Not Copyrightable (machine-written)";
+ print "# Generated by scripts/genfile.awk, DO NOT EDIT!";
+ while (check_status(command | getline line)) {
+ if (line !~ /^[0-7]{6}\t/) {
+ # this is a git bug
+ print "FATAL: git ls-files output didn't start with a valid mode" > "/dev/stderr";
+ exit 1;
+ }
+ path = substr(line, 8);
+ if (path !~ /^[ -~]+$/) {
+ # also a git bug
+ print "FATAL: git ls-files didn't quote properly" > "/dev/stderr";
+ exit 1;
+ }
+ if (path ~ /^\/|((^|\/)\.{0,2}($|\/))/) {
+ # also a git bug
+ printf "FATAL: git ls-files output non-canonical path '%s'\n", path > "/dev/stderr";
+ exit 1;
+ }
+ if (path !~ /^[[:alnum:]_.+@/-]+$/) {
+ printf "FATAL: filename '%s' has forbidden characters\n", path > "/dev/stderr";
+ exit 1;
+ }
+ mode = modes[substr(line, 1, 6)];
+ is_license = path ~ /\.license$/;
+ is_rc = path ~ /^etc\/s6-rc\//;
+ if (mode == "regular") {
+ if (is_license) {
+ continue;
+ }
+ if (is_rc) {
+ rc_count += 1;
+ rc_files[rc_count] = path;
+ } else {
+ file_count += 1;
+ files[file_count] = path;
+ }
+ continue;
+ }
+ if (mode == "symlink") {
+ if (is_rc) {
+ printf "FATAL: symlink in s6-rc-compile input: %s\n", path;
+ exit 1;
+ }
+ symlink_count += 1;
+ symlinks[symlink_count] = path;
+ } else if (mode != "directory") {
+ printf "FATAL: file %s has unknown mode %s\n", path, substr(line, 1, 6) > "/dev/stderr";
+ exit 1;
+ }
+ if (is_license) {
+ printf "FATAL: %s (type %s) ends in .license\n", path, mode > "/dev/stderr";
+ exit 1;
+ }
+ }
+ check_close(command);
+
+ printf "override FILES ::=";
+ for (array_index = 1; array_index <= file_count; array_index += 1) {
+ printf " \\\n\t%s", files[array_index];
+ }
+ printf ("\n\n" \
+"# These are separate because they need to be included, but putting\n" \
+"# them as make dependencies would confuse make.\n" \
+"override LINKS ::=");
+ for (array_index = 1; array_index <= symlink_count; array_index += 1) {
+ printf " \\\n\t%s", symlinks[array_index];
+ }
+ printf "\n\noverride S6_RC_FILES ::=";
+ for (array_index = 1; array_index <= rc_count; array_index += 1) {
+ printf " \\\n\t%s", rc_files[array_index];
+ }
+ printf "\n"
+}
+
+BEGIN {
+ RS = "\n";
+ FS = "\t";
+ get("set -euo pipefail && { git -c core.quotePath=true -C " shell_quote(ARGV[1]) " ls-files '--format=%(objectmode)\t%(path)' -- .|sort -t '\t' -k 2;}");
+ exit 0;
+}
diff --git a/vm/sys/net/Makefile b/vm/sys/net/Makefile
index e7024fb5011ed9dbf706b9de6083c80e344b24e3..e731bcea7fc61f9b2019689e52a600f3741dd55f 100644
--- a/vm/sys/net/Makefile
+++ b/vm/sys/net/Makefile
@@ -4,6 +4,7 @@
.POSIX:

include ../../../lib/common.mk
+include file-list.mk

prefix = build/host
libdir = $(prefix)/lib
@@ -28,62 +29,25 @@ $(vmdir)/netvm/blk/root.img: ../../../scripts/make-gpt.sh ../../../scripts/sfdis
build/rootfs.erofs:root:ea21da27-0391-48da-9235-9d2ab2ca7844:root
mv $@.tmp $@

-VM_FILES = \
- etc/dbus-1/system.conf \
- etc/fstab \
- etc/init \
- etc/mdev.conf \
- etc/mdev/iface \
- etc/nftables.conf \
- etc/passwd \
- etc/s6-linux-init/run-image/service/getty-hvc0/run \
- etc/s6-linux-init/scripts/rc.init \
- etc/sysctl.conf
-VM_DIRS = dev etc/s6-linux-init/env run proc sys var/lib/connman
-
-# These are separate because they need to be included, but putting
-# them as make dependencies would confuse make.
-VM_LINKS = bin lib sbin var/run
-
VM_BUILD_FILES = build/etc/s6-rc

build/empty:
mkdir -p $@

-build/rootfs.erofs: ../../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(VM_FILES)) $(VM_BUILD_FILES) build/empty
+build/rootfs.erofs: ../../../scripts/make-erofs.sh $(PACKAGES_FILE) $(addprefix image/,$(FILES)) $(VM_BUILD_FILES) build/empty file-list.mk
( \
cat $(PACKAGES_FILE) ;\
- for file in $(VM_FILES) $(VM_LINKS); do printf 'image/%s\n%s\n' $$file $$file; done ;\
+ for file in $(FILES) $(LINKS); do printf 'image/%s\n%s\n' $$file $$file; done ;\
for file in $(VM_BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(VM_DIRS) ;\
) | ../../../scripts/make-erofs.sh $@

-VM_S6_RC_FILES = \
- etc/s6-rc/connman/dependencies \
- etc/s6-rc/connman/run \
- etc/s6-rc/connman/type \
- etc/s6-rc/dbus/notification-fd \
- etc/s6-rc/dbus/run \
- etc/s6-rc/dbus/type \
- etc/s6-rc/mdevd-coldplug/dependencies \
- etc/s6-rc/mdevd-coldplug/type \
- etc/s6-rc/mdevd-coldplug/up \
- etc/s6-rc/mdevd/notification-fd \
- etc/s6-rc/mdevd/run \
- etc/s6-rc/mdevd/type \
- etc/s6-rc/nftables/type \
- etc/s6-rc/nftables/up \
- etc/s6-rc/ok-all/contents \
- etc/s6-rc/ok-all/type \
- etc/s6-rc/sysctl/type \
- etc/s6-rc/sysctl/up
-
-build/etc/s6-rc: $(addprefix image/,$(VM_S6_RC_FILES))
+build/etc/s6-rc: $(addprefix image/,$(S6_RC_FILES)) file-list.mk
mkdir -p $$(dirname $@)
rm -rf $@

dir=$$(mktemp -d) && \
- tar -C image -c $(VM_S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \
+ tar -C image -c $(S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \
s6-rc-compile $@ $$dir; \
exit=$$?; rm -r $$dir; exit $$exit

@@ -138,6 +102,11 @@ run-crosvm: $(vmdir)/netvm/blk/root.img
$(KERNEL)
.PHONY: run-crosvm

+update-file-list:
+ ../../scripts/genfiles.awk image > file-list.mk
+
+.PHONY: update-file-list
+
run: run-$(VMM)
.PHONY: run

diff --git a/vm/sys/net/file-list.mk b/vm/sys/net/file-list.mk
new file mode 100644
index 0000000000000000000000000000000000000000..1614b8e64297fd977fb4c9acdb3205069516dad1
--- /dev/null
+++ b/vm/sys/net/file-list.mk
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyRightText: Not Copyrightable (machine-written)
+# Generated by scripts/genfile.awk, DO NOT EDIT!
+override FILES ::= \
+ etc/dbus-1/system.conf \
+ etc/fstab \
+ etc/init \
+ etc/mdev.conf \
+ etc/mdev/iface \
+ etc/nftables.conf \
+ etc/passwd \
+ etc/s6-linux-init/run-image/service/getty-hvc0/run \
+ etc/s6-linux-init/scripts/rc.init \
+ etc/sysctl.conf
+
+# These are separate because they need to be included, but putting
+# them as make dependencies would confuse make.
+override LINKS ::= \
+ bin \
+ lib \
+ sbin
+
+override S6_RC_FILES ::= \
+ etc/s6-rc/connman/dependencies \
+ etc/s6-rc/connman/run \
+ etc/s6-rc/connman/type \
+ etc/s6-rc/dbus/notification-fd \
+ etc/s6-rc/dbus/run \
+ etc/s6-rc/dbus/type \
+ etc/s6-rc/mdevd-coldplug/dependencies \
+ etc/s6-rc/mdevd-coldplug/type \
+ etc/s6-rc/mdevd-coldplug/up \
+ etc/s6-rc/mdevd/notification-fd \
+ etc/s6-rc/mdevd/run \
+ etc/s6-rc/mdevd/type \
+ etc/s6-rc/nftables/type \
+ etc/s6-rc/nftables/up \
+ etc/s6-rc/ok-all/contents \
+ etc/s6-rc/ok-all/type \
+ etc/s6-rc/sysctl/type \
+ etc/s6-rc/sysctl/up

--
2.51.0