Write a multi-line command in a Makefile
Occasionally, there is a need for adding multiple continuous lines for one target in a Makefile.
Writing multiple lines for a target
Executing multiple commands in a target is trivial:
1test:
2 @echo 1
3 @echo 2
Output:
11
22
However, each line is executed in its own shell. If a continuous line is needed, the following rules must be applied:
- Use
$$
instead of$
- Terminate each line using a semicolon
;
- Add a trailing backslash at the ending of the line
\
1test:
2 var1=test; \
3 echo $$var1
Output:
1var1=test; \
2echo $var1
3test
A real use case using multi-line targets
For how.wtf
, the CI/CD process invalidates a CloudFront distribution via id.
For context, the aws
dependency verifies that aws
is executable prior to the command execution. More information on that here.
1.PHONY: invalidate
2invalidate: aws
3 distribution_id=$$(aws cloudfront list-distributions --query "DistributionList.Items[?starts_with(Origins.Items[0].DomainName, '$(BUCKET)')].Id" --output text); \
4 aws cloudfront create-invalidation \
5 --distribution-id $$distribution_id \
6 --paths "/*" \
7 --query "Invalidation.Id" \
8 --output text
1distribution_id=$(aws cloudfront list-distributions --query "DistributionList.Items[?starts_with(Origins.Items[0].DomainName, 'how.wtf')].Id" --output text); \
2aws cloudfront create-invalidation \
3 --distribution-id $distribution_id \
4 --paths "/*" \
5 --query "Invalidation.Id" \
6 --output text
7ID6WOFMWKLCYDYRUA6AGPXXXXX
Writing multiple lines using ONESHELL
The ONESHELL
directive allows multiple lines to executed in the same shell; however, special characters like @
, -
, and +
are interpreted differently.
1.ONESHELL:
2test:
3 var1=test
4 echo $$var1
Output:
1var1=test
2echo $var1
3test