315 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			315 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Intro
 | 
						|
 | 
						|
The fundamental problem:
 | 
						|
 | 
						|
```bash
 | 
						|
git submodule update --init soundscape
 | 
						|
cargo build --release
 | 
						|
install -pm755 target/release/tap /usr/local/bin/
 | 
						|
```
 | 
						|
 | 
						|
*But you can't type this for each run.*
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
## First Solution
 | 
						|
 | 
						|
```bash
 | 
						|
#!/bin/sh
 | 
						|
git submodule update --init soundscape
 | 
						|
cargo build --release
 | 
						|
install -pm755 target/release/tap /usr/local/bin/
 | 
						|
```
 | 
						|
 | 
						|
At this point, every test takes 10 minutes.
 | 
						|
 | 
						|
## Second Solution
 | 
						|
 | 
						|
```bash
 | 
						|
#!/bin/sh
 | 
						|
[ -f soundscape/.git ] || git submodule update --init soundscape
 | 
						|
[ -f target/release/tap ] || cargo build --release
 | 
						|
[ -f target/release/tap ] || \
 | 
						|
    install -pm755 target/release/tap /usr/local/bin/
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Makefile Solutions
 | 
						|
 | 
						|
- input, process, output.
 | 
						|
- automatic idempotence
 | 
						|
 | 
						|
```bash
 | 
						|
INSTALL_DIR = /usr/local/bin
 | 
						|
 | 
						|
soundscape/.git:
 | 
						|
    git submodule update --init soundscape
 | 
						|
 | 
						|
/usr/local/bin/tap: target/release/tap
 | 
						|
	install -pm755 target/release/tap $(INSTALL_DIR)
 | 
						|
 | 
						|
target/release/tap: src soundscape/.git
 | 
						|
	cargo build --release
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# The Three Sigils
 | 
						|
 | 
						|
Readable, but slow:
 | 
						|
 | 
						|
```make fort_1
 | 
						|
forts/big_fort.txt: forts/short.txt forts/long.txt
 | 
						|
	cat forts/short.txt forts/long.txt > forts/big_fort.txt
 | 
						|
 | 
						|
forts/:
 | 
						|
	mkdir forts
 | 
						|
 | 
						|
forts/short.txt: forts/
 | 
						|
	fortune -s > forts/short.txt
 | 
						|
 | 
						|
forts/long.txt: forts/
 | 
						|
	fortune -l > forts/long.txt
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
| Make this | From That | From These |
 | 
						|
|:---------:|:---------:|:----------:|
 | 
						|
|  `$@`     |  `$<`     |   `$^`     |
 | 
						|
 | 
						|
 | 
						|
```make fort_2
 | 
						|
forts/big_fort.txt: forts/short.txt forts/long.txt
 | 
						|
		cat $^ > $@
 | 
						|
 | 
						|
forts/: README.md
 | 
						|
	mkdir $@
 | 
						|
forts/short.txt: forts/
 | 
						|
	fortune -s > $@
 | 
						|
forts/long.txt: forts/
 | 
						|
	fortune -l > $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Gotcha: Directories
 | 
						|
 | 
						|
 | 
						|
```make fort_2
 | 
						|
forts/big_fort.txt: forts/short.txt forts/long.txt
 | 
						|
		cat $^ > $@
 | 
						|
 | 
						|
forts/: README.md
 | 
						|
	mkdir $@
 | 
						|
forts/short.txt: forts/
 | 
						|
	fortune -s > $@
 | 
						|
forts/long.txt: forts/
 | 
						|
	fortune -l > $@
 | 
						|
 | 
						|
README.md:
 | 
						|
    echo "Find the fortunes in the fort dir" > $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Variables
 | 
						|
 | 
						|
```make vars
 | 
						|
include /etc/os-release
 | 
						|
DAY != date +%d
 | 
						|
MESSAGE != fortune -s
 | 
						|
 | 
						|
motd_$(DAY):
 | 
						|
	$(info Placing message:)
 | 
						|
	echo "Welcome to $(NAME)" > $@
 | 
						|
	echo $(MESSAGE) >> $@
 | 
						|
```
 | 
						|
 | 
						|
### Gotcha: Hanging Quotes
 | 
						|
 | 
						|
> echo "Welcome to "Arch Linux""
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
## Add New Variables
 | 
						|
 | 
						|
```make
 | 
						|
make -f vars -e MESSAGE="Red alert, all hands on deck!"
 | 
						|
```
 | 
						|
 | 
						|
### Gotcha: Quote, or Risk Escape
 | 
						|
 | 
						|
```make
 | 
						|
make -f vars -e MESSAGE="<h1> HTML Headers </h1>"
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Gotcha: Variables from Shell
 | 
						|
 | 
						|
This works:
 | 
						|
 | 
						|
```make
 | 
						|
file:
 | 
						|
    $(info Hello $(USER))
 | 
						|
```
 | 
						|
 | 
						|
...but not this:
 | 
						|
 | 
						|
```make
 | 
						|
file:
 | 
						|
    user=bob
 | 
						|
    echo $user
 | 
						|
```
 | 
						|
 | 
						|
Nor this:
 | 
						|
 | 
						|
```make
 | 
						|
numbers:
 | 
						|
    for x in 1 2 3 4 5; do
 | 
						|
        echo $x
 | 
						|
    done > $@
 | 
						|
```
 | 
						|
 | 
						|
Nor this:
 | 
						|
 | 
						|
```make
 | 
						|
numbers:
 | 
						|
    for x in 1 2 3 4 5; do echo $x ; done > $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
### Ugly Fixes are Ugly
 | 
						|
 | 
						|
This works, but don't.
 | 
						|
 | 
						|
```make
 | 
						|
file:
 | 
						|
	for x in 1 2 ;\
 | 
						|
			do echo $$x ;\
 | 
						|
	done > $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
 | 
						|
# Phonies, and the Problems with Lies
 | 
						|
 | 
						|
## Clean
 | 
						|
 | 
						|
 | 
						|
```make
 | 
						|
.PHONY: clean
 | 
						|
clean:
 | 
						|
    git clean -fdX
 | 
						|
```
 | 
						|
 | 
						|
## Gotcha: Recompiling without Changes
 | 
						|
 | 
						|
```make
 | 
						|
CHECKER = command -v
 | 
						|
.PHONY: check
 | 
						|
check:
 | 
						|
	$(CHECKER) fortune >/dev/null
 | 
						|
	$(CHECKER) cowsay >/dev/null
 | 
						|
 | 
						|
file: check # Needs a '|'
 | 
						|
	fortune | cowsay > $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
 | 
						|
## Non-Compiling Checks
 | 
						|
 | 
						|
- `make` -n
 | 
						|
- *Gotcha*: shell output variables.
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
 | 
						|
# The Fourth Sigil: `%`
 | 
						|
 | 
						|
Create standardized rules with `%`.
 | 
						|
 | 
						|
 | 
						|
```make rules
 | 
						|
CP = ln -f
 | 
						|
 | 
						|
output: pngs/ldap.png
 | 
						|
 | 
						|
jpgs/ldap.jpg: ../../ldap/ldap.jpg
 | 
						|
	mkdir -p $(dir $@)
 | 
						|
	$(CP) $< $@
 | 
						|
 | 
						|
pngs/%.png: jpgs/%.jpg
 | 
						|
	mkdir -p $(dir $@)
 | 
						|
	$(info making $(@F) in $(@D))
 | 
						|
	magick $< $@
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Bling: makefile2graph
 | 
						|
 | 
						|
```graph
 | 
						|
 | 
						|
┌────────────────┐     ┌────────────────────┐
 | 
						|
│ forts/long.txt │ ◀── │       forts/       │
 | 
						|
└────────────────┘     └────────────────────┘
 | 
						|
  │                      │
 | 
						|
  │                      │
 | 
						|
  │                      ▼
 | 
						|
  │                    ┌────────────────────┐
 | 
						|
  │                    │  forts/short.txt   │
 | 
						|
  │                    └────────────────────┘
 | 
						|
  │                      │
 | 
						|
  │                      │
 | 
						|
  │                      ▼
 | 
						|
  │                    ┌────────────────────┐
 | 
						|
  └──────────────────▶ │ forts/big_fort.txt │
 | 
						|
                       └────────────────────┘
 | 
						|
```
 | 
						|
 | 
						|
### Gotcha: The Binary is Called `make2graph`
 | 
						|
 | 
						|
- Works with GUI tools maybe, IDK, I don't use Windows.
 | 
						|
- Some systems can use `graph-easy`, but it's outdated.
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Patsubst and Wildcards
 | 
						|
 | 
						|
 | 
						|
```make pats
 | 
						|
IMAGES = $(wildcard jpgs/*)
 | 
						|
COL = $(patsubst jpgs/%,collection/%,$(IMAGES))
 | 
						|
 | 
						|
.PHONY: show
 | 
						|
show:
 | 
						|
	$(info IMAGES is $(IMAGES))
 | 
						|
	$(info Col is $(COL))
 | 
						|
 | 
						|
.PHONY: output
 | 
						|
output: $(COL)
 | 
						|
 | 
						|
collection/%.jpg: jpgs/%.jpg
 | 
						|
	mkdir -p $(@D)
 | 
						|
	cp $< $@
 | 
						|
 | 
						|
```
 | 
						|
 | 
						|
***
 | 
						|
 | 
						|
# Use Cases
 | 
						|
 | 
						|
- Backups
 | 
						|
- Making Websites
 | 
						|
    * `git clone https://gitlab.com/bindrpg/blag`
 | 
						|
- `NOT installations`
 | 
						|
    - ...but maybe installations?
 | 
						|
- Setting
 |