...
1# Copyright 2018-2019 Datawire. All rights reserved.
2#
3# Useful bits for writing Makefiles or Makefile snippets.
4#
5## Eager inputs ##
6# (none)
7## Lazy inputs ##
8# (none)
9## Outputs ##
10#
11# Boolean support:
12# - Variable: TRUE = T
13# - Variable: FALSE =
14# - Function: not
15#
16# String support:
17# - Variable: export NL
18# - Variable: SPACE
19# - Variable: COMMA
20# - Function: str.eq
21#
22# Unsigned integer support:
23# - Function: uint.max
24# - Function: uint.min
25# - Function: uint.eq
26# - Function: uint.ge
27# - Function: uint.le
28# - Function: uint.gt
29# - Function: uint.lt
30#
31# Path support:
32# - Function: path.trimprefix
33# - Function: path.addprefix
34#
35# Build tool support:
36# - Variable: export GOHOSTOS
37# - Variable: export GOHOSTARCH
38# - Variable: build-aux.dir
39#
40# Other support:
41# - Function: joinlist
42# - Function: quote.shell
43# - Function: lazyonce
44# - .PHONY Target: noop
45# - .PHONY Target: FORCE
46#
47# Internal use:
48# - Variable: _prelude.go.VERSION (exposed as go-mod.mk:go.goversion)
49# - Function: _prelude.go.VERSION.HAVE (exposed as go-mod.mk:go.goversion.HAVE)
50# - Variable: _prelude.go.ensure (used by go-mod.mk)
51#
52## common.mk targets ##
53# - clobber
54ifeq ($(words $(filter $(abspath $(lastword $(MAKEFILE_LIST))),$(abspath $(MAKEFILE_LIST)))),1)
55_prelude.mk := $(lastword $(MAKEFILE_LIST))
56
57# For my own sanity with organization, I've split out several "groups"
58# of functionality from this file. Maybe that's a sign that this has
59# grown too complex. Maybe we should stop fighting it and just use
60# [GMSL](https://gmsl.sourceforge.io/). Absolutely nothing in any of
61# the `prelude_*.mk` files is allowed to be eager, so ordering doesn't
62# matter. Anything eager must go in this main `prelude.mk` file.
63include $(dir $(_prelude.mk))prelude_bool.mk
64include $(dir $(_prelude.mk))prelude_str.mk
65include $(dir $(_prelude.mk))prelude_uint.mk
66include $(dir $(_prelude.mk))prelude_path.mk
67include $(dir $(_prelude.mk))prelude_go.mk
68
69#
70# Functions
71
72# Usage: $(call joinlist,SEPARATOR,LIST)
73# Example: $(call joinlist,/,foo bar baz) => foo/bar/baz
74joinlist=$(if $(word 2,$2),$(firstword $2)$1$(call joinlist,$1,$(wordlist 2,$(words $2),$2)),$2)
75
76# Usage: $(call quote.shell,STRING)
77# Example: $(call quote.shell,some'string"with`special characters) => "some'string\"with\`special characters"
78#
79# Based on
80# https://git.lukeshu.com/autothing/tree/build-aux/Makefile.once.head/00-quote.mk?id=9384e763b00774603208b3d44977ed0e6762a09a
81# but modified to make newlines work with shells other than Bash.
82quote.shell = $(subst $(NL),'"$${NL}"','$(subst ','\'',$1)')
83
84# Usage: VAR = $(call lazyonce,VAR,EXPR)
85#
86# Caches the value of EXPR (in case it's expensive/slow) once it is
87# evaluated, but doesn't eager-evaluate it either.
88lazyonce = $(eval $(strip $1) := $2)$2
89_lazyonce.disabled = $(FALSE)
90
91ifeq ($(MAKE_VERSION),3.81)
92 define _lazyonce.print_warning
93 $(warning The 'lazyonce' function is known to trigger a memory corruption bug in GNU Make 3.81)
94 $(warning Disabling the 'lazyonce' function; upgrade your copy of GNU Make for faster builds)
95 $(eval _lazyonce.need_warning = $(FALSE))
96 endef
97 _lazyonce.need_warning = $(TRUE)
98 # The second $(if) is just so that the evaluated result output of
99 # _lazyonce.print_warning isn't part of the returned value.
100 lazyonce = $(if $(_lazyonce.need_warning),$(if $(_lazyonce.print_warning),))$2
101 _lazyonce.disabled = $(TRUE)
102
103 # These are use a lot, so go ahead and eager-evaluate them to speed
104 # things up.
105 _prelude.go.HAVE := $(_prelude.go.HAVE)
106 _prelude.go.VERSION := $(_prelude.go.VERSION)
107endif
108
109#
110# Variable constants
111
112build-aux.dir = $(patsubst %/,%,$(dir $(_prelude.mk)))
113
114#
115# Targets
116
117noop:
118 @true
119.PHONY: noop
120
121# Sometimes we have a file-target that we want Make to always try to
122# re-generate (such as compiling a Go program; we would like to let
123# `go install` decide whether it is up-to-date or not, rather than
124# trying to teach Make how to do that). We could mark it as .PHONY,
125# but that tells Make that "this isn't a real file that I expect to
126# ever exist", which has a several implications for Make, most of
127# which we don't want. Instead, we can have them *depend* on a .PHONY
128# target (which we'll name "FORCE"), so that they are always
129# considered out-of-date by Make, but without being .PHONY themselves.
130.PHONY: FORCE
131
132endif
View as plain text