# Top-level package build for Cryptech Alpha board.
# What we call the package before we start mucking with branches and revision numbers
PACKAGE_BASE_NAME := cryptech-alpha
PACKAGE_BASE_VERSION := 3.1
# Git voodoo: plumbing commands to pull the current branch and list of
# all (local) branches, and to pull something we can use as a version
# number suffix.
#
# Using a timestamp here is not particularly friendly, but we're
# looking for something simple that all the packaging systems involved
# are willing to accept as a version number, so, at least for now, we
# avoid more interesting options such as git-describe.
GIT_VERSION := $(shell git show -s --format=%ct HEAD)
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
GIT_BRANCHES := $(filter-out HEAD,$(sort $(notdir $(shell git for-each-ref --format '%(refname)' refs/heads/ refs/remotes/))))
# Make voodoo: construct the package name, version number, and list of
# other package names (constructed on other branches) with which this
# one conflicts.
PACKAGE_BRANCH = ${PACKAGE_BASE_NAME}$(and $(filter-out master,$(1)),-$(subst _,-,$(1)))
PACKAGE_NAME := $(call PACKAGE_BRANCH,${GIT_BRANCH})
PACKAGE_CONFLICT := $(foreach I,$(filter-out ${GIT_BRANCH},${GIT_BRANCHES}),$(call PACKAGE_BRANCH,${I}))
PACKAGE_VERSION := ${PACKAGE_BASE_VERSION}.${GIT_VERSION}
# gpg setup, for signing packages and repositories
export GNUPGHOME := /home/aptbot/gnupg
GPG_USER := APT Builder Robot <aptbot@cryptech.is>
GPG_KEYID := 37A8E93F5D7E7B9A
# Package repository setup
REPO_BASE := /home/aptbot
REPO_UMASK := 002
# Debian clean-room package builder setup
PBUILDER_BASE := ${HOME}/pbuilder
PBUILDER_TARGETS := $(foreach D,debian/stretch debian/buster,${D}/i386 ${D}/amd64 ${D}/armhf) \
$(foreach D,ubuntu/xenial ubuntu/bionic,${D}/i386 ${D}/amd64)
# Where we upload the final results (if we do)
REPO_UPLOAD_USER := aptbot
REPO_UPLOAD_HOST := bikeshed.cryptech.is
REPO_UPLOAD_DIRS := apt brew
# Yes, we really are putting the firmware tarball into the source package.
# We want to supply the firmware in both source and binary form, to save users
# the trouble of all the cross compilation and Verilog synthesis, and the Alpha
# firmware is the same regardless of the host platform, so including the firmware
# tarball in the source package lets us simplify installation for the user.
FIRMWARE_TARBALL := source/cryptech-alpha-firmware.tar.gz
BITSTREAM := build/core/platform/alpha/build/alpha_fmc.bit
ELVES := build/sw/stm32/projects/bootloader/bootloader.elf build/sw/stm32/projects/hsm/hsm.elf
TAMPER := build/sw/tamper/tamper.hex
all: init firmware dsc pbuilder homebrew expire
enchilada: all upload
init:
git submodule update --init --recursive
tidy:
rm -rf tap
git clean -dfx -e build -e .pbuilder-sell-by-date
git submodule foreach --recursive git clean -dfx
clean: tidy
git clean -dfx
sandblast: clean
git submodule deinit -f .
firmware: shadow ${FIRMWARE_TARBALL}
shadow:
./scripts/build-shadow-tree.py
${FIRMWARE_TARBALL}: ${BITSTREAM} $(sort ${ELVES} ${ELVES:.elf=.bin}) ${TAMPER}
fakeroot ./scripts/build-firmware-package.py $@ $^
bitstream: ${BITSTREAM}
${BITSTREAM}: $(shell find source/core -name .git -prune -o -type f -print)
${MAKE} -C build/core/platform/alpha/build
${ELVES:.elf=.bin}: shadow elves
elves:
${MAKE} -C build/sw/stm32 distclean bootloader hsm
${TAMPER}: tamper
tamper:
${MAKE} -C $(dir ${TAMPER})
# For extra credit, figure out how to put the right path names into
# the initial source tarball so we don't need to mess with it in the loop.
#
# For more extra credit, figure out how to do the pbuilder stuff as
# GNU make $(eval) rules rather than as a shell for loop. Maybe.
dsc:
rm -f source/debian/changelog ${PACKAGE_NAME}_*.dsc ${PACKAGE_NAME}_*.tar.xz ${PACKAGE_NAME}_*_source.build ${PACKAGE_NAME}_*_source.changes
cd source; ../scripts/build-debian-control-files.py --debemail='${GPG_USER}' --package='${PACKAGE_NAME}' --newversion='${PACKAGE_VERSION}' --conflicts='${PACKAGE_CONFLICT}'
cd source; debuild -S -uc -us
pbuilder:
rm -f ${PBUILDER_BASE}/*result/*
touch -d 'last week' .pbuilder-sell-by-date
set -x; umask ${REPO_UMASK}; \
for target in ${PBUILDER_TARGETS}; do echo $$target | tr '/' ' '; done | \
while read dist code arch; do \
reprepro -b ${REPO_BASE}/apt/$$dist -A $$arch list $$code ${PACKAGE_NAME} | awk -v "c=$$code" '{v = $$3} END {exit v != "${PACKAGE_VERSION}~" c}' && continue; \
if test $${HOME}/pbuilder/$${code}-$${arch}-base.tgz -ot .pbuilder-sell-by-date; then pbuilder-dist $$code $$arch update; else true; fi; \
pbuilder-dist $$code $$arch build ${PACKAGE_NAME}_${PACKAGE_VERSION}.dsc; \
test -f ${REPO_BASE}/brew/tarballs/${PACKAGE_NAME}_${PACKAGE_VERSION}.tar.xz || \
cp -p ${PBUILDER_BASE}/$${code}-$${arch}_result/${PACKAGE_NAME}_${PACKAGE_VERSION}.tar.xz ${REPO_BASE}/brew/tarballs/; \
reprepro -b ${REPO_BASE}/apt/$$dist -T dsc list $$code ${PACKAGE_NAME} | awk '{v = $$3} END {exit v != "${PACKAGE_VERSION}"}' || \
reprepro -b ${REPO_BASE}/apt/$$dist includedsc $$code ${PBUILDER_BASE}/$${code}-$${arch}_result/${PACKAGE_NAME}_${PACKAGE_VERSION}.dsc; \
reprepro -b ${REPO_BASE}/apt/$$dist includedeb $$code ${PBUILDER_BASE}/$${code}-$${arch}_result/${PACKAGE_NAME}_${PACKAGE_VERSION}~$${code}_$${arch}.deb; \
done
homebrew:
rm -rf tap
umask ${REPO_UMASK}; \
git clone ${REPO_BASE}/brew/tap tap; \
cd tap; \
../scripts/build-homebrew-formula.py --tarball='${REPO_BASE}/brew/tarballs/${PACKAGE_NAME}_${PACKAGE_VERSION}.tar.xz' --formula='${PACKAGE_NAME}.rb' \
--package='${PACKAGE_NAME}' --version='${PACKAGE_VERSION}' --conflicts='${PACKAGE_CONFLICT}'; \
git add ${PACKAGE_NAME}.rb; \
git commit -S${GPG_KEYID} --author='${GPG_USER}' -m '${PACKAGE_NAME} ${PACKAGE_VERSION}'; \
git push
# rm -rf tap
expire:
find ${REPO_BASE}/brew/tarballs \
-name '${PACKAGE_NAME}_*.tar.xz' \
! -name '${PACKAGE_NAME}_${PACKAGE_VERSION}.tar.xz' \
-mtime +7 -ls -delete
RSYNC := rsync --rsh 'ssh -l ${REPO_UPLOAD_USER}' --archive --itemize-changes
upload:
for dir in ${REPO_UPLOAD_DIRS}; do \
${RSYNC} --ignore-existing ${REPO_BASE}/$${dir}/ rsync://${REPO_UPLOAD_HOST}/$${dir}/; \
${RSYNC} --delete --delete-delay ${REPO_BASE}/$${dir}/ rsync://${REPO_UPLOAD_HOST}/$${dir}/; \
done
bother:
for dir in ${REPO_UPLOAD_DIRS}; do \
${RSYNC} --delete rsync://${REPO_UPLOAD_HOST}/$${dir}/ ${REPO_BASE}/$${dir}/; \
done
happy:
git pull
git submodule update --remote
.PHONY: all init tidy clean firmware shadow bitstream elves tamper dsc pbuilder homebrew expire upload enchilada sandblast happy bother