Migrating from Make¶
A practical guide to converting Makefiles to Mustfile.toml.
Concept mapping¶
| Make | must |
|---|---|
Makefile |
Mustfile.toml |
target: deps |
[recipe.target] with deps |
| Recipe body (tab-indented) | script = "..." |
$(VAR) / ${VAR} |
${VAR} (same syntax) |
.PHONY: clean |
phony = true |
$(MAKE) -C subdir |
workdir = "subdir/" |
ifeq / ifdef |
[env.<profile>] or recipe-level env |
include other.mk |
[include] paths = [...] |
@echo "message" |
script = "echo 'message'" |
Pattern rules (%.o: %.c) |
No equivalent — use a loop or first-class type |
$(shell ...) |
Use must's built-in variable expansion |
$@, $<, $^ |
Expanded inline during import |
Step-by-step migration¶
1. Import¶
This generates Mustfile.toml and import-report.md.
2. Review the import report¶
Check for:
- Pattern rules that need manual conversion
- Complex variable expansions
- Implicit dependencies
3. Convert to first-class types¶
Replace generic shell recipes with language-specific types:
# Before
[recipe.build]
type = "shell"
script = "cargo build --release -p my-app"
# After
[recipe.build]
type = "rust-bin"
package = "my-app"
4. Move variables to [env]¶
5. Convert phony targets¶
# Mustfile.toml
[recipe.clean]
type = "shell"
phony = true
script = "rm -rf build/"
[recipe.test]
type = "rust-test"
package = "my-app"
6. Remove tab indentation¶
must uses TOML strings — no tab-significant whitespace.
Side-by-side comparison¶
Makefile:
CFLAGS := -O2 -Wall
SRC := $(wildcard src/*.c)
OBJ := $(SRC:.c=.o)
my-app: $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean test
test: my-app
./my-app --test
clean:
rm -f $(OBJ) my-app
Mustfile.toml: