1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
# 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 := 4.0
# 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 := \
$(addsuffix /amd64, debian/stretch debian/buster ubuntu/xenial ubuntu/bionic ubuntu/focal) \
$(addsuffix /i386, debian/stretch debian/buster ubuntu/xenial ubuntu/bionic) \
$(addsuffix /armhf, debian/stretch debian/buster)
# 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}
rm -f $@
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
|