aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: b20a84266185783d3aab204b843a2dc4e4e721b1 (plain) (blame)
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