syd 3.12.0

seccomp and landlock based application sandbox with support for namespaces
# syd's Makefile
# Copyright (c) 2023 Ali Polatel <alip@chesswob.org>
# SPDX-License-Identifier: GPL-3.0-or-later

# User variables
# Target, e.g: --target=aarch64-unknown-linux-musl
TARGET=

ARCH=$(shell uname -m)
LIBC=$(shell readlink /lib/ld-linux* | grep -q musl && echo musl || echo gnu)
ALPINE_MMV=3.18
ALPINE_VER=$(ALPINE_MMV).4

# Common tools
RM= rm
FIND= find
RSYNC = rsync
GIT = git
INSTALL= install
PREFIX= /usr/local
BINDIR= bin
MANDIR= share/man
DOCDIR= $(HOME)/src/sydbox.exherbolinux.org
CARGO= cargo
SCDOC= scdoc
MANDOC= mandoc
PKG_CONFIG= pkg-config

# Environment variables necessary to link libseccomp statically.
export LIBSECCOMP_LINK_TYPE= static
export LIBSECCOMP_LIB_PATH= $(shell $(PKG_CONFIG) --variable=libdir libseccomp || echo /usr/lib)

export RUST_BACKTRACE=1

# Cargo flags
CARGOFLAGS= -j$(shell nproc) -v

PROGRAMS= \
	  syd \
	  syd-cat \
	  syd-chk \
	  syd-env \
	  syd-err \
	  syd-exec \
	  syd-ldd \
	  syd-lock \
	  syd-log \
	  syd-ls \
	  syd-mem \
	  syd-norm \
	  syd-read \
	  syd-run \
	  syd-size \
	  syd-stat \
	  syd-sys \
	  syd-test \
	  syd-test-do \
	  syd-tty

# Manual pages
MANS1= \
       man/syd.1 \
       man/syd-cat.1 \
       man/syd-chk.1 \
       man/syd-env.1 \
       man/syd-err.1 \
       man/syd-exec.1 \
       man/syd-ldd.1 \
       man/syd-lock.1 \
       man/syd-log.1 \
       man/syd-ls.1 \
       man/syd-mem.1 \
       man/syd-norm.1 \
       man/syd-read.1 \
       man/syd-run.1 \
       man/syd-size.1 \
       man/syd-stat.1 \
       man/syd-sys.1 \
       man/syd-test.1 \
       man/syd-tty.1
MANS2= \
       man/syd.2
MANS5= \
       man/syd.5
MANS7=

MANS= $(MANS1) $(MANS2) $(MANS5) $(MANS7)

HTMLS= $(patsubst man/%.1,target/man/%.1.html,$(MANS1)) \
       $(patsubst man/%.2,target/man/%.2.html,$(MANS2)) \
       $(patsubst man/%.5,target/man/%.5.html,$(MANS5)) \
       $(patsubst man/%.7,target/man/%.7.html,$(MANS7))

PUTFLAGS= -c $(HOME)/.s3cfg.site
PUTFLAGS_HTML= $(PUTFLAGS) \
	       --no-guess-mime-type \
	       --default-mime-type=text/html

all: build

man: $(MANS)

build:
	@echo Using libseccomp library from $(LIBSECCOMP_LIB_PATH)
	$(CARGO) +nightly acl -n
	$(CARGO) deny check
	$(CARGO) +nightly clippy $(CARGOFLAGS)
	$(CARGO) build --locked --features log,uring $(CARGOFLAGS)
	$(CARGO) test
build32:
	env \
		LIBSECCOMP_LINK_TYPE=static \
		LIBSECCOMP_LIB_PATH=/usr/i686-linux-gnu/lib \
		LD_LIBRARY_PATH=/usr/i686-linux-gnu/lib \
		RUSTFLAGS="-Ctarget-feature=+crt-static" \
		$(CARGO) build \
			--target=i686-unknown-linux-gnu \
			--release --features log,uring $(CARGOFLAGS)
install32: build32
	$(INSTALL) -d $(DESTDIR)$(PREFIX)/$(BINDIR)/
	for program in $(PROGRAMS); do \
		$(INSTALL) -pm 0755 target/i686-unknown-linux-gnu/release/$$program $(DESTDIR)$(PREFIX)/$(BINDIR)/$$program"32"; \
	done
install: release
	$(INSTALL) -d $(DESTDIR)$(PREFIX)/$(BINDIR)/
	for program in $(PROGRAMS); do \
		$(INSTALL) -pm 0755 target/release/$$program $(DESTDIR)$(PREFIX)/$(BINDIR)/; \
	done
	$(MAKE) install-man
debug:
	$(CARGO) build --locked --features log,uring $(CARGOFLAGS)
	$(INSTALL) -d $(DESTDIR)$(PREFIX)/$(BINDIR)/
	for program in $(PROGRAMS); do \
		$(INSTALL) -pm 0755 target/debug/$$program $(DESTDIR)$(PREFIX)/$(BINDIR)/; \
	done
	$(MAKE) install-man
install-man: $(MANS)
	for man in $(MANS1); do \
		$(INSTALL) -pm 0644 $$man $(DESTDIR)$(PREFIX)/$(MANDIR)/man1/; \
	done
	for man in $(MANS2); do \
		$(INSTALL) -pm 0644 $$man $(DESTDIR)$(PREFIX)/$(MANDIR)/man2/; \
	done
	for man in $(MANS5); do \
		$(INSTALL) -pm 0644 $$man $(DESTDIR)$(PREFIX)/$(MANDIR)/man5/; \
	done
	for man in $(MANS7); do \
		$(INSTALL) -pm 0644 $$man $(DESTDIR)$(PREFIX)/$(MANDIR)/man7/; \
	done
uninstall:
	for program in $(PROGRAMS); do \
		$(RM) -f $(DESTDIR)$(PREFIX)/$(BINDIR)/$$program; \
	done
	for man in $(MANS1); do \
		$(RM) -f $(DESTDIR)$(PREFIX)/$(MANDIR)/man1/$$man; \
	done
	for man in $(MANS2); do \
		$(RM) -f $(DESTDIR)$(PREFIX)/$(MANDIR)/man2/$$man; \
	done
	for man in $(MANS5); do \
		$(RM) -f $(DESTDIR)$(PREFIX)/$(MANDIR)/man5/$$man; \
	done
	for man in $(MANS7); do \
		$(RM) -f $(DESTDIR)$(PREFIX)/$(MANDIR)/man7/$$man; \
	done
release:
	@echo Using libseccomp library from $(LIBSECCOMP_LIB_PATH)
	$(CARGO) build --release --locked --features uring $(CARGOFLAGS) $(TARGET)
check:
	$(CARGO) test $(CARGOFLAGS)
distcheck:
	$(CARGO) test --release $(CARGOFLAGS)
doc:
	$(CARGO) doc --open
fmt:
	$(CARGO) +nightly fmt
	$(MAKE) -C lib fmt
dist:
	./dev/release.sh
publish:
	$(CARGO) publish
upload:
	rm -rf target/man
	mkdir -m700 -p target/man
	$(MAKE) -j $(HTMLS)
	echo "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>Man Pages Index</title></head><body><h1>man.exherbolinux.org</h1>" > target/man/index.html
	@for man in target/man/*.*.html; do \
		filename=$${man##*/} ;\
		basename=$${filename%.html}; \
		echo "<a href=\"$$filename\">$$basename</a><br>" ;\
	done | sort >> target/man/index.html
	echo "</body></html>" >> target/man/index.html
	s3cmd put $(PUTFLAGS_HTML) -P target/man/*.html s3://man.exherbolinux.org/

# Library
lib:
	$(MAKE) -C lib all
checklib:
	$(MAKE) -C lib check

# Fuzzing
fuzz:
	$(MAKE) -C fuzz all
fuzz_conf:
	$(MAKE) -C fuzz $@
fuzz_path:
	$(MAKE) -C fuzz $@

# Use LLVM sanitizers
sanitize_address:
	env RUSTFLAGS="-Zsanitizer=address -Ctarget-feature=-crt-static" $(CARGO) +nightly build $(CARGOFLAGS) -Zbuild-std --target $(ARCH)-unknown-linux-$(LIBC)
sanitize_leak:
	env RUSTFLAGS="-Zsanitizer=leak -Ctarget-feature=-crt-static" $(CARGO) +nightly build $(CARGOFLAGS) -Zbuild-std --target $(ARCH)-unknown-linux-$(LIBC)
sanitize_memory:
	env RUSTFLAGS="-Zsanitizer=memory -Ctarget-feature=-crt-static" $(CARGO) +nightly build $(CARGOFLAGS) -Zbuild-std --target $(ARCH)-unknown-linux-$(LIBC)
sanitize_thread:
	env RUSTFLAGS="-Zsanitizer=thread -Ctarget-feature=-crt-static" $(CARGO) +nightly build $(CARGOFLAGS) -Zbuild-std --target $(ARCH)-unknown-linux-$(LIBC)

bench:
	$(CARGO) bench $(CARGOFLAGS)
bloat:
	$(CARGO) bloat --crates -n 100 --bin syd --profile release
cov:
	$(CARGO) llvm-cov --open
deny:
	$(CARGO) deny check
msrv:
	$(CARGO) msrv --bisect
watch:
	$(CARGO) watch
who:
	@git log --all --format='%cN <%cE>' | sort -u

root: alpine-rootfs.tar.gz
	mkdir -p -m700 $@
	doas tar -C root -xpf alpine-rootfs.tar.gz
	./dev/hut-get.sh
	doas cp dist/syd root/bin
	doas cp dist/syd-test root/bin
	doas cp dist/syd-test-do root/bin
	doas chmod +x root/init
	doas chmod +x root/bin/syd
	doas chmod +x root/bin/syd-test
	doas chmod +x root/bin/syd-test-do
chroot:
	./dev/chroot.sh
alpine-rootfs.tar.gz:
	wget -cO$@ https://dl-cdn.alpinelinux.org/alpine/v$(ALPINE_MMV)/releases/$(ARCH)/alpine-minirootfs-$(ALPINE_VER)-$(ARCH).tar.gz
clean:
	-doas rm -rf root

%.1: %.1.scd
	$(SCDOC) < $< > $@
%.2: %.2.scd
	$(SCDOC) < $< > $@
%.5: %.5.scd
	$(SCDOC) < $< > $@
%.7: %.7.scd
	$(SCDOC) < $< > $@

# Pattern rule for man page to HTML conversion
target/man/%.html: man/%
	$(MANDOC) -Thtml $< > $@

.PHONY: check dist distcheck clean debug doc fmt man install-man publish upload watch who
.PHONY: all bench bloat build build32 cov deny msrv native release install install32 uninstall
.PHONY: sanitize_address sanitize_leak sanitize_memory sanitize_thread
.PHONY: chroot fuzz
.PHONY: lib checklib