#!/usr/bin/make -f

include /usr/share/dpkg/architecture.mk
include /usr/share/dpkg/pkg-info.mk

export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export VERBOSE = 1
export PYBUILD_NAME = minijail
# setup.py only; build it through the PEP 517 path rather than the deprecated
# distutils plugin.
export PYBUILD_SYSTEM = pyproject

LIBDIR = /usr/lib/$(DEB_HOST_MULTIARCH)
# libminijailpreload.so is LD_PRELOADed by minijail0 rather than linked
# against, and upstream gives it no SONAME, so it must stay out of the
# public library directory or lintian errors. Upstream's LIBDIR only sets
# the preload path compiled into minijail0, nothing else.
PRELOADDIR = $(LIBDIR)/minijail
# Not ./build, which setuptools uses for the Python part.
BUILDDIR = $(CURDIR)/debian/build

# The Rust crates under rust/ are not on crates.io; they are shipped as
# Debian Rust source packages so that crosvm can build against them.
REGISTRY = debian/tmp/usr/share/cargo/registry
crate_version = $(shell sed -n 's/^version = "\(.*\)"/\1/p' rust/$(1)/Cargo.toml)
MINIJAIL_SYS_VERSION := $(call crate_version,minijail-sys)
MINIJAIL_VERSION := $(call crate_version,minijail)

# Virtual package names in the form debcargo generates, so that the usual
# librust-<crate>-<semver>+default-dev Build-Depends work. As the Rust
# packaging policy requires, they are versioned with the crate version, not
# the minijail package version, so that versioned dependencies on them
# (e.g. "<< 0.0.15~~") compare against the crate.
#   $(1) = crate name, $(2) = crate version
rust_provides = $(shell v=$(2); n=librust-$(1); out=; \
	for s in "" "-$${v%%.*}" "-$${v%.*}" "-$$v"; do \
		if [ -n "$$s" ]; then out="$$out$$n$$s-dev (= $$v), "; fi; \
		out="$$out$$n$$s+default-dev (= $$v), "; \
	done; echo "$${out%, }")

%:
	dh $@

override_dh_auto_build-arch:
	dh_auto_build -- OUT=$(BUILDDIR)/ LIBDIR=$(PRELOADDIR) VERBOSE=1
	sed -e 's|@BSLOT@|$(DEB_VERSION_UPSTREAM)|' \
	    -e 's|@INCLUDE_DIR@|/usr/include/minijail|' \
	    libminijail.pc.in > $(BUILDDIR)/libminijail.pc

override_dh_auto_build-indep:
	dh_auto_build --buildsystem=pybuild
	# Manual pages from --help. Run each tool from tools/ through a wrapper
	# named like the installed command, so argparse prints that name.
	mkdir -p $(BUILDDIR)/bin $(BUILDDIR)/man
	set -e; for t in compile_seccomp_policy:"compile a minijail seccomp policy to BPF" \
	        generate_seccomp_policy:"generate a minijail seccomp policy from strace or audit logs" \
	        generate_constants_json:"generate minijail syscall and constant tables"; do \
		n=$${t%%:*}; w=$(BUILDDIR)/bin/$$n; \
		printf '#!/bin/sh\nexec python3 -c "import sys; sys.path.insert(0, \\"%s\\"); sys.argv[0] = \\"%s\\"; import %s; sys.exit(%s.main())" "$$@"\n' \
			"$(CURDIR)/tools" "$$n" "$$n" "$$n" > $$w; \
		chmod +x $$w; \
		help2man --no-info --no-discard-stderr \
			--version-string='$(DEB_VERSION_UPSTREAM)' \
			--name="$${t#*:}" --output=$(BUILDDIR)/man/$$n.1 $$w; \
	done

override_dh_auto_install-arch:
	install -D -m0755 $(BUILDDIR)/minijail0 \
		debian/tmp/usr/bin/minijail0
	install -D -m0644 $(BUILDDIR)/libminijail.so \
		debian/tmp$(LIBDIR)/libminijail.so.1
	ln -sf libminijail.so.1 debian/tmp$(LIBDIR)/libminijail.so
	install -D -m0644 $(BUILDDIR)/libminijailpreload.so \
		debian/tmp$(PRELOADDIR)/libminijailpreload.so
	install -D -m0644 libminijail.h \
		debian/tmp/usr/include/minijail/libminijail.h
	install -D -m0644 scoped_minijail.h \
		debian/tmp/usr/include/minijail/scoped_minijail.h
	install -D -m0644 $(BUILDDIR)/libminijail.pc \
		debian/tmp$(LIBDIR)/pkgconfig/libminijail.pc
	# Rust crates, laid out as in a cargo directory registry.
	set -e; d=$(REGISTRY)/minijail-sys-$(MINIJAIL_SYS_VERSION); \
	install -D -m0644 -t $$d rust/minijail-sys/Cargo.toml \
		rust/minijail-sys/build.rs rust/minijail-sys/lib.rs; \
	echo '{"package":null,"files":{}}' > $$d/.cargo-checksum.json
	set -e; d=$(REGISTRY)/minijail-$(MINIJAIL_VERSION); \
	install -D -m0644 -t $$d rust/minijail/Cargo.toml; \
	install -D -m0644 -t $$d/src rust/minijail/src/lib.rs \
		rust/minijail/src/test_filter.policy; \
	install -D -m0644 -t $$d/tests rust/minijail/tests/fork_remap.rs; \
	echo '{"package":null,"files":{}}' > $$d/.cargo-checksum.json

override_dh_auto_install-indep:
	# pybuild installs straight into debian/python3-minijail (PYBUILD_NAME).
	dh_auto_install --buildsystem=pybuild
	# The unit tests need tools/testdata, which is not installed.
	rm -f debian/python3-minijail/usr/lib/python3*/dist-packages/minijail/*_unittest.py

override_dh_gencontrol:
	echo 'rust:Provides=$(call rust_provides,minijail-sys,$(MINIJAIL_SYS_VERSION))' \
		>> debian/librust-minijail-sys-dev.substvars
	echo 'rust:Provides=$(call rust_provides,minijail,$(MINIJAIL_VERSION))' \
		>> debian/librust-minijail-dev.substvars
	dh_gencontrol

override_dh_auto_clean:
	rm -rf $(BUILDDIR) .pybuild build *.egg-info
	find tools -name __pycache__ -prune -exec rm -rf {} +

# The upstream C test suite enters namespaces and installs seccomp filters,
# which does not work in a build chroot.
override_dh_auto_test-arch:

# The Python tools' unit tests are self-contained.
override_dh_auto_test-indep:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	cd tools && python3 -m unittest -v parser_unittest compiler_unittest \
		seccomp_policy_lint_unittest
endif
