Skip to content

Commit a32cd16

Browse files
authored
Merge pull request #2993 from tonistiigi/xx-build
dockerfile based binary building
2 parents 59fd6f0 + 26b633d commit a32cd16

File tree

16 files changed

+238
-225
lines changed

16 files changed

+238
-225
lines changed

.circleci/config.yml

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
docker: [{image: 'docker:19.03-git'}]
4343
environment:
4444
DOCKER_BUILDKIT: 1
45+
BUILDX_VERSION: "v0.5.1"
4546
parallelism: 3
4647
steps:
4748
- checkout
@@ -55,21 +56,14 @@ jobs:
5556
- run:
5657
name: "Docker info"
5758
command: docker info
58-
- run:
59-
name: "Cross - build image"
60-
command: |
61-
docker build --progress=plain -f dockerfiles/Dockerfile.cross --tag cli-builder:$CIRCLE_BUILD_NUM .
62-
- run:
63-
name: "Cross"
64-
command: |
65-
name=cross-$CIRCLE_BUILD_NUM-$CIRCLE_NODE_INDEX
66-
docker run \
67-
-e CROSS_GROUP=$CIRCLE_NODE_INDEX \
68-
--name $name cli-builder:$CIRCLE_BUILD_NUM \
69-
make cross
70-
docker cp \
71-
$name:/go/src/github.com/docker/cli/build \
72-
/work/build
59+
- run: apk add make curl
60+
- run: mkdir -vp ~/.docker/cli-plugins/
61+
- run: curl -fsSL --output ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/${BUILDX_VERSION}/buildx-${BUILDX_VERSION}.linux-amd64
62+
- run: chmod a+x ~/.docker/cli-plugins/docker-buildx
63+
- run: docker buildx version
64+
- run: docker context create buildctx
65+
- run: docker buildx create --use buildctx && docker buildx inspect --bootstrap
66+
- run: GROUP_INDEX=$CIRCLE_NODE_INDEX GROUP_TOTAL=$CIRCLE_NODE_TOTAL docker buildx bake cross --progress=plain
7367
- store_artifacts:
7468
path: /work/build
7569

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
.circleci
22
.dockerignore
3-
.git
43
.github
54
.gitignore
65
appveyor.yml

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
Thumbs.db
99
.editorconfig
1010
/build/
11-
cli/winresources/rsrc_386.syso
12-
cli/winresources/rsrc_amd64.syso
11+
cli/winresources/rsrc_*.syso
1312
/man/man1/
1413
/man/man5/
1514
/man/man8/

Dockerfile

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#syntax=docker/dockerfile:1.2
2+
3+
ARG BASE_VARIANT=alpine
4+
ARG GO_VERSION=1.13.15
5+
6+
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable
7+
FROM --platform=$BUILDPLATFORM golang:1.16-${BASE_VARIANT} AS golatest
8+
9+
FROM gostable AS go-linux
10+
FROM golatest AS go-darwin
11+
FROM golatest AS go-windows-amd64
12+
FROM golatest AS go-windows-386
13+
FROM golatest AS go-windows-arm
14+
FROM --platform=$BUILDPLATFORM tonistiigi/golang:497feff1-${BASE_VARIANT} AS go-windows-arm64
15+
FROM go-windows-${TARGETARCH} AS go-windows
16+
17+
FROM --platform=$BUILDPLATFORM tonistiigi/xx@sha256:620d36a9d7f1e3b102a5c7e8eff12081ac363828b3a44390f24fa8da2d49383d AS xx
18+
19+
FROM go-${TARGETOS} AS build-base-alpine
20+
COPY --from=xx / /
21+
RUN apk add --no-cache clang lld llvm file git
22+
WORKDIR /go/src/github.com/docker/cli
23+
24+
FROM build-base-alpine AS build-alpine
25+
ARG TARGETPLATFORM
26+
# gcc is installed for libgcc only
27+
RUN xx-apk add --no-cache musl-dev gcc
28+
29+
FROM go-${TARGETOS} AS build-base-buster
30+
COPY --from=xx / /
31+
RUN apt-get update && apt-get install --no-install-recommends -y clang lld file
32+
WORKDIR /go/src/github.com/docker/cli
33+
34+
FROM build-base-buster AS build-buster
35+
ARG TARGETPLATFORM
36+
RUN xx-apt install --no-install-recommends -y libc6-dev libgcc-8-dev
37+
38+
FROM build-${BASE_VARIANT} AS build
39+
# GO_LINKMODE defines if static or dynamic binary should be produced
40+
ARG GO_LINKMODE=static
41+
# GO_BUILDTAGS defines additional build tags
42+
ARG GO_BUILDTAGS
43+
# GO_STRIP strips debugging symbols if set
44+
ARG GO_STRIP
45+
# CGO_ENABLED manually sets if cgo is used
46+
ARG CGO_ENABLED
47+
# VERSION sets the version for the produced binary
48+
ARG VERSION
49+
RUN --mount=ro --mount=type=cache,target=/root/.cache \
50+
--mount=from=dockercore/golang-cross:xx-sdk-extras,target=/xx-sdk,src=/xx-sdk \
51+
--mount=type=tmpfs,target=cli/winresources \
52+
xx-go --wrap && \
53+
# export GOCACHE=$(go env GOCACHE)/$(xx-info)$([ -f /etc/alpine-release ] && echo "alpine") && \
54+
TARGET=/out ./scripts/build/binary && \
55+
xx-verify $([ "$GO_LINKMODE" = "static" ] && echo "--static") /out/docker
56+
57+
FROM build-base-${BASE_VARIANT} AS dev
58+
COPY . .
59+
60+
FROM scratch AS binary
61+
COPY --from=build /out .

Makefile

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,28 @@ lint: ## run all the lint tools
3030
gometalinter --config gometalinter.json ./...
3131

3232
.PHONY: binary
33-
binary: ## build executable for Linux
34-
@echo "WARNING: binary creates a Linux executable. Use cross for macOS or Windows."
35-
./scripts/build/binary
33+
binary:
34+
docker buildx bake binary
3635

3736
.PHONY: plugins
3837
plugins: ## build example CLI plugins
3938
./scripts/build/plugins
4039

4140
.PHONY: cross
42-
cross: ## build executable for macOS and Windows
43-
./scripts/build/cross
44-
45-
.PHONY: binary-windows
46-
binary-windows: ## build executable for Windows
47-
./scripts/build/windows
41+
cross:
42+
docker buildx bake cross
4843

4944
.PHONY: plugins-windows
5045
plugins-windows: ## build example CLI plugins for Windows
5146
./scripts/build/plugins-windows
5247

53-
.PHONY: binary-osx
54-
binary-osx: ## build executable for macOS
55-
./scripts/build/osx
56-
5748
.PHONY: plugins-osx
5849
plugins-osx: ## build example CLI plugins for macOS
5950
./scripts/build/plugins-osx
6051

6152
.PHONY: dynbinary
6253
dynbinary: ## build dynamically linked binary
63-
./scripts/build/dynbinary
54+
USE_GLIBC=1 docker buildx bake dynbinary
6455

6556
vendor: vendor.conf ## check that vendor matches vendor.conf
6657
rm -rf vendor

README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,31 @@ Development
1212

1313
`docker/cli` is developed using Docker.
1414

15-
Build a linux binary:
15+
Build CLI from source:
1616

1717
```
18-
$ make -f docker.Makefile binary
18+
$ docker buildx bake
1919
```
2020

2121
Build binaries for all supported platforms:
2222

2323
```
24-
$ make -f docker.Makefile cross
24+
$ docker buildx bake cross
2525
```
2626

27+
Build for a specific platform:
28+
29+
```
30+
$ docker buildx bake --set binary.platform=linux/arm64
31+
```
32+
33+
Build dynamic binary for glibc or musl:
34+
35+
```
36+
$ USE_GLIBC=1 docker buildx bake dynbinary
37+
```
38+
39+
2740
Run all linting:
2841

2942
```
@@ -44,12 +57,6 @@ Start an interactive development environment:
4457
$ make -f docker.Makefile shell
4558
```
4659

47-
In the development environment you can run many tasks, including build binaries:
48-
49-
```
50-
$ make binary
51-
```
52-
5360
Legal
5461
=====
5562
*Brought to you courtesy of our legal counsel. For more context,

cli/winresources/res_windows.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ These resources are used to provide
55
* An icon
66
* A Windows manifest declaring Windows version support
77
8-
The resource object files are generated with go generate.
8+
The resource object files are generated when building with scripts/build/binary .
99
The resource source files are located in scripts/winresources.
1010
This occurs automatically when you run scripts/build/windows.
1111
@@ -14,5 +14,3 @@ is included.
1414
1515
*/
1616
package winresources
17-
18-
//go:generate ../../scripts/gen/windows-resources

docker-bake.hcl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
variable "VERSION" {
2+
default = ""
3+
}
4+
5+
variable "USE_GLIBC" {
6+
default = ""
7+
}
8+
9+
variable "STRIP_TARGET" {
10+
default = ""
11+
}
12+
13+
group "default" {
14+
targets = ["binary"]
15+
}
16+
17+
target "binary" {
18+
target = "binary"
19+
platforms = ["local"]
20+
output = ["build"]
21+
args = {
22+
BASE_VARIANT = USE_GLIBC != "" ? "buster" : "alpine"
23+
VERSION = VERSION
24+
GO_STRIP = STRIP_TARGET
25+
}
26+
}
27+
28+
target "dynbinary" {
29+
inherits = ["binary"]
30+
args = {
31+
GO_LINKMODE = "dynamic"
32+
}
33+
}
34+
35+
variable "GROUP_TOTAL" {
36+
default = "1"
37+
}
38+
39+
variable "GROUP_INDEX" {
40+
default = "0"
41+
}
42+
43+
function "platforms" {
44+
params = [USE_GLIBC]
45+
result = concat(["linux/amd64", "linux/386", "linux/arm64", "linux/arm", "linux/ppc64le", "linux/s390x", "darwin/amd64", "darwin/arm64", "windows/amd64", "windows/arm", "windows/386"], USE_GLIBC!=""?[]:["windows/arm64"])
46+
}
47+
48+
function "glen" {
49+
params = [platforms, GROUP_TOTAL]
50+
result = ceil(length(platforms)/GROUP_TOTAL)
51+
}
52+
53+
target "_all_platforms" {
54+
platforms = slice(platforms(USE_GLIBC), GROUP_INDEX*glen(platforms(USE_GLIBC), GROUP_TOTAL),min(length(platforms(USE_GLIBC)), (GROUP_INDEX+1)*glen(platforms(USE_GLIBC), GROUP_TOTAL)))
55+
}
56+
57+
target "cross" {
58+
inherits = ["binary", "_all_platforms"]
59+
}
60+
61+
target "dynbinary-cross" {
62+
inherits = ["dynbinary", "_all_platforms"]
63+
}

docker.Makefile

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ build_linter_image:
3838
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
3939
cat ./dockerfiles/Dockerfile.lint | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(LINTER_IMAGE_NAME) -
4040

41-
.PHONY: build_cross_image
42-
build_cross_image:
43-
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
44-
cat ./dockerfiles/Dockerfile.cross | docker build ${DOCKER_BUILD_ARGS} --build-arg=GO_VERSION -t $(CROSS_IMAGE_NAME) -
45-
4641
.PHONY: build_shell_validate_image
4742
build_shell_validate_image:
4843
# build dockerfile from stdin so that we don't send the build-context; source is bind-mounted in the development environment
@@ -80,22 +75,10 @@ test-unit: build_docker_image ## run unit tests (using go test)
8075
.PHONY: test ## run unit and e2e tests
8176
test: test-unit test-e2e
8277

83-
.PHONY: cross
84-
cross: build_cross_image ## build the CLI for macOS and Windows
85-
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make cross
86-
87-
.PHONY: binary-windows
88-
binary-windows: build_cross_image ## build the CLI for Windows
89-
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
90-
9178
.PHONY: plugins-windows
9279
plugins-windows: build_cross_image ## build the example CLI plugins for Windows
9380
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
9481

95-
.PHONY: binary-osx
96-
binary-osx: build_cross_image ## build the CLI for macOS
97-
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
98-
9982
.PHONY: plugins-osx
10083
plugins-osx: build_cross_image ## build the example CLI plugins for macOS
10184
$(DOCKER_RUN) $(CROSS_IMAGE_NAME) make $@
@@ -120,9 +103,6 @@ fmt: ## run gofmt
120103
vendor: build_docker_image vendor.conf ## download dependencies (vendor/) listed in vendor.conf
121104
$(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make vendor
122105

123-
dynbinary: build_cross_image ## build the CLI dynamically linked
124-
$(DOCKER_RUN) -it $(CROSS_IMAGE_NAME) make dynbinary
125-
126106
.PHONY: authors
127107
authors: ## generate AUTHORS file from git history
128108
$(DOCKER_RUN) -it $(DEV_DOCKER_IMAGE_NAME) make authors

scripts/build/.variables

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
#!/usr/bin/env bash
1+
#!/usr/bin/env sh
22
set -eu
33

4+
TARGET=${TARGET:-"build"}
5+
46
PLATFORM=${PLATFORM:-}
5-
VERSION=${VERSION:-"unknown-version"}
7+
VERSION=${VERSION:-$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags | sed 's/^v//' 2>/dev/null || echo "unknown-version" )}
68
GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)}
79
BUILDTIME=${BUILDTIME:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")}
810

@@ -20,15 +22,15 @@ export LDFLAGS="\
2022
${LDFLAGS:-} \
2123
"
2224

23-
GOOS="${GOOS:-$(go env GOHOSTOS)}"
24-
GOARCH="${GOARCH:-$(go env GOHOSTARCH)}"
25+
GOOS="$(go env GOOS)"
26+
GOARCH="$(go env GOARCH)"
2527
if [ "${GOARCH}" = "arm" ]; then
26-
GOARM="${GOARM:-$(go env GOHOSTARM)}"
28+
GOARM="$(go env GOARM)"
2729
fi
2830

29-
TARGET="build/docker-$GOOS-$GOARCH"
31+
TARGET="$TARGET/docker-${GOOS}-${GOARCH}"
3032
if [ "${GOARCH}" = "arm" ] && [ -n "${GOARM}" ]; then
31-
TARGET="${TARGET}-v${GOARM}"
33+
TARGET="${TARGET}-v${GOARM}"
3234
fi
3335

3436
if [ "${GOOS}" = "windows" ]; then

0 commit comments

Comments
 (0)