Rework the build system to be more modular

Split most of the work off into make/base.mk and allow for easy wrappers
to be created around that that can build with different instrumentation
in their own build directory.

Create wrappers for the following:
 - release build
 - debug build
 - afl++ fuzzing build
 - static analysis with clang
 - clang memory sanitizer
 - clang address/undefined sanitizer
This commit is contained in:
omicron 2025-04-03 23:14:56 +02:00
parent 0d3881f680
commit 0f9ced8eb1
9 changed files with 102 additions and 50 deletions

View File

@ -1,54 +1,42 @@
.PHONY: all clean clean-objects clean-reports run sanitize validate fuzz
.PHONY: all clean distclean release debug afl asan msan validate analyze fuzz
CC=clang
LD=clang
CFLAGS=-Wall -Wextra -Wpedantic -O0 -g3 -std=c23 -fno-omit-frame-pointer -fno-optimize-sibling-calls -D_POSIX_C_SOURCE=200809L
LDFLAGS?=
debug:
make -rRf make/debug.mk all
SOURCES = $(shell find src/ -type f -name '*.c')
OBJECTS = $(SOURCES:.c=.o)
DEPENDENCIES = $(SOURCES:.c=.d)
TARGET?=oas
OUTPUTS=oas oas-asan oas-msan oas-afl
RUNARGUMENTS?=ast tests/input/valid.asm
all: $(TARGET)
all: debug release afl asan msan
run: $(TARGET)
./$(TARGET) $(RUNARGUMENTS)
release:
make -rRf make/release.mk all
afl:
make -rRf make/afl.mk all
fuzz:
make CC="afl-clang-fast" LD="afl-clang-fast" TARGET="oas-afl" clean-objects all
make clean-objects
mkdir -p reports/afl
afl-fuzz -i tests/input -o reports/afl -m none -- ./oas-afl -tokens @@
make -rRf make/afl.mk fuzz
sanitize:
make CFLAGS="$(CFLAGS) -fsanitize=address,undefined" \
LDFLAGS="-fsanitize=address,undefined" \
TARGET="oas-asan" clean-objects all
make CFLAGS="$(CFLAGS) -fsanitize=memory -fsanitize-memory-track-origins=2" \
LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2" \
TARGET="oas-msan" clean-objects all
make clean-objects
asan:
make -rRf make/asan.mk all
validate:
msan:
make -rRf make/msan.mk all
validate: asan msan debug
./validate.sh
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $^
analyze:
make -rRf make/analyze.mk clean all
%.o: %.c
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
clean:
make -rRf make/release.mk clean
make -rRf make/debug.mk clean
make -rRf make/afl.mk clean
make -rRf make/msan.mk clean
make -rRf make/asan.mk clean
make -rRf make/analyze.mk clean
rm -rf build/
-include $(DEPENDENCIES)
clean-objects:
rm -f $(OBJECTS) $(DEPENDENCIES)
clean-reports:
distclean: clean
make -rRf make/afl.mk distclean
make -rRf make/analyze.mk distclean
rm -rf reports/
clean: clean-objects
rm -f $(TARGET) $(OUTPUTS)

14
make/afl.mk Normal file
View File

@ -0,0 +1,14 @@
.PHONY: fuzz distclean
CC=afl-clang-fast
LD=afl-clang-fast
BUILD_DIR=build/afl/
-include make/base.mk
fuzz: $(BUILD_DIR)$(TARGET)
mkdir -p reports/afl
afl-fuzz -i tests/input -o reports/afl -m none -- ./$< -tokens @@
distclean: clean
rm -rf reports/afl

9
make/analyze.mk Normal file
View File

@ -0,0 +1,9 @@
BUILD_DIR=build/analyze/
-include make/base.mk
analyze:
mkdir -p reports/static-analysis
scan-build -o reports/static-analysis/ -plist-html --status-bugs make -rRf make/analyze.mk all
distclean: clean
rm -rf reports/static-analysis

5
make/asan.mk Normal file
View File

@ -0,0 +1,5 @@
CFLAGS=-Wall -Wextra -Wpedantic -O0 -g3 -std=c23 -fno-omit-frame-pointer -fno-optimize-sibling-calls -D_POSIX_C_SOURCE=200809L -fsanitize=address,undefined
LDFLAGS=-fsanitize=address,undefined
BUILD_DIR=build/asan/
-include make/base.mk

27
make/base.mk Normal file
View File

@ -0,0 +1,27 @@
.PHONY: all clean
CC?=clang
LD?=clang
CFLAGS?=-Wall -Wextra -Wpedantic -O0 -g3 -std=c23 -fno-omit-frame-pointer -fno-optimize-sibling-calls -D_POSIX_C_SOURCE=200809L
LDFLAGS?=
BUILD_DIR?=build/debug/
SOURCES?=$(shell find src/ -type f -name '*.c')
OBJECTS=$(patsubst %.c,$(BUILD_DIR)%.o,$(SOURCES))
DEPENDENCIES=$(OBJECTS:.o=.d)
TARGET?=oas
all: $(BUILD_DIR)$(TARGET)
$(BUILD_DIR)$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $^
$(BUILD_DIR)%.o: %.c
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
-include $(DEPENDENCIES)
clean:
rm -rf $(BUILD_DIR)

1
make/debug.mk Normal file
View File

@ -0,0 +1 @@
-include make/base.mk

5
make/msan.mk Normal file
View File

@ -0,0 +1,5 @@
CFLAGS=-Wall -Wextra -Wpedantic -O0 -g3 -std=c23 -fno-omit-frame-pointer -fno-optimize-sibling-calls -D_POSIX_C_SOURCE=200809L -fsanitize=memory
LDFLAGS=-fsanitize=memory
BUILD_DIR=build/msan/
-include make/base.mk

5
make/release.mk Normal file
View File

@ -0,0 +1,5 @@
CFLAGS?=-Wall -Wextra -Wpedantic -O2 -std=c23 -flto -fomit-frame-pointer -DNDEBUG -D_POSIX_C_SOURCE=200809L
LDFLAGS?=-flto -s -Wl,--gc-sections
BUILD_DIR?=build/release/
-include make/base.mk

View File

@ -2,19 +2,17 @@
set -euo pipefail
# Start with static analysis
make clean all
mkdir -p reports/static-analysis
scan-build -o reports/static-analysis/ -plist-html --status-bugs make all
make analyze debug asan msan
# Run the sanitizer builds and valgrind
make clean sanitize all
ASAN=build/asan/oas
MSAN=build/msan/oas
DEBUG=build/debug/oas
ARGUMENTS=("tokens" "text" "ast")
while IFS= read -r INPUT_FILE; do
for ARGS in ${ARGUMENTS[@]}; do
./oas-asan $ARGS $INPUT_FILE > /dev/null
./oas-msan $ARGS $INPUT_FILE > /dev/null
valgrind --leak-check=full --error-exitcode=1 ./oas $ARGS $INPUT_FILE >/dev/null
$ASAN $ARGS $INPUT_FILE > /dev/null
$MSAN $ARGS $INPUT_FILE > /dev/null
valgrind --leak-check=full --error-exitcode=1 $DEBUG $ARGS $INPUT_FILE >/dev/null
done
done < <(find tests/input/ -type f -name '*.asm')