aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--_notes/makefile.md172
-rw-r--r--_posts/2020-05-20-makefile-escaping.md52
2 files changed, 123 insertions, 101 deletions
diff --git a/_notes/makefile.md b/_notes/makefile.md
index fb52d43..2c01406 100644
--- a/_notes/makefile.md
+++ b/_notes/makefile.md
@@ -1,65 +1,129 @@
---
title: Makefile
subtitle: best practices
----
-Best practices for my Makefiles (sorry for the botched highlighting).
-
-```make
-# Put this in the top of the Makefile:
-
-MAKEFLAGS += --no-builtin-rules --no-builtin-variables --warn-undefined-variables
-unexport MAKEFLAGS
-.DEFAULT_GOAL := all
-.DELETE_ON_ERROR:
-.SUFFIXES:
-SHELL := bash
-.SHELLFLAGS := -eu -o pipefail -c
-
-escape = $(subst ','\'',$(1))
-
-define noexpand
-ifeq ($$(origin $(1)),environment)
- $(1) := $$(value $(1))
-endif
-ifeq ($$(origin $(1)),environment override)
- $(1) := $$(value $(1))
-endif
-ifeq ($$(origin $(1)),command line)
- override $(1) := $$(value $(1))
-endif
-endef
+layout: nosidebar
+links:
+ - {rel: stylesheet, href: 'assets/css/bash.css'}
+features:
+ - note: This should go on top of every Makefile.
+ sections:
+ - do:
+ - |
+ MAKEFLAGS += --no-builtin-rules --no-builtin-variables --warn-undefined-variables
+ unexport MAKEFLAGS
+ .DEFAULT_GOAL := all
+ .DELETE_ON_ERROR:
+ .SUFFIXES:
+ SHELL := bash
+ .SHELLFLAGS := -eu -o pipefail -c
-# OK, now some examples of how to use it:
+ escape = $(subst ','\'',$(1))
-.PHONY: all
-all: test-escape test-noexpand
+ define noexpand
+ ifeq ($$(origin $(1)),environment)
+ $(1) := $$(value $(1))
+ endif
+ ifeq ($$(origin $(1)),environment override)
+ $(1) := $$(value $(1))
+ endif
+ ifeq ($$(origin $(1)),command line)
+ override $(1) := $$(value $(1))
+ endif
+ endef
+ - note: Quote command arguments and use the `escape` function on variables and shell output.
+ sections:
+ - do:
+ - |
+ var := Includes ' quote
+ test:
+ printf '%s\n' '$(call escape,$(var))'
+ dont:
+ - |
+ var := Includes space
+ test:
+ printf '%s\n' $(var)
+ - |
+ var := Includes ' quote
+ test:
+ printf '%s\n' '$(var)'
+ - do:
+ - |
+ cwd := $(shell pwd)
+ test:
+ printf 'In directory %s\n' '$(call escape,$(cwd))'
+ dont:
+ - |
+ cwd := $(shell pwd)
+ test:
+ printf 'In directory %s\n' $(cwd)
+ - |
+ cwd := $(shell pwd)
+ test:
+ printf 'In directory %s\n' '$(cwd)'
+ - note: Use the `noexpand` function on environment variables or variables that can be overridden on the command line.
+ sections:
+ - do:
+ - |
+ has_default ?= Default value
+ $(eval $(call noexpand,has_default))
-# Always put command arguments in single quotes.
-# Escape variables and shell output using the escape function.
+ test:
+ echo '$(call escape,$(has_default))'
+ dont:
+ - |
+ has_default ?= Default value
-var_with_quote := Includes ' quote
+ test:
+ echo '$(call escape,$(has_default))'
+ - |
+ has_default ?= Default value
+ export has_default
-.PHONY: test-escape
-test-escape:
- printf '%s\n' '$(call escape,$(var_with_quote))'
- printf '%s\n' '$(call escape,$(shell echo "Includes ' quote"))'
+ test:
+ echo "$$has_default"
+ - do:
+ - |
+ $(eval $(call noexpand,ENV_VAR))
-# The above recipe will print "Includes ' quote" twice.
-
-# If you define variables using ?= or use environment variables in your
-# Makefile, use noexpand on them (to safeguard against ${accidental}
-# references).
-
-var_with_default ?= Accidental reference?
-$(eval $(call noexpand,var_with_default))
-
-$(eval $(call noexpand,env_var))
+ test:
+ echo '$(call escape,$(ENV_VAR))'
+ dont:
+ - |
+ test:
+ echo '$(call escape,$(ENV_VAR))'
+---
+I've made a [detailed blog post] about how all of this works.
+{: .alert .alert-info }
-.PHONY: test-noexpand
-test-noexpand:
- printf '%s\n' '$(call escape,$(var_with_default))'
- printf '%s\n' '$(call escape,$(env_var))'
+[detailed blog post]: {{ site.baseurl }}{% post_url 2020-05-20-makefile-escaping %}
-# The above recipe will print "Accidental ${reference}" twice if you run using
-# env_var='Accidental ${reference}' make var_with_default='Accidental ${reference}'
-```
+{% for feature in page.features %}
+ {{ feature.note | markdownify }}
+ {% for section in feature.sections %}
+<div class="row">
+ {% if section.do %}
+ {% if section.dont %}{% assign width = "6" %}{% else %}{% assign width = "12" %}{% endif %}
+ <div class="col-md-{{ width }}">
+ {% for guide in section.do %}
+ <div class="pre_container pre_do">
+ <pre>{{ guide }}</pre>
+ <div class="pre_mark"><span class="glyphicon glyphicon-ok"></span></div>
+ </div>
+ {% endfor %}
+ </div>
+ {% endif %}
+ {% if section.dont %}
+ {% if section.do %}{% assign width = "6" %}{% else %}{% assign width = "12" %}{% endif %}
+ <div class="col-md-{{ width }}">
+ {% for guide in section.dont %}
+ <div class="pre_container pre_dont">
+ <pre>{{ guide }}</pre>
+ <div class="pre_mark"><span class="glyphicon glyphicon-remove"></span></div>
+ </div>
+ {% endfor %}
+ </div>
+ {% endif %}
+</div>
+ {% endfor %}
+ <hr/>
+{% endfor %}
diff --git a/_posts/2020-05-20-makefile-escaping.md b/_posts/2020-05-20-makefile-escaping.md
index 4190fff..7d468dc 100644
--- a/_posts/2020-05-20-makefile-escaping.md
+++ b/_posts/2020-05-20-makefile-escaping.md
@@ -2,6 +2,11 @@
title: Escaping characters in Makefile
excerpt: Making less error-prone.
---
+TL;DR: visit [this page] for a short and concise version of this article.
+{: .alert .alert-success }
+
+[this page]: {{ site.baseurl }}{% link _notes/makefile.md %}
+
I'm a big sucker for irrelevant nitpicks like properly quoting arguments in
shell scripts.
I've also recently started using GNU make as a substitute for one-line shell
@@ -32,53 +37,6 @@ the choice of shell is very relevant.
The Makefiles in this post specify `bash` explicitly using the `SHELL`
variable, but the same rules should apply for all similar `sh`-like shells.
-TL;DR
------
-
-Visit [this page] for an all-in-one Makefile template.
-{: .alert .alert-info }
-
-[this page]: {{ site.baseurl }}{% link _notes/makefile.md %}
-
-* Put the prologue above at the top of your Makefile.
-* Quote command arguments in Makefiles using single quotes `'`.
-* Define a helper function:
-
- escape = $(subst ','\'',$(1))
-
- Instead of:
-
- test:
- echo '$(var)'
-
- do
-
- test:
- echo '$(call escape,$(var))'
-
-* If you use environment variables in your Makefile (or you override variables
-on the command line), add the following lengthy snippet:
-
- define noexpand
- ifeq ($$(origin $(1)),environment)
- $(1) := $$(value $(1))
- endif
- ifeq ($$(origin $(1)),environment override)
- $(1) := $$(value $(1))
- endif
- ifeq ($$(origin $(1)),command line)
- override $(1) := $$(value $(1))
- endif
- endef
-
- Then `eval` the `noexpand` function output for every possibly overridden
-variable or a used environment variable:
-
- has_default ?= Default value
- $(eval $(call noexpand,has_default))
-
- $(eval $(call noexpand,ENV_VAR))
-
Quoting arguments
-----------------