Closed LukeShu closed 5 years ago
Added:
The memory corruption bug in Make is triggering on macOS 2/3 - 3/4 of the time. Variables set with lazyonce
might get 2 extra bytes at the end, hence:
make: *** No rule to make target `/private/var/folders/yy/d215g62s727f4w2137t9jl2m0000gn/T/tmp.gvpSR9WD/build-aux/bin/flockck', needed by `all'. Stop.
So 3/4 of the macOS CI jobs failed, but the Go 1.11 one passed.
One of the Ubuntu jobs is pending because it passed, but then I SSHed in to it to experiment with speeding up APT.
diff from what was reviewed:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b72feadc..d7926ec6 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -26,7 +26,12 @@ commands:
type: string
steps:
- run:
- command: sudo apt update && sudo apt install << parameters.packages >>
+ # CircleCI seems to be in EC2 us-east-1, so use an archive.ubuntu.com mirror there, so that "apt
+ # update" is consistently fast.
+ command: |
+ sudo sed -i 's,//archive\.ubuntu\.com,//us-east-1.ec2.archive.ubuntu.com,g' /etc/apt/sources.list &&
+ sudo apt update &&
+ sudo apt install << parameters.packages >>
"brew-install":
parameters:
@@ -53,7 +58,7 @@ commands:
- run:
name: "Install Go"
command: |
- curl https://dl.google.com/go/go1.12.$(uname -s | tr A-Z a-z)-amd64.tar.gz -o /tmp/go.tar.gz
+ curl https://dl.google.com/go/go<< parameters.version >>.$(uname -s | tr A-Z a-z)-amd64.tar.gz -o /tmp/go.tar.gz
tar -C /tmp -xzf /tmp/go.tar.gz
echo 'export PATH=/tmp/go/bin:$PATH' >> "$BASH_ENV"
if [ -z "$(/tmp/go/bin/go env GOPROXY)" ]; then
@@ -104,8 +109,6 @@ jobs:
"VM macOS 10-13":
executor: vm-macos-10-13
- environment:
- build_aux_unsupported_go: true
steps:
- brew-install:
packages: bats
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc745ab9..12162a27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -58,7 +58,7 @@
- 2019-05-01: `prelude.mk`: Add `$(call lazyonce,…)`.
- 2019-05-01: `prelude.mk`: Introduce, steal code from `common.mk`.
- - 2019-02-15: `kubernaut-ui.mk`: Avoid warnings from `make` inside of `makeh shell`.
+ - 2019-02-15: `kubernaut-ui.mk`: Avoid warnings from `make` inside of `make shell`.
- 2019-02-13: `_go-common.mk`: Bump golangci-lint version 1.13.1→1.15.0.
diff --git a/go-mod.mk b/go-mod.mk
index 19145aad..9bf67502 100644
--- a/go-mod.mk
+++ b/go-mod.mk
@@ -57,7 +57,6 @@ include $(dir $(_go-mod.mk))common.mk
# Configure the `go` command
go.goversion = $(_prelude.go.VERSION)
-go.goversion.HAVE= $(_prelude.go.VERSION.HAVE)
go.lock = $(_prelude.go.lock)
export GO111MODULE = on
@@ -85,9 +84,7 @@ $(eval $(call build-aux.bin-go.rule, go-mkopensource, github.com/datawire/build-
NAME ?= $(notdir $(go.module))
-_go.module.error = $(error This Makefile requires Go '1.11.4' or newer; you $(if $(go.goversion),have '$(go.goversion)',do not seem to have Go))
-_go.module.value = $(shell GO111MODULE=on go mod edit -json | jq -r .Module.Path)
-go.module := $(_go.module.$(if $(call go.goversion.HAVE,1.11.4),value,error))
+go.module := $(_prelude.go.ensure)$(shell GO111MODULE=on go mod edit -json | jq -r .Module.Path)
ifneq ($(words $(go.module)),1)
$(error Could not extract $$(go.module) from ./go.mod)
endif
diff --git a/prelude.mk b/prelude.mk
index 4055c187..b67cc39f 100644
--- a/prelude.mk
+++ b/prelude.mk
@@ -51,8 +51,8 @@
#
# Internal use:
# - Variable: _prelude.go.VERSION (exposed as go-mod.mk:go.goversion)
-# - Function: _prelude.go.VERSION.HAVE (exposed as go-mod.mk:go.goversion.have)
# - Variable: _prelude.go.lock (exposed as go-mod.mk:go.lock)
+# - Variable: _prelude.go.ensure (used by go-mod.mk)
#
## common.mk targets ##
# - clobber
@@ -99,6 +99,25 @@ quote.shell = $(subst $(NL),'"$${NL}"','$(subst ','\'',$1)')
# Caches the value of EXPR (in case it's expensive/slow) once it is
# evaluated, but doesn't eager-evaluate it either.
lazyonce = $(eval $(strip $1) := $2)$2
+_lazyonce.disabled = $(FALSE)
+
+ifeq ($(MAKE_VERSION),3.81)
+ define _lazyonce.print_warning
+ $(warning The 'lazyonce' function is known to trigger a memory corruption bug in GNU Make 3.81)
+ $(warning Disabling the 'lazyonce' function; upgrade your copy of GNU Make for faster builds)
+ $(eval _lazyonce.need_warning = $(FALSE))
+ endef
+ _lazyonce.need_warning = $(TRUE)
+ # The second $(if) is just so that the evaluated result output of
+ # _lazyonce.print_warning isn't part of the returned value.
+ lazyonce = $(if $(_lazyonce.need_warning),$(if $(_lazyonce.print_warning),))$2
+ _lazyonce.disabled = $(TRUE)
+
+ # These are use a lot, so go ahead and eager-evaluate them to speed
+ # things up.
+ _prelude.go.HAVE := $(_prelude.go.HAVE)
+ _prelude.go.VERSION := $(_prelude.go.VERSION)
+endif
#
# Variable constants
@@ -112,7 +131,7 @@ build-aux.bindir = $(abspath $(build-aux.dir)/bin)
# Have this section toward the end, so that it can eagerly use stuff
# defined above.
-FLOCK ?= $(call lazyonce,FLOCK,$(or $(shell which flock 2>/dev/null),$(build-aux.bindir)/flock))
+FLOCK ?= $(call lazyonce,FLOCK,$(or $(shell which flock 2>/dev/null),$(_prelude.go.ensure)$(build-aux.bindir)/flock))
COPY_IFCHANGED ?= $(build-aux.bindir)/copy-ifchanged
MOVE_IFCHANGED ?= $(build-aux.bindir)/move-ifchanged
WRITE_IFCHANGED ?= $(build-aux.bindir)/write-ifchanged
diff --git a/prelude_go.mk b/prelude_go.mk
index 103b52f1..e52521ac 100644
--- a/prelude_go.mk
+++ b/prelude_go.mk
@@ -85,13 +85,16 @@ _prelude.go.VERSION.HAVE = $(if $(_prelude.go.HAVE),$(call _prelude.go.VERSION.g
#
# Building Go programs for use by build-aux
+_prelude.go.error_unsupported = $(error This Makefile requires Go '1.11.4' or newer; you $(if $(_prelude.go.HAVE),have '$(_prelude.go.VERSION)',do not seem to have Go))
+_prelude.go.ensure = $(if $(call _prelude.go.VERSION.HAVE,1.11.4),,$(_prelude.go.error_unsupported))
+
# All of this funny business with locking can be ditched once we drop
# support for Go 1.11. (When removing it, be aware that go-mod.mk
# uses `_prelude.go.*` variables).
-_prelude.go.lock.missing = $(error This Makefile requires Go '1.11.4' or newer; you do not seem to have Go)
-_prelude.go.lock.too_old = $(error This Makefile requires Go '1.11.4' or newer; you have '$(_prelude.go.VERSION)')
-_prelude.go.lock.1_11 = $(FLOCK)$(if $@, $(_prelude.go.GOPATH)/pkg/mod )
+_prelude.go.lock.unsupported = $(_prelude.go.error_unsupported)
+# The second $(if) is just to make sure that any output isn't part of what we return.
+_prelude.go.lock.1_11 = $(FLOCK)$(if $@, $(_prelude.go.GOPATH)/pkg/mod $(if $(shell mkdir -p $(_prelude.go.GOPATH)/pkg/mod),))
_prelude.go.lock.current =
# _prelude.go.lock is a slightly magical variable. When evaluated as a dependency in a
@@ -102,7 +105,6 @@ _prelude.go.lock.current =
# When evaluated as part of a recipe, it evaluates as a command prefix
# with arguments.
_prelude.go.lock = $(_prelude.go.lock.$(strip \
- $(if $(call not,$(_prelude.go.HAVE)), missing,\
$(if $(call _prelude.go.VERSION.HAVE, 1.12beta1), current,\
$(if $(call _prelude.go.VERSION.HAVE, 1.11.4), 1_11,\
- too_old)))))
+ unsupported))))
diff --git a/tests/go-mod.bats b/tests/go-mod.bats
index a1785053..fe166ea6 100644
--- a/tests/go-mod.bats
+++ b/tests/go-mod.bats
@@ -38,7 +38,7 @@ setup() {
else
[[ $(sed -n 1p actual) == 'outside: '* ]]
[[ $(sed -n 2p actual) == 'inside: '* ]]
- [[ $(wc -l actual) -eq 2 ]]
+ [[ $(wc -l <actual) -eq 2 ]]
outside="$(sed -n 's/^outside: //p' actual)"
[[ "$outside" != *' '* ]]
diff --git a/tests/prelude.bats b/tests/prelude.bats
index 9a3dbe7e..9224e4b7 100644
--- a/tests/prelude.bats
+++ b/tests/prelude.bats
@@ -32,6 +32,9 @@ load common
}
@test "prelude.mk: lazyonce" {
+ if [[ "$(make --version | head -n1)" == 'GNU Make 3.81' ]]; then
+ skip
+ fi
cat >>Makefile <<-'__EOT__'
include build-aux/prelude.mk
var = $(call lazyonce,var,$(info eval-time)value)
This uses BATS to add tests for
prelude.mk
. Obviously, it would be good to add tests for more stuff as well, but it's a start.Closes #3.