This project extends OpenBSD's make utility to support GNU Make-style pattern rules.
Pattern rules define how to build targets based on filename patterns using the % wildcard character. Unlike suffix rules, pattern rules:
- Use explicit patterns (e.g.,
%.o: %.c) instead of implicit suffix lists - Support patterns anywhere in the filename, not just at the end
- Allow multiple wildcards and complex transformations
- Provide clearer and more maintainable Makefiles
- Are the standard in GNU Make and more widely understood
Suffix Rules (traditional):
.SUFFIXES: .c .o
.c.o:
cc -c $<Pattern Rules (modern):
%.o: %.c
cc -c $< -o $@Pattern rules offer:
- Better readability: the relationship between source and target is explicit
- More flexibility: patterns can match any part of the filename
- Automatic variables:
$@(target),$<(first prerequisite),$^(all prerequisites) - Compatibility: widely used in modern build systems
%.o: %.c
gcc -c $< -o $@Builds foo.o from foo.c, bar.o from bar.c, etc.
%.o: %.c %.h
gcc -c $< -o $@build/%.o: src/%.c
gcc -c $< -o $@%.pdf: %.tex
pdflatex $<
%.html: %.md
markdown $< > $@This implementation adds pattern rule support to OpenBSD make through the following key modifications:
-
Pattern Detection and Matching (
targ.c,targ.h)match_pattern(): Matches filenames against patterns with%wildcardsTarg_FindPatternMatchingNode(): Searches for pattern rules matching a targetTarg_BuildFromPattern(): Expands pattern rules into concrete targets- Pattern nodes tracking via
is_patternflag in GNode structure
-
Dynamic Target Creation (
targ.c)Targ_CreateNodeFromPattern(): Creates new targets from pattern templates- Pattern expansion: replaces
%with matched stem - Command copying: transfers recipes from pattern to concrete targets
- Temporary target management:
is_tmpflag for intermediate files - New GNode fields (
gnode.h):is_pattern: Indicates if the node represents a pattern ruleexpanded_from: Points to the original pattern nodeis_tmp: Marks temporary targets for cleanup
-
Children Expansion (
expandchildren.c)- Modified
expand_children_from()to search for pattern matches - Automatic prerequisite generation from pattern rules
- Fallback to pattern rules when no explicit dependencies exist
- Modified
-
Directory Search (
dir.c)find_file_hashi_with_pattern(): Pattern-aware file lookup- Integration with existing directory caching mechanism
-
Debug Support (
defines.h,main.c)- New
DEBUG_PATTERNflag (0x100000) - Activated with
-dPcommand-line option - Detailed pattern matching trace output
- New
-
Cleanup (
engine.c)Targ_RemoveAllTmpChildren(): Removes intermediate files after build- Automatic cleanup of temporary pattern-generated targets
The project uses OpenBSD's standard make build system:
cd make
makeThis produces the make binary with pattern support enabled.
The project includes a comprehensive test suite in testsuite_patterns/:
cd testsuite_patterns
./launch_testsuite.shcd testsuite_patterns/01-basic-pattern
../../make/make- 01-04: Basic pattern matching
- 05-09: Multiple targets and rules
- 10-12: Special operators and directory patterns
- 13-14: Pattern priority and automatic variables
- 15-18: Edge cases (empty stems, subdirectories)
- 19-23: Target types (secondary, intermediate, VPATH)
- 24-32: Advanced features (static patterns, nested patterns, terminal rules)
Enable verbose pattern matching output:
../../make/make -dPThis implementation maintains backward compatibility with OpenBSD make while adding GNU Make pattern rule semantics. Traditional suffix rules continue to work as before.
This project is based on OpenBSD make, which is distributed under the BSD license. See individual source files for detailed copyright information.