From 22e4dfa534a25251f10d472eb4e105cfd5728a01 Mon Sep 17 00:00:00 2001 From: Johan Bloemberg Date: Sun, 11 Feb 2018 14:34:59 +0100 Subject: [PATCH] build: Unify build/crossbuild MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - allows explicit crossbuild targets (eg: `make mgmt-darwin-amd64`) - adds darwin/amd64 to default crossbuild targets - gitignore only build artifacts (eg: not all files starting with `mgmt-`) - `build` and `crossbuild` target now utilize the same build function (`build` still generates only a `mgmt` binary for the current os/arch) - test crossbuilding - allow specifying custom GOOSARCHES envvar to override defaults - crossbuild artifacts go into `build/` now - add `build-debug` which includes symbol tables and debug info - the build function now has `-s -w` linker arguments which discards some debug info afaict, to build a debug release use `make build-debug` On my mac crossbuilding won't work unless I disable augeas and libvirt: ``` ~/.g/s/g/p/mgmt (build|●1✚8…3) $ make build Generating: bindata... Generating: lang... /Applications/Xcode.app/Contents/Developer/usr/bin/make --quiet -C lang Building: mgmt, os/arch: darwin-amd64, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=darwin GOARCH=amd64 time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-darwin-amd64 ; 7.14 real 10.36 user 1.73 sys mv mgmt-darwin-amd64 mgmt ``` ``` ~/.g/s/g/p/mgmt (build|●1✚8…3) $ time env GOTAGS='noaugeas novirt' make crossbuild Generating: bindata... Generating: lang... /Applications/Xcode.app/Contents/Developer/usr/bin/make --quiet -C lang Building: mgmt, os/arch: linux-amd64, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=linux GOARCH=amd64 time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-linux-amd64 -tags 'noaugeas novirt'; 18.48 real 50.02 user 5.83 sys Building: mgmt, os/arch: linux-ppc64, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=linux GOARCH=ppc64 time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-linux-ppc64 -tags 'noaugeas novirt'; 29.83 real 85.09 user 11.54 sys Building: mgmt, os/arch: linux-ppc64le, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=linux GOARCH=ppc64le time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-linux-ppc64le -tags 'noaugeas novirt'; 29.74 real 85.84 user 11.76 sys Building: mgmt, os/arch: linux-arm64, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=linux GOARCH=arm64 time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-linux-arm64 -tags 'noaugeas novirt'; 28.33 real 83.24 user 11.40 sys Building: mgmt, os/arch: darwin-amd64, version: 0.0.14-12-g94c8bc1-dirty... env GOOS=darwin GOARCH=amd64 time go build -ldflags "-X main.program=mgmt -X main.version=0.0.14-12-g94c8bc1-dirty -s -w" -o mgmt-darwin-amd64 -tags 'noaugeas novirt'; 7.16 real 10.15 user 1.74 sys 114.71 real 315.26 user 42.44 sys ``` --- .gitignore | 3 ++- Makefile | 42 +++++++++++++++++++++++++++-------------- test.sh | 3 +++ test/test-crossbuild.sh | 25 ++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 15 deletions(-) create mode 100755 test/test-crossbuild.sh diff --git a/.gitignore b/.gitignore index cf7882da..d9d7b87c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ tmp/ bindata/*.go mgmt mgmt.static -mgmt-* +# crossbuild artifacts +build/mgmt-* mgmt.iml rpmbuild/ *.deb diff --git a/Makefile b/Makefile index 693c4ba5..6dd9f584 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ # along with this program. If not, see . SHELL = /usr/bin/env bash -.PHONY: all art cleanart version program lang path deps run race bindata generate build crossbuild clean test gofmt yamlfmt format docs rpmbuild mkdirs rpm srpm spec tar upload upload-sources upload-srpms upload-rpms copr +.PHONY: all art cleanart version program lang path deps run race bindata generate build build-debug crossbuild clean test gofmt yamlfmt format docs rpmbuild mkdirs rpm srpm spec tar upload upload-sources upload-srpms upload-rpms copr .SILENT: clean bindata GO_FILES := $(shell find . -name '*.go') @@ -40,7 +40,10 @@ REMOTE_PATH = 'pub/alt/$(USERNAME)/$(PROGRAM)' ifneq ($(GOTAGS),) BUILD_FLAGS = -tags '$(GOTAGS)' endif -GOOSARCHES = linux/amd64 linux/ppc64 linux/ppc64le linux/arm64 +GOOSARCHES ?= linux/amd64 linux/ppc64 linux/ppc64le linux/arm64 darwin/amd64 + +GOHOSTOS = $(shell go env GOHOSTOS) +GOHOSTARCH = $(shell go env GOHOSTARCH) default: build @@ -115,24 +118,33 @@ lang: @echo "Generating: lang..." $(MAKE) --quiet -C lang -$(PROGRAM): $(GO_FILES) - @echo "Building: $(PROGRAM), version: $(SVERSION)..." - time go build -i -ldflags "-X main.program=$(PROGRAM) -X main.version=$(SVERSION)" -o $(PROGRAM) $(BUILD_FLAGS); - -define buildrelease -GOOS=$(1) GOARCH=$(2) go build -ldflags "-X main.program=$(PROGRAM) -X main.version=$(SVERSION) -s -w" -o $(PROGRAM)-$(1)-$(2) $(BUILD_FLAGS); -endef - -crossbuild: - @echo "Building: $(PROGRAM), version: $(SVERSION), arches: $(GOOSARCHES) ..." - $(foreach GOOSARCH,$(GOOSARCHES), $(call buildrelease,$(subst /,,$(dir $(GOOSARCH))),$(notdir $(GOOSARCH)))) +# build a `mgmt` binary for current host os/arch +$(PROGRAM): build/mgmt-${GOHOSTOS}-${GOHOSTARCH} + cp $< $@ $(PROGRAM).static: $(GO_FILES) @echo "Building: $(PROGRAM).static, version: $(SVERSION)..." go generate go build -a -installsuffix cgo -tags netgo -ldflags '-extldflags "-static" -X main.program=$(PROGRAM) -X main.version=$(SVERSION) -s -w' -o $(PROGRAM).static $(BUILD_FLAGS); -build: bindata lang $(PROGRAM) +build: LDFLAGS=-s -w +build: $(PROGRAM) + +build-debug: LDFLAGS= +build-debug: $(PROGRAM) + +# pattern rule target for (cross)building, mgmt-OS-ARCH will be expanded to the correct build +# extract os and arch from target pattern +GOOS=$(firstword $(subst -, ,$*)) +GOARCH=$(lastword $(subst -, ,$*)) +build/mgmt-%: $(GO_FILES) | bindata lang + @echo "Building: $(PROGRAM), os/arch: $*, version: $(SVERSION)..." + @# reassigning GOOS and GOARCH to make build command copy/pastable + env GOOS=${GOOS} GOARCH=${GOARCH} time go build -ldflags "-X main.program=$(PROGRAM) -X main.version=$(SVERSION) ${LDFLAGS}" -o $@ $(BUILD_FLAGS); + +# create a list of binary file names to use as make targets +crossbuild_targets = $(addprefix build/mgmt-,$(subst /,-,${GOOSARCHES})) +crossbuild: ${crossbuild_targets} clean: $(MAKE) --quiet -C bindata clean @@ -140,6 +152,8 @@ clean: [ ! -e $(PROGRAM) ] || rm $(PROGRAM) rm -f *_stringer.go # generated by `go generate` rm -f *_mock.go # generated by `go generate` + # crossbuild artifacts + rm -f build/mgmt-* test: bindata ./test.sh diff --git a/test.sh b/test.sh index d0e5814c..c7711334 100755 --- a/test.sh +++ b/test.sh @@ -26,6 +26,9 @@ run-test ./test/test-govet.sh run-test ./test/test-examples.sh run-test ./test/test-gotest.sh +# skipping: https://github.com/purpleidea/mgmt/issues/327 +# run-test ./test/test-crossbuild.sh + # do these longer tests only when running on ci if env | grep -q -e '^TRAVIS=true$' -e '^JENKINS_URL=' -e '^BUILD_TAG=jenkins'; then run-test ./test/test-shell.sh diff --git a/test/test-crossbuild.sh b/test/test-crossbuild.sh new file mode 100755 index 00000000..38025a58 --- /dev/null +++ b/test/test-crossbuild.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e -o pipefail + +echo running "$(basename "$0")" + +. test/util.sh + +# test if we can build for all OSes and ARCHes. + +tmpdir="`$mktemp --tmpdir -d tmp.XXX`" # get a dir outside of the main package +log="$tmpdir/$(basename $0 .sh).log" + +set +e +make crossbuild &> "$log" + +RET=$? +if [ ! $RET -eq 0 ]; then + echo 'FAIL' + cat "$log" +else + echo 'PASS' +fi +rm -rf "$tmpdir" +exit $RET