acdea1880e
With more scripts generating CSV files this moves most CSV manipulation into summary.py, which can now handle more or less any arbitrary CSV file with arbitrary names and fields. This also includes a bunch of additional, probably unnecessary, tweaks: - summary.py/coverage.py use a custom fractional type for encoding fractions, this will also be used for test counts. - Added a smaller diff output for size scripts with the --percent flag. - Added line and hit info to coverage.py's CSV files. - Added --tree flag to stack.py to show only the call tree without other noise. - Renamed structs.py to struct.py. - Changed a few flags around for consistency between size/summary scripts. - Added `make sizes` alias. - Added `make lfs.code.csv` rules
233 lines
5.4 KiB
Makefile
233 lines
5.4 KiB
Makefile
ifdef BUILDDIR
|
|
# make sure BUILDDIR ends with a slash
|
|
override BUILDDIR := $(BUILDDIR)/
|
|
# bit of a hack, but we want to make sure BUILDDIR directory structure
|
|
# is correct before any commands
|
|
$(if $(findstring n,$(MAKEFLAGS)),, $(shell mkdir -p \
|
|
$(BUILDDIR) \
|
|
$(BUILDDIR)bd \
|
|
$(BUILDDIR)runners \
|
|
$(BUILDDIR)tests))
|
|
endif
|
|
|
|
# overridable target/src/tools/flags/etc
|
|
ifneq ($(wildcard test.c main.c),)
|
|
TARGET ?= $(BUILDDIR)lfs
|
|
else
|
|
TARGET ?= $(BUILDDIR)lfs.a
|
|
endif
|
|
|
|
|
|
CC ?= gcc
|
|
AR ?= ar
|
|
SIZE ?= size
|
|
CTAGS ?= ctags
|
|
NM ?= nm
|
|
OBJDUMP ?= objdump
|
|
LCOV ?= lcov
|
|
|
|
SRC ?= $(filter-out $(wildcard *.*.c),$(wildcard *.c))
|
|
OBJ := $(SRC:%.c=$(BUILDDIR)%.o)
|
|
DEP := $(SRC:%.c=$(BUILDDIR)%.d)
|
|
ASM := $(SRC:%.c=$(BUILDDIR)%.s)
|
|
CI := $(SRC:%.c=$(BUILDDIR)%.ci)
|
|
GCDA := $(SRC:%.c=$(BUILDDIR)%.t.a.gcda)
|
|
|
|
TESTS ?= $(wildcard tests/*.toml)
|
|
TEST_SRC ?= $(SRC) \
|
|
$(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
|
|
runners/test_runner.c
|
|
TEST_TC := $(TESTS:%.toml=$(BUILDDIR)%.t.c) $(TEST_SRC:%.c=$(BUILDDIR)%.t.c)
|
|
TEST_TAC := $(TEST_TC:%.t.c=%.t.a.c)
|
|
TEST_OBJ := $(TEST_TAC:%.t.a.c=%.t.a.o)
|
|
TEST_DEP := $(TEST_TAC:%.t.a.c=%.t.a.d)
|
|
TEST_CI := $(TEST_TAC:%.t.a.c=%.t.a.ci)
|
|
TEST_GCNO := $(TEST_TAC:%.t.a.c=%.t.a.gcno)
|
|
TEST_GCDA := $(TEST_TAC:%.t.a.c=%.t.a.gcda)
|
|
|
|
ifdef DEBUG
|
|
override CFLAGS += -O0
|
|
else
|
|
override CFLAGS += -Os
|
|
endif
|
|
ifdef TRACE
|
|
override CFLAGS += -DLFS_YES_TRACE
|
|
endif
|
|
override CFLAGS += -g3
|
|
override CFLAGS += -I.
|
|
override CFLAGS += -std=c99 -Wall -pedantic
|
|
override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
|
|
override CFLAGS += -ftrack-macro-expansion=0
|
|
|
|
override TESTFLAGS += -b
|
|
# forward -j flag
|
|
override TESTFLAGS += $(filter -j%,$(MAKEFLAGS))
|
|
ifdef VERBOSE
|
|
override TESTFLAGS += -v
|
|
override CODEFLAGS += -v
|
|
override DATAFLAGS += -v
|
|
override STACKFLAGS += -v
|
|
override STRUCTFLAGS += -v
|
|
override COVERAGEFLAGS += -v
|
|
override TESTFLAGS += -v
|
|
override TESTCFLAGS += -v
|
|
endif
|
|
ifdef EXEC
|
|
override TESTFLAGS += --exec="$(EXEC)"
|
|
endif
|
|
ifdef BUILDDIR
|
|
override CODEFLAGS += --build-dir="$(BUILDDIR:/=)"
|
|
override DATAFLAGS += --build-dir="$(BUILDDIR:/=)"
|
|
override STACKFLAGS += --build-dir="$(BUILDDIR:/=)"
|
|
override STRUCTFLAGS += --build-dir="$(BUILDDIR:/=)"
|
|
override COVERAGEFLAGS += --build-dir="$(BUILDDIR:/=)"
|
|
endif
|
|
ifneq ($(NM),nm)
|
|
override CODEFLAGS += --nm-tool="$(NM)"
|
|
override DATAFLAGS += --nm-tool="$(NM)"
|
|
endif
|
|
ifneq ($(OBJDUMP),objdump)
|
|
override STRUCTFLAGS += --objdump-tool="$(OBJDUMP)"
|
|
endif
|
|
|
|
|
|
# commands
|
|
.PHONY: all build
|
|
all build: $(TARGET)
|
|
|
|
.PHONY: asm
|
|
asm: $(ASM)
|
|
|
|
.PHONY: size
|
|
size: $(OBJ)
|
|
$(SIZE) -t $^
|
|
|
|
.PHONY: tags
|
|
tags:
|
|
$(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
|
|
|
|
.PHONY: test-runner build-test
|
|
test-runner build-test: override CFLAGS+=--coverage
|
|
test-runner build-test: $(BUILDDIR)runners/test_runner
|
|
rm -f $(TEST_GCDA)
|
|
|
|
.PHONY: test
|
|
test: test-runner
|
|
./scripts/test.py $(BUILDDIR)runners/test_runner $(TESTFLAGS)
|
|
|
|
.PHONY: test-list
|
|
test-list: test-runner
|
|
./scripts/test.py $(BUILDDIR)runners/test_runner $(TESTFLAGS) -l
|
|
|
|
.PHONY: code
|
|
code: $(OBJ)
|
|
./scripts/code.py $^ -S $(CODEFLAGS)
|
|
|
|
.PHONY: data
|
|
data: $(OBJ)
|
|
./scripts/data.py $^ -S $(DATAFLAGS)
|
|
|
|
.PHONY: stack
|
|
stack: $(CI)
|
|
./scripts/stack.py $^ -S $(STACKFLAGS)
|
|
|
|
.PHONY: struct
|
|
struct: $(OBJ)
|
|
./scripts/struct.py $^ -S $(STRUCTFLAGS)
|
|
|
|
.PHONY: coverage
|
|
coverage: $(GCDA)
|
|
./scripts/coverage.py $^ -s $(COVERAGEFLAGS)
|
|
|
|
.PHONY: summary sizes
|
|
summary sizes: $(BUILDDIR)lfs.csv
|
|
$(strip ./scripts/summary.py -Y $^ \
|
|
-f code=code_size,$\
|
|
data=data_size,$\
|
|
stack=stack_limit,$\
|
|
struct=struct_size \
|
|
$(SUMMARYFLAGS))
|
|
|
|
|
|
# rules
|
|
-include $(DEP)
|
|
-include $(TEST_DEP)
|
|
.SUFFIXES:
|
|
.SECONDARY:
|
|
|
|
$(BUILDDIR)lfs: $(OBJ)
|
|
$(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.a: $(OBJ)
|
|
$(AR) rcs $@ $^
|
|
|
|
$(BUILDDIR)lfs.code.csv: $(OBJ)
|
|
./scripts/code.py $^ -q $(CODEFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.data.csv: $(OBJ)
|
|
./scripts/data.py $^ -q $(CODEFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.stack.csv: $(CI)
|
|
./scripts/stack.py $^ -q $(CODEFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.struct.csv: $(OBJ)
|
|
./scripts/struct.py $^ -q $(CODEFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.coverage.csv: $(GCDA)
|
|
./scripts/coverage.py $^ -q $(COVERAGEFLAGS) -o $@
|
|
|
|
$(BUILDDIR)lfs.csv: \
|
|
$(BUILDDIR)lfs.code.csv \
|
|
$(BUILDDIR)lfs.data.csv \
|
|
$(BUILDDIR)lfs.stack.csv \
|
|
$(BUILDDIR)lfs.struct.csv
|
|
./scripts/summary.py $^ -q $(SUMMARYFLAGS) -o $@
|
|
|
|
$(BUILDDIR)runners/test_runner: $(TEST_OBJ)
|
|
$(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
|
|
|
|
# our main build rule generates .o, .d, and .ci files, the latter
|
|
# used for stack analysis
|
|
$(BUILDDIR)%.o $(BUILDDIR)%.ci: %.c
|
|
$(CC) -c -MMD -fcallgraph-info=su $(CFLAGS) $< -o $(BUILDDIR)$*.o
|
|
|
|
$(BUILDDIR)%.s: %.c
|
|
$(CC) -S $(CFLAGS) $< -o $@
|
|
|
|
$(BUILDDIR)%.a.c: %.c
|
|
./scripts/pretty_asserts.py -p LFS_ASSERT $< -o $@
|
|
|
|
$(BUILDDIR)%.a.c: $(BUILDDIR)%.c
|
|
./scripts/pretty_asserts.py -p LFS_ASSERT $< -o $@
|
|
|
|
$(BUILDDIR)%.t.c: %.toml
|
|
./scripts/test.py -c $< $(TESTCFLAGS) -o $@
|
|
|
|
$(BUILDDIR)%.t.c: %.c $(TESTS)
|
|
./scripts/test.py -c $(TESTS) -s $< $(TESTCFLAGS) -o $@
|
|
|
|
# clean everything
|
|
.PHONY: clean
|
|
clean:
|
|
rm -f $(BUILDDIR)lfs
|
|
rm -f $(BUILDDIR)lfs.a
|
|
$(strip rm -f \
|
|
$(BUILDDIR)lfs.csv \
|
|
$(BUILDDIR)lfs.code.csv \
|
|
$(BUILDDIR)lfs.data.csv \
|
|
$(BUILDDIR)lfs.stack.csv \
|
|
$(BUILDDIR)lfs.struct.csv \
|
|
$(BUILDDIR)lfs.coverage.csv)
|
|
rm -f $(BUILDDIR)runners/test_runner
|
|
rm -f $(OBJ)
|
|
rm -f $(DEP)
|
|
rm -f $(ASM)
|
|
rm -f $(CI)
|
|
rm -f $(TEST_TC)
|
|
rm -f $(TEST_TAC)
|
|
rm -f $(TEST_OBJ)
|
|
rm -f $(TEST_DEP)
|
|
rm -f $(TEST_CI)
|
|
rm -f $(TEST_GCNO)
|
|
rm -f $(TEST_GCDA)
|