Merge pull request #78 from dnephin/fix-cross-build

Fix cross compile build
This commit is contained in:
Tibor Vass 2017-05-15 12:31:34 -07:00 committed by GitHub
commit a2225276af
19 changed files with 231 additions and 104 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
.DS_Store .DS_Store
build ./build

View File

@ -2,10 +2,7 @@
# github.com/docker/cli # github.com/docker/cli
# #
# build the CLI all: binary
.PHONY: build
build: clean
@./scripts/build/binary
# remove build artifacts # remove build artifacts
.PHONY: clean .PHONY: clean
@ -18,24 +15,32 @@ clean:
test: test:
@go test -tags daemon -v $(shell go list ./... | grep -v /vendor/) @go test -tags daemon -v $(shell go list ./... | grep -v /vendor/)
# run linters
.PHONY: lint .PHONY: lint
lint: lint:
@gometalinter --config gometalinter.json ./... @gometalinter --config gometalinter.json ./...
.PHONY: binary
binary:
@./scripts/build/binary
# build the CLI for multiple architectures # build the CLI for multiple architectures
.PHONY: cross .PHONY: cross
cross: clean cross:
@./scripts/build/cross @./scripts/build/cross
.PHONY: dynbinary
dynbinary:
@./scripts/build/dynbinary
# download dependencies (vendor/) listed in vendor.conf # download dependencies (vendor/) listed in vendor.conf
.PHONY: vendor .PHONY: vendor
vendor: vendor.conf vendor: vendor.conf
@vndr 2> /dev/null @vndr 2> /dev/null
@script/validate/check-git-diff vendor @scripts/validate/check-git-diff vendor
cli/compose/schema/bindata.go: cli/compose/schema/data/*.json cli/compose/schema/bindata.go: cli/compose/schema/data/*.json
go generate github.com/docker/cli/cli/compose/schema go generate github.com/docker/cli/cli/compose/schema
compose-jsonschema: cli/compose/schema/bindata.go compose-jsonschema: cli/compose/schema/bindata.go
@script/validate/check-git-diff cli/compose/schema/bindata.go @scripts/validate/check-git-diff cli/compose/schema/bindata.go

View File

@ -6,60 +6,42 @@ docker/cli
This repository is the home of the cli used in the Docker CE and This repository is the home of the cli used in the Docker CE and
Docker EE products. Docker EE products.
It's composed of 3 main folders
* `/cli` - all the commands code.
* `/cmd/docker` - the entrypoint of the cli, aka the main.
Development Development
=========== ===========
### Build locally `docker/cli` is developed using Docker.
Build a linux binary:
``` ```
$ make build $ make -f docker.Makefile binary
``` ```
``` Build binaries for all supported platforms:
$ make clean
```
You will need [gox](https://github.com/mitchellh/gox) for this one:
```
$ make cross
```
If you don't have [gox](https://github.com/mitchellh/gox), you can use the "in-container" version of `make cross`, listed below.
### Build inside container
```
$ make -f docker.Makefile build
```
```
$ make -f docker.Makefile clean
```
``` ```
$ make -f docker.Makefile cross $ make -f docker.Makefile cross
``` ```
Run all linting:
```
$ make -f docker.Makefile lint
```
`
### In-container development environment ### In-container development environment
``` Start an interactive development environment:
$ make -f docker.Makefile dev
```
Then you can use the [build locally](#build-locally) commands:
``` ```
$ make build $ make -f docker.Makefile shell
``` ```
In the development environment you can run many tasks, including build binaries:
``` ```
$ make clean $ make binary
``` ```
Legal Legal

View File

@ -15,26 +15,34 @@ jobs:
name: "Lint" name: "Lint"
command: | command: |
if [ "$CIRCLE_NODE_INDEX" != "0" ]; then exit; fi if [ "$CIRCLE_NODE_INDEX" != "0" ]; then exit; fi
docker build -f dockerfiles/Dockerfile.lint --tag cli-linter . dockerfile=dockerfiles/Dockerfile.lint
echo "COPY . ." >> $dockerfile
docker build -f $dockerfile --tag cli-linter .
docker run cli-linter docker run cli-linter
- run: - run:
name: "Cross" name: "Cross"
command: | command: |
if [ "$CIRCLE_NODE_INDEX" != "1" ]; then exit; fi if [ "$CIRCLE_NODE_INDEX" != "1" ]; then exit; fi
docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . dockerfile=dockerfiles/Dockerfile.cross
echo "COPY . ." >> $dockerfile
docker build -f $dockerfile --tag cli-builder .
docker run --name cross cli-builder make cross docker run --name cross cli-builder make cross
docker cp cross:/go/src/github.com/docker/cli/build /work/build docker cp cross:/go/src/github.com/docker/cli/build /work/build
- run: - run:
name: "Unit Test" name: "Unit Test"
command: | command: |
if [ "$CIRCLE_NODE_INDEX" != "2" ]; then exit; fi if [ "$CIRCLE_NODE_INDEX" != "2" ]; then exit; fi
docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . dockerfile=dockerfiles/Dockerfile.dev
echo "COPY . ." >> $dockerfile
docker build -f $dockerfile --tag cli-builder .
docker run cli-builder make test docker run cli-builder make test
- run: - run:
name: "Validate Vendor and Code Generation" name: "Validate Vendor and Code Generation"
command: | command: |
if [ "$CIRCLE_NODE_INDEX" != "3" ]; then exit; fi if [ "$CIRCLE_NODE_INDEX" != "3" ]; then exit; fi
docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . dockerfile=dockerfiles/Dockerfile.dev
echo "COPY . ." >> $dockerfile
docker build -f $dockerfile --tag cli-builder .
docker run cli-builder make -B vendor compose-jsonschema docker run cli-builder make -B vendor compose-jsonschema
- store_artifacts: - store_artifacts:

View File

@ -6,23 +6,30 @@
DEV_DOCKER_IMAGE_NAME = docker-cli-dev DEV_DOCKER_IMAGE_NAME = docker-cli-dev
LINTER_IMAGE_NAME = docker-cli-lint LINTER_IMAGE_NAME = docker-cli-lint
CROSS_IMAGE_NAME = docker-cli-cross
MOUNTS = -v `pwd`:/go/src/github.com/docker/cli MOUNTS = -v `pwd`:/go/src/github.com/docker/cli
# build docker image (dockerfiles/Dockerfile.build) # build docker image (dockerfiles/Dockerfile.build)
.PHONY: build_docker_image .PHONY: build_docker_image
build_docker_image: build_docker_image:
@docker build -q -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.build . @docker build -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.dev .
# build docker image having the linting tools (dockerfiles/Dockerfile.lint) # build docker image having the linting tools (dockerfiles/Dockerfile.lint)
.PHONY: build_linter_image .PHONY: build_linter_image
build_linter_image: build_linter_image:
@docker build -q -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint . @docker build -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint .
.PHONY: build_cross_image
build_cross_image:
@docker build -t $(CROSS_IMAGE_NAME) -f ./dockerfiles/Dockerfile.cross .
# build executable using a container # build executable using a container
.PHONY: build binary: build_docker_image
build: build_docker_image
@echo "WARNING: this will drop a Linux executable on your host (not a macOS or Windows one)" @echo "WARNING: this will drop a Linux executable on your host (not a macOS or Windows one)"
@docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make build @docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make binary
build: binary
# clean build artifacts using a container # clean build artifacts using a container
.PHONY: clean .PHONY: clean
@ -36,14 +43,16 @@ test: build_docker_image
# build the CLI for multiple architectures using a container # build the CLI for multiple architectures using a container
.PHONY: cross .PHONY: cross
cross: build_docker_image cross: build_cross_image
@docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make cross @docker run --rm $(MOUNTS) $(CROSS_IMAGE_NAME) make cross
# start container in interactive mode for in-container development # start container in interactive mode for in-container development
.PHONY: dev .PHONY: dev
dev: build_docker_image dev: build_docker_image
@docker run -ti $(MOUNTS) -v /var/run/docker.sock:/var/run/docker.sock $(DEV_DOCKER_IMAGE_NAME) ash @docker run -ti $(MOUNTS) -v /var/run/docker.sock:/var/run/docker.sock $(DEV_DOCKER_IMAGE_NAME) ash
shell: dev
# run linters in a container # run linters in a container
.PHONY: lint .PHONY: lint
lint: build_linter_image lint: build_linter_image
@ -53,3 +62,6 @@ lint: build_linter_image
.PHONY: vendor .PHONY: vendor
vendor: build_docker_image vendor.conf vendor: build_docker_image vendor.conf
@docker run -ti --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make vendor @docker run -ti --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make vendor
dynbinary: build_cross_image
@docker run -ti --rm $(MOUNTS) $(CROSS_IMAGE_NAME) make dynbinary

View File

@ -1,29 +0,0 @@
#
# This Dockerfile makes the docker builder run the tests.
# It means that if this Dockerfile can be built successfully,
# the tests passed.
#
# From the repo root dir:
# $ docker build -f dockerfiles/Dockerfile.ci .
#
FROM golang:1.8-alpine
RUN apk add -U git make
RUN go get github.com/LK4D4/vndr && \
cp /go/bin/vndr /usr/bin && \
rm -rf /go/src/* /go/pkg/* /go/bin/*
RUN go get github.com/mitchellh/gox && \
cp /go/bin/gox /usr/bin && \
rm -rf /go/src/* /go/pkg/* /go/bin/*
RUN go get github.com/jteeuwen/go-bindata/go-bindata && \
cp /go/bin/go-bindata /usr/bin && \
rm -rf /go/src/* /go/pkg/* /go/bin/*
COPY . /go/src/github.com/docker/cli
ENV CGO_ENABLED=0
WORKDIR /go/src/github.com/docker/cli

View File

@ -0,0 +1,22 @@
FROM golang:1.8.1
# allow replacing httpredir or deb mirror
ARG APT_MIRROR=deb.debian.org
RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
RUN apt-get update -qq && apt-get install -y -q \
libltdl-dev \
gcc-mingw-w64 \
parallel \
;
RUN go get github.com/mitchellh/gox && \
cp /go/bin/gox /usr/bin && \
rm -rf /go/src/* /go/pkg/* /go/bin/*
COPY dockerfiles/osx-cross.sh /tmp/
RUN /tmp/osx-cross.sh
ENV PATH /osxcross/target/bin:$PATH
WORKDIR /go/src/github.com/docker/cli

View File

@ -1,7 +1,7 @@
FROM golang:1.8-alpine FROM golang:1.8-alpine
RUN apk add -U git make RUN apk add -U git make bash coreutils
RUN go get github.com/LK4D4/vndr && \ RUN go get github.com/LK4D4/vndr && \
cp /go/bin/vndr /usr/bin && \ cp /go/bin/vndr /usr/bin && \

View File

@ -7,6 +7,5 @@ RUN go get -u gopkg.in/alecthomas/gometalinter.v1 && \
gometalinter --install gometalinter --install
WORKDIR /go/src/github.com/docker/cli WORKDIR /go/src/github.com/docker/cli
COPY . .
ENTRYPOINT ["/usr/local/bin/gometalinter"] ENTRYPOINT ["/usr/local/bin/gometalinter"]
CMD ["--config=gometalinter.json", "./..."] CMD ["--config=gometalinter.json", "./..."]

29
dockerfiles/osx-cross.sh Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
#
# Install dependencies required to cross compile osx, then cleanup
#
# TODO: this should be a separate build stage when CI supports it
set -eu -o pipefail
PKG_DEPS="patch xz-utils clang"
apt-get update -qq
apt-get install -y -q $PKG_DEPS
OSX_SDK=MacOSX10.11.sdk
OSX_CROSS_COMMIT=a9317c18a3a457ca0a657f08cc4d0d43c6cf8953
OSXCROSS_PATH="/osxcross"
echo "Cloning osxcross"
time git clone https://github.com/tpoechtrager/osxcross.git $OSXCROSS_PATH
cd $OSXCROSS_PATH
git checkout -q $OSX_CROSS_COMMIT
echo "Downloading OSX SDK"
time curl -sSL https://s3.dockerproject.org/darwin/v2/${OSX_SDK}.tar.xz \
-o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz"
echo "Buidling osxcross"
UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh > /dev/null

18
scripts/build/.variables Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -eu
VERSION=${VERSION:-"unknown-version"}
GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)}
BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')}
export LDFLAGS="\
-w \
-X github.com/docker/cli/cli.GitCommit=${GITCOMMIT} \
-X github.com/docker/cli/cli.BuildTime=${BUILDTIME} \
-X github.com/docker/cli/cli.Version=${VERSION} \
${LDFLAGS:-} \
"
export TARGET="build/docker-$(go env GOHOSTOS)-$(go env GOHOSTARCH)"
export SOURCE="github.com/docker/cli/cmd/docker"

View File

@ -1,5 +1,14 @@
#!/usr/bin/env sh #!/usr/bin/env bash
#
# Build a static binary for the host OS/ARCH
#
source ./scripts/build/ldflags set -eu -o pipefail
go build -o ./build/docker --ldflags "${LDFLAGS}" github.com/docker/cli/cmd/docker source ./scripts/build/.variables
echo "Building statically linked $TARGET"
export CGO_ENABLED=0
go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}"
ln -sf "$(basename ${TARGET})" build/docker

View File

@ -1,8 +1,12 @@
#!/usr/bin/env sh #!/usr/bin/env bash
source ./scripts/build/ldflags set -eu -o pipefail
gox -output build/docker-{{.OS}}-{{.Arch}} \ export BUILDDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-osarch="linux/arm linux/amd64 darwin/amd64 windows/amd64" \
--ldflags "${LDFLAGS}" \ echo "Building all binaries"
github.com/docker/cli/cmd/docker SHELL=/bin/bash parallel ::: \
"$BUILDDIR/linux-cross" \
"$BUILDDIR/windows" \
"$BUILDDIR/osx" \
;

14
scripts/build/dynbinary Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
#
# Build a dynamically linked binary for the host OS/ARCH
#
set -eu -o pipefail
source ./scripts/build/.variables
echo "Building dynamically linked $TARGET"
export CGO_ENABLED=1
go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}"
ln -sf "$(basename ${TARGET})" build/docker

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
VERSION=${VERSION:-"unknown-version"}
GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)}
BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')}
export LDFLAGS="-X github.com/docker/cli/cli.GitCommit=${GITCOMMIT} \
-X github.com/docker/cli/cli.BuildTime=${BUILDTIME} \
-X github.com/docker/cli/cli.Version=${VERSION} ${LDFLAGS}"

22
scripts/build/linux-cross Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# Build static linux binary for multiple architectures
#
set -eu -o pipefail
source ./scripts/build/.variables
CROSS_OSARCH="linux/amd64 linux/arm"
# Compile is broken
# linux/ppc64le
# Not yet supported by gox
# linux/s390x
echo "Building all linux binaries"
gox -output build/docker-{{.OS}}-{{.Arch}} \
-osarch "${CROSS_OSARCH}" \
--ldflags "${LDFLAGS}" \
"${SOURCE}"

21
scripts/build/osx Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env bash
#
# Build an osx binary from linux
#
set -eu -o pipefail
source ./scripts/build/.variables
export CGO_ENABLED=1
export GOOS=darwin
export GOARCH=amd64
export CC=o64-clang
export LDFLAGS='-linkmode external -s'
export LDFLAGS_STATIC_DOCKER='-extld='${CC}
# Override TARGET
TARGET="build/docker-$GOOS-$GOARCH"
echo "Building $TARGET"
go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}"

20
scripts/build/windows Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
#
# Build a windows binary from linux
#
set -eu -o pipefail
source ./scripts/build/.variables
export CC=x86_64-w64-mingw32-gcc
export CGO_ENABLED=1
export GOOS=windows
export GOARCH=amd64
# Override TARGET
TARGET="build/docker-$GOOS-$GOARCH"
echo "Building $TARGET"
# TODO: -tags pkcs11
go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}"