SHELL := /bin/sh
CC ?= cc
undefine FC
FC ?= gfortran
CFLAGS ?= -O2 -g -std=c17 -Wall -Wextra -Werror -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3
FFLAGS ?= -O2 -g -std=f2018 -Wall -Wextra -Werror -fimplicit-none
LDLIBS ?= -lssl -lcrypto
PREFIX ?= /usr
SBINDIR ?= $(PREFIX)/sbin
LIBDIR ?= $(PREFIX)/lib
LIBEXECDIR ?= $(PREFIX)/lib/systemd
RUSTD_LIBEXECDIR ?= $(PREFIX)/lib/rustd
UNITDIR ?= $(PREFIX)/lib/systemd/system
TMPFILESDIR ?= $(PREFIX)/lib/tmpfiles.d
SYSUSERSDIR ?= $(PREFIX)/lib/sysusers.d
DBUSSERVICEDIR ?= $(PREFIX)/share/dbus-1/system-services
DBUSPOLICYDIR ?= $(PREFIX)/share/dbus-1/system.d
POLKITDIR ?= $(PREFIX)/share/polkit-1/actions
.PHONY: all build test check-native check-rust check-formal check-packaging check-live check-nss clean install
.PHONY: supremacy-dirs nss release release-with-nss install-replace uninstall boot-smoke bench
all: build
build:
cargo build --release --locked
check-native:
mkdir -p build
$(FC) $(FFLAGS) -Jbuild -c ffi/routing.f90 -o build/routing.o
$(CC) $(CFLAGS) -Iffi -c ffi/native.c -o build/native.o
$(CC) $(CFLAGS) -Iffi -c ffi/interface.c -o build/interface.o
$(CC) $(CFLAGS) -Iffi -c ffi/tls.c -o build/tls.o
$(CC) $(CFLAGS) -Iffi -c ffi/dnssec.c -o build/dnssec.o
$(CC) $(CFLAGS) -Iffi -c ffi/netlink.c -o build/netlink.o
$(CC) $(CFLAGS) -Iffi -c ffi/networkd.c -o build/networkd.o
$(CC) $(CFLAGS) -Iffi -c ffi/mdns.c -o build/mdns.o
$(CC) $(CFLAGS) -Iffi -c ffi/test_native.c -o build/test_native.o
$(CC) $(CFLAGS) -Iffi -c ffi/test_mdns.c -o build/test_mdns.o
$(FC) build/test_native.o build/native.o build/interface.o build/tls.o build/dnssec.o build/netlink.o build/networkd.o build/mdns.o build/routing.o $(LDLIBS) -o build/test_native
./build/test_native
$(CC) build/test_mdns.o build/mdns.o -o build/test_mdns
./build/test_mdns
check-rust:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features --locked -- -D warnings
cargo test --all-targets --all-features --locked
check-formal:
idris2 --build formal/idris/resolved-policy.ipkg
agda -i formal/agda formal/agda/Resolved/DNS/Name.agda
agda -i formal/agda formal/agda/Resolved/DNS/Transaction.agda
check-packaging:
bash -n scripts/install-replace.sh scripts/uninstall-restore.sh scripts/boot-smoke.sh \
scripts/run-upstream-test-75.sh scripts/certify-replacement-v2.sh \
scripts/run-boot-replacement-vm.sh scripts/check-rustd-naming.sh \
scripts/switch-resolved-transactionally-v2.sh scripts/test-package-lifecycle.sh \
nss/run-tests.sh \
tests/parity/llmnr_avahi_interop.sh \
tests/parity/dnssec_ad_bit.sh \
tests/parity/dbus_manager_methods.sh \
tests/parity/run_all.sh \
tests/direct-root-privilege-drop.sh \
tests/release_feature_boundary.sh \
tests/ops_runtime_contract.sh \
scripts/certify-replacement.sh scripts/certify-replacement-v2.sh
@set -eu; \
work=$$(mktemp -d); \
trap 'rm -rf "$$work"' EXIT HUP INT TERM; \
PYTHONPYCACHEPREFIX="$$work/pycache" python3 -m py_compile \
tests/live-dns.py tests/deterministic-dns-server.py tests/fake-varlink-resolve.py \
tests/live-llmnr.py \
tests/check-varlink-authorization.py \
tests/check-dnssd-preauthorization.py \
tests/fake-polkit.py \
tests/test-readiness-bundle.py \
tests/test-replacement-proof-validator.py \
tests/test-upstream-surface-audit.py \
scripts/audit-upstream-resolver-surfaces.py scripts/check-workflow-fleet.py \
scripts/download-replacement-proofs.py scripts/import-replacement-proof.py \
scripts/validate-replacement-proof.py scripts/verify-readiness-bundle.py \
scripts/probe-stub.py; \
PYTHONPYCACHEPREFIX="$$work/pycache" python3 tests/test-upstream-surface-audit.py; \
PYTHONPYCACHEPREFIX="$$work/pycache" python3 tests/test-readiness-bundle.py; \
PYTHONPYCACHEPREFIX="$$work/pycache" python3 tests/test-replacement-proof-validator.py; \
python3 scripts/check-workflow-fleet.py; \
./scripts/check-rustd-naming.sh; \
./tests/release_feature_boundary.sh; \
./tests/ops_runtime_contract.sh; \
./scripts/test-package-lifecycle.sh; \
varlinkctl validate-idl interfaces/io.systemd.Resolve.varlink >"$$work/resolve.varlink"; \
varlinkctl validate-idl interfaces/io.systemd.Resolve.Monitor.varlink >"$$work/resolve-monitor.varlink"; \
: "Validate exact v261 generic IDLs through a comment-free form for older varlinkctl"; \
for interface in io.systemd io.systemd.service org.varlink.service; do \
sed '/^[[:space:]]*#/d' "interfaces/$$interface.varlink" >"$$work/$$interface.semantic.varlink"; \
varlinkctl validate-idl "$$work/$$interface.semantic.varlink" >"$$work/$$interface.varlink"; \
done; \
python3 -c 'import pathlib, xml.etree.ElementTree as ET; [ET.parse(path) for path in pathlib.Path("compat").glob("*.xml")]'; \
cargo metadata --no-deps --format-version 1 >"$$work/cargo-metadata.json"; \
python3 -c 'import json, sys; data = json.load(open(sys.argv[1], encoding="utf-8")); package = next(package for package in data["packages"] if package["name"] == "rustd-resolved"); bins = sorted(target["name"] for target in package["targets"] if "bin" in target["kind"]); expected = ["resolvectl", "rustd-resolvectl", "rustd-resolved", "systemd-resolved"]; assert bins == expected, f"unexpected Cargo binary targets: {bins}"; default = set(package["features"]["default"]); expected_default = {"fortran-routing", "idna-name"}; assert default == expected_default, f"unexpected production default features: {sorted(default)}"' "$$work/cargo-metadata.json"; \
test "$$(grep -Fc 'ExecStart=@RUSTD_RESOLVED@' packaging/systemd/systemd-resolved-replacement.service)" -eq 1; \
mkdir -p "$$work/rustd" "$$work/systemd"; \
sed 's|ExecStart=/usr/lib/rustd/rustd-resolved|ExecStart=/bin/true|g' \
packaging/systemd/rustd-resolved.service >"$$work/rustd/rustd-resolved.service"; \
cp packaging/systemd/rustd-resolved-varlink.socket "$$work/rustd/rustd-resolved-varlink.socket"; \
cp packaging/systemd/rustd-resolved-monitor.socket "$$work/rustd/rustd-resolved-monitor.socket"; \
sed 's|@RUSTD_RESOLVED@|/bin/true|g' \
SYSTEMD_UNIT_PATH="$$work/rustd" systemd-analyze verify \
"$$work/rustd/rustd-resolved.service" \
"$$work/rustd/rustd-resolved-monitor.socket" \
"$$work/rustd/rustd-resolved-varlink.socket"; \
SYSTEMD_UNIT_PATH="$$work/systemd" systemd-analyze verify \
check-live: build
python3 tests/live-dns.py target/release/systemd-resolved target/release/resolvectl
python3 tests/live-dns.py target/release/rustd-resolved target/release/rustd-resolvectl
check-nss:
$(MAKE) -C nss clean check
test: check-native check-rust check-packaging check-nss
install: build nss
install -Dm0755 target/release/rustd-resolved $(DESTDIR)$(RUSTD_LIBEXECDIR)/rustd-resolved
install -Dm0755 target/release/rustd-resolvectl $(DESTDIR)$(PREFIX)/bin/rustd-resolvectl
install -Dm0755 nss/libnss_rustd.so.2 $(DESTDIR)$(LIBDIR)/libnss_rustd.so.2
install -d -m0755 $(DESTDIR)$(LIBEXECDIR)
ln -sfn ../rustd/rustd-resolved $(DESTDIR)$(LIBEXECDIR)/rustd-resolved
install -Dm0644 packaging/systemd/rustd-resolved.service $(DESTDIR)$(UNITDIR)/rustd-resolved.service
install -Dm0644 packaging/systemd/rustd-resolved-varlink.socket $(DESTDIR)$(UNITDIR)/rustd-resolved-varlink.socket
install -Dm0644 packaging/systemd/rustd-resolved-monitor.socket $(DESTDIR)$(UNITDIR)/rustd-resolved-monitor.socket
install -Dm0644 packaging/tmpfiles/rustd-resolved.conf $(DESTDIR)$(TMPFILESDIR)/rustd-resolved.conf
install -Dm0644 packaging/sysusers/rustd-resolve.conf $(DESTDIR)$(SYSUSERSDIR)/rustd-resolve.conf
install -Dm0644 packaging/dbus/org.rustd.resolve1.service $(DESTDIR)$(DBUSSERVICEDIR)/org.rustd.resolve1.service
install -Dm0644 packaging/dbus/org.rustd.resolve1.conf $(DESTDIR)$(DBUSPOLICYDIR)/org.rustd.resolve1.conf
install -Dm0644 packaging/polkit/org.rustd.resolve1.policy $(DESTDIR)$(POLKITDIR)/org.rustd.resolve1.policy
clean:
rm -rf build target
$(MAKE) -C nss clean
supremacy-dirs:
mkdir -p src/supremacy src/llmnr src/mdns nss scripts tests/parity tests/supremacy
mkdir -p packaging/polkit packaging/rpm
nss:
$(MAKE) -C nss
release: build check-packaging check-nss
release-with-nss: release
install-replace: release
sudo bash scripts/install-replace.sh
uninstall:
sudo bash scripts/uninstall-restore.sh
boot-smoke:
bash scripts/boot-smoke.sh
bench:
bash tests/supremacy/bench_compare.sh