Mastering Makefile: Dynamic Dates, Variable Assignments, and Parameterized Targets
This guide demonstrates how to use Makefile for automating builds by retrieving the current date, exploring different variable assignment operators, looping over multiple hosts, and encapsulating reusable targets with parameter passing, complete with practical code examples and execution steps.
Getting the Current Date
Define a variable that stores the formatted date using the shell date command and the $(shell ...) function, then display it with a simple target.
# Define a variable to store the formatted date
DATE := $(shell date +%Y%m%d)
# Example target that shows how to use the date variable
all: show_date
show_date:
@echo Today is: $(DATE)Variable Assignment Operators
Makefile provides several assignment symbols, each with distinct behavior: =: Simple (recursive) assignment; the value is evaluated when the variable is used. :=: Immediate assignment; the value is computed at definition time and fixed. ?=: Conditional assignment; only sets the variable if it is undefined. +=: Append assignment; adds new content to the existing value.
Example illustrating the differences:
FOO = $(BAR)
BAR = hello
BAZ := $(BAR)
BAR = world
QUX ?= default
QUX ?= new_value
LIST = item1
LIST += item2Passing Multiple Parameters and Looping
To process several hosts in one run, define a space‑separated list and iterate over it with a for loop inside a target.
# Define a variable that stores hosts
HOSTS := host1 host2 host3
all: iterate_hosts
iterate_hosts:
@for host in $(HOSTS); do \
echo "Processing $$host"; \
# Add per‑host actions here, e.g., ping
ping -c 1 $$host; \
doneThe target expands HOSTS, runs the loop, and executes ping for each host.
Encapsulating Functions and Passing Arguments
Makefile functions and define blocks allow you to create reusable targets that accept parameters. The example below defines a macro PROCESS_HOST and invokes it for every host using foreach and eval.
# Default hosts variable
HOSTS := host1 host2 host3
# Main target that triggers processing of all hosts
all: $(HOSTS)
@echo "All hosts processed."
# Macro that creates a target for a single host
define PROCESS_HOST
$(1):
@echo "Processing $(1)..."
# Add per‑host actions here, e.g., ping
ping -c 1 $(1)
endef
# Generate a target for each host
$(foreach host,$(HOSTS),$(eval $(call PROCESS_HOST,$(host))))
# Example target to manually invoke specific hosts
process_specific_host:
$(MAKE) host1
$(MAKE) host2Running the Makefile
Save the content as a file named Makefile and execute it from the terminal:
make allThe command iterates over each host, runs the defined actions (e.g., ping), and prints a final message indicating all hosts have been processed. You can also invoke individual host targets directly, such as make process_specific_host, which calls the specific host targets in sequence.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
