build: Unify build/crossbuild

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
```
This commit is contained in:
Johan Bloemberg
2018-02-11 14:34:59 +01:00
committed by James Shubin
parent 41eb850b3d
commit 22e4dfa534
4 changed files with 58 additions and 15 deletions

3
.gitignore vendored
View File

@@ -9,7 +9,8 @@ tmp/
bindata/*.go bindata/*.go
mgmt mgmt
mgmt.static mgmt.static
mgmt-* # crossbuild artifacts
build/mgmt-*
mgmt.iml mgmt.iml
rpmbuild/ rpmbuild/
*.deb *.deb

View File

@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
SHELL = /usr/bin/env bash 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 .SILENT: clean bindata
GO_FILES := $(shell find . -name '*.go') GO_FILES := $(shell find . -name '*.go')
@@ -40,7 +40,10 @@ REMOTE_PATH = 'pub/alt/$(USERNAME)/$(PROGRAM)'
ifneq ($(GOTAGS),) ifneq ($(GOTAGS),)
BUILD_FLAGS = -tags '$(GOTAGS)' BUILD_FLAGS = -tags '$(GOTAGS)'
endif 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 default: build
@@ -115,24 +118,33 @@ lang:
@echo "Generating: lang..." @echo "Generating: lang..."
$(MAKE) --quiet -C lang $(MAKE) --quiet -C lang
$(PROGRAM): $(GO_FILES) # build a `mgmt` binary for current host os/arch
@echo "Building: $(PROGRAM), version: $(SVERSION)..." $(PROGRAM): build/mgmt-${GOHOSTOS}-${GOHOSTARCH}
time go build -i -ldflags "-X main.program=$(PROGRAM) -X main.version=$(SVERSION)" -o $(PROGRAM) $(BUILD_FLAGS); cp $< $@
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))))
$(PROGRAM).static: $(GO_FILES) $(PROGRAM).static: $(GO_FILES)
@echo "Building: $(PROGRAM).static, version: $(SVERSION)..." @echo "Building: $(PROGRAM).static, version: $(SVERSION)..."
go generate 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); 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: clean:
$(MAKE) --quiet -C bindata clean $(MAKE) --quiet -C bindata clean
@@ -140,6 +152,8 @@ clean:
[ ! -e $(PROGRAM) ] || rm $(PROGRAM) [ ! -e $(PROGRAM) ] || rm $(PROGRAM)
rm -f *_stringer.go # generated by `go generate` rm -f *_stringer.go # generated by `go generate`
rm -f *_mock.go # generated by `go generate` rm -f *_mock.go # generated by `go generate`
# crossbuild artifacts
rm -f build/mgmt-*
test: bindata test: bindata
./test.sh ./test.sh

View File

@@ -26,6 +26,9 @@ run-test ./test/test-govet.sh
run-test ./test/test-examples.sh run-test ./test/test-examples.sh
run-test ./test/test-gotest.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 # do these longer tests only when running on ci
if env | grep -q -e '^TRAVIS=true$' -e '^JENKINS_URL=' -e '^BUILD_TAG=jenkins'; then if env | grep -q -e '^TRAVIS=true$' -e '^JENKINS_URL=' -e '^BUILD_TAG=jenkins'; then
run-test ./test/test-shell.sh run-test ./test/test-shell.sh

25
test/test-crossbuild.sh Executable file
View File

@@ -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