-
Notifications
You must be signed in to change notification settings - Fork 71
/
Makefile
173 lines (144 loc) · 5.36 KB
/
Makefile
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
171
172
173
# Shortcut targets
default: image
## Build binary for current platform
all: image-all
###############################################################################
# Both native and cross architecture builds are supported.
# The target architecture is select by setting the ARCH variable.
# When ARCH is undefined it is set to the detected host architecture.
# When ARCH differs from the host architecture a crossbuild will be performed.
###############################################################################
ARCHES = amd64 arm64 ppc64le s390x
# BUILDARCH is the host architecture
# ARCH is the target architecture
# we need to keep track of them separately
BUILDARCH ?= $(shell uname -m)
# canonicalized names for host architecture
ifeq ($(BUILDARCH),aarch64)
BUILDARCH=arm64
endif
ifeq ($(BUILDARCH),x86_64)
BUILDARCH=amd64
endif
# unless otherwise set, I am building for my own architecture, i.e. not cross-compiling
ARCH ?= $(BUILDARCH)
# canonicalized names for target architecture
ifeq ($(ARCH),x86_64)
override ARCH=amd64
else ifeq ($(ARCH),aarch64)
override ARCH=arm64
endif
# ELF interpreter (dynamic loader) soname
LDSONAME=ld64.so.1
ifeq ($(ARCH),amd64)
override LDSONAME=ld-linux-x86-64.so.2
else ifeq ($(ARCH),arm64)
override LDSONAME=ld-linux-aarch64.so.1
else ifeq ($(ARCH),ppc64le)
override LDSONAME=ld64.so.2
else ifeq ($(ARCH),s390)
override LDSONAME=ld64.so.1
endif
VERSION ?= latest
GOBUILD ?= calico/go-build
GOBUILD_IMAGE ?= $(GOBUILD):$(VERSION)
GOBUILD_ARCH_IMAGE ?= $(GOBUILD_IMAGE)-$(ARCH)
BASE ?= calico/base
BASE_IMAGE ?= $(BASE):latest
BASE_ARCH_IMAGE ?= $(BASE_IMAGE)-$(ARCH)
QEMU ?= calico/qemu-user-static
QEMU_IMAGE ?= $(QEMU):latest
ifdef CI
DOCKER_PROGRESS := --progress=plain
endif
###############################################################################
# Building images
###############################################################################
QEMU_IMAGE_CREATED=.qemu.created
.PHONY: image-qemu
image-qemu: $(QEMU_IMAGE_CREATED)
$(QEMU_IMAGE_CREATED):
docker buildx build $(DOCKER_PROGRESS) --load --platform=linux/amd64 --pull -t $(QEMU_IMAGE) -f qemu/Dockerfile qemu
touch $@
.PHONY: image
image: register image-qemu
docker buildx build $(DOCKER_PROGRESS) --load --platform=linux/$(ARCH) -t $(GOBUILD_ARCH_IMAGE) -f Dockerfile .
ifeq ($(ARCH),amd64)
docker tag $(GOBUILD_ARCH_IMAGE) $(GOBUILD_IMAGE)
endif
.PHONY: image-all
image-all: $(addprefix sub-image-,$(ARCHES))
sub-image-%:
$(MAKE) image ARCH=$*
.PHONY: image-base
image-base: register image-qemu
docker buildx build $(DOCKER_PROGRESS) --load --platform=linux/$(ARCH) --build-arg LDSONAME=$(LDSONAME) -t $(BASE_ARCH_IMAGE) -f base/Dockerfile base
.PHONY: image-base-all
image-base-all: $(addprefix sub-image-base-,$(ARCHES))
sub-image-base-%:
$(MAKE) image-base ARCH=$*
# Enable binfmt adding support for miscellaneous binary formats.
.PHONY: register
register:
ifeq ($(BUILDARCH),amd64)
docker run --rm --privileged multiarch/qemu-user-static:register --reset
endif
.PHONY: push
push: image
docker push $(GOBUILD_ARCH_IMAGE)
# to handle default case, because quay.io does not support manifest yet
ifeq ($(ARCH),amd64)
docker tag $(GOBUILD_ARCH_IMAGE) quay.io/$(GOBUILD_IMAGE)
docker push quay.io/$(GOBUILD_IMAGE)
endif
.PHONY: push-base
push-base: image-base
docker push $(BASE_ARCH_IMAGE)
.PHONY: push-qemu
push-qemu: image-qemu
docker push $(QEMU_IMAGE)
push-all: $(addprefix sub-push-,$(ARCHES))
sub-push-%:
$(MAKE) push ARCH=$*
$(MAKE) push-base ARCH=$*
$(MAKE) push-qemu
.PHONY: push-manifest
push-manifest:
# Docker login to hub.docker.com required before running this target as we are using $(HOME)/.docker/config.json holds the docker login credentials
docker manifest create $(GOBUILD_IMAGE) $(addprefix --amend ,$(addprefix $(GOBUILD_IMAGE)-,$(ARCHES)))
docker manifest push --purge $(GOBUILD_IMAGE)
docker manifest create $(BASE_IMAGE) $(addprefix --amend ,$(addprefix $(BASE_IMAGE)-,$(ARCHES)))
docker manifest push --purge $(BASE_IMAGE)
.PHONY: clean
clean:
rm -f $(QEMU_IMAGE_CREATED)
-docker image rm -f $$(docker images $(GOBUILD) -a -q)
-docker image rm -f $$(docker images $(BASE) -a -q)
-docker image rm -f $$(docker images $(QEMU) -a -q)
###############################################################################
# UTs
###############################################################################
test: register
for arch in $(ARCHES) ; do ARCH=$$arch $(MAKE) testcompile; done
testcompile:
docker run --rm -e LOCAL_USER_ID=$(shell id -u) -e GOARCH=$(ARCH) -w /code -v ${PWD}:/code $(GOBUILD_IMAGE)-$(BUILDARCH) go build -o hello-$(ARCH) hello.go
docker run --rm -v ${PWD}:/code $(GOBUILD_IMAGE)-$(BUILDARCH) /code/hello-$(ARCH) | grep -q "hello world"
@echo "success"
###############################################################################
# CI
###############################################################################
.PHONY: ci
ci: image-all image-base-all test
###############################################################################
# CD
###############################################################################
.PHONY: cd
cd:
ifndef CONFIRM
$(error CONFIRM is undefined - run using make <target> CONFIRM=true)
endif
ifndef BRANCH_NAME
$(error BRANCH_NAME is undefined - run using make <target> BRANCH_NAME=var or set an environment variable)
endif
$(MAKE) push-all VERSION=${BRANCH_NAME}
$(MAKE) push-manifest VERSION=${BRANCH_NAME}