1ifdef BUILDDIR 2# make sure BUILDDIR ends with a slash 3override BUILDDIR := $(BUILDDIR)/ 4# bit of a hack, but we want to make sure BUILDDIR directory structure 5# is correct before any commands 6$(if $(findstring n,$(MAKEFLAGS)),, $(shell mkdir -p \ 7 $(BUILDDIR) \ 8 $(BUILDDIR)bd \ 9 $(BUILDDIR)tests)) 10endif 11 12# overridable target/src/tools/flags/etc 13ifneq ($(wildcard test.c main.c),) 14TARGET ?= $(BUILDDIR)lfs 15else 16TARGET ?= $(BUILDDIR)lfs.a 17endif 18 19 20CC ?= gcc 21AR ?= ar 22SIZE ?= size 23CTAGS ?= ctags 24NM ?= nm 25OBJDUMP ?= objdump 26LCOV ?= lcov 27 28SRC ?= $(wildcard *.c) 29OBJ := $(SRC:%.c=$(BUILDDIR)%.o) 30DEP := $(SRC:%.c=$(BUILDDIR)%.d) 31ASM := $(SRC:%.c=$(BUILDDIR)%.s) 32CGI := $(SRC:%.c=$(BUILDDIR)%.ci) 33 34ifdef DEBUG 35override CFLAGS += -O0 36else 37override CFLAGS += -Os 38endif 39ifdef TRACE 40override CFLAGS += -DLFS_YES_TRACE 41endif 42override CFLAGS += -g3 43override CFLAGS += -I. 44override CFLAGS += -std=c99 -Wall -pedantic 45override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef 46 47ifdef VERBOSE 48override TESTFLAGS += -v 49override CALLSFLAGS += -v 50override CODEFLAGS += -v 51override DATAFLAGS += -v 52override STACKFLAGS += -v 53override STRUCTSFLAGS += -v 54override COVERAGEFLAGS += -v 55endif 56ifdef EXEC 57override TESTFLAGS += --exec="$(EXEC)" 58endif 59ifdef COVERAGE 60override TESTFLAGS += --coverage 61endif 62ifdef BUILDDIR 63override TESTFLAGS += --build-dir="$(BUILDDIR:/=)" 64override CALLSFLAGS += --build-dir="$(BUILDDIR:/=)" 65override CODEFLAGS += --build-dir="$(BUILDDIR:/=)" 66override DATAFLAGS += --build-dir="$(BUILDDIR:/=)" 67override STACKFLAGS += --build-dir="$(BUILDDIR:/=)" 68override STRUCTSFLAGS += --build-dir="$(BUILDDIR:/=)" 69override COVERAGEFLAGS += --build-dir="$(BUILDDIR:/=)" 70endif 71ifneq ($(NM),nm) 72override CODEFLAGS += --nm-tool="$(NM)" 73override DATAFLAGS += --nm-tool="$(NM)" 74endif 75ifneq ($(OBJDUMP),objdump) 76override STRUCTSFLAGS += --objdump-tool="$(OBJDUMP)" 77endif 78 79 80# commands 81.PHONY: all build 82all build: $(TARGET) 83 84.PHONY: asm 85asm: $(ASM) 86 87.PHONY: size 88size: $(OBJ) 89 $(SIZE) -t $^ 90 91.PHONY: tags 92tags: 93 $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC) 94 95.PHONY: calls 96calls: $(CGI) 97 ./scripts/calls.py $^ $(CALLSFLAGS) 98 99.PHONY: test 100test: 101 ./scripts/test.py $(TESTFLAGS) 102.SECONDEXPANSION: 103test%: tests/test$$(firstword $$(subst \#, ,%)).toml 104 ./scripts/test.py $@ $(TESTFLAGS) 105 106.PHONY: code 107code: $(OBJ) 108 ./scripts/code.py $^ -S $(CODEFLAGS) 109 110.PHONY: data 111data: $(OBJ) 112 ./scripts/data.py $^ -S $(DATAFLAGS) 113 114.PHONY: stack 115stack: $(CGI) 116 ./scripts/stack.py $^ -S $(STACKFLAGS) 117 118.PHONY: structs 119structs: $(OBJ) 120 ./scripts/structs.py $^ -S $(STRUCTSFLAGS) 121 122.PHONY: coverage 123coverage: 124 ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info -s $(COVERAGEFLAGS) 125 126.PHONY: summary 127summary: $(BUILDDIR)lfs.csv 128 ./scripts/summary.py -Y $^ $(SUMMARYFLAGS) 129 130 131# rules 132-include $(DEP) 133.SUFFIXES: 134 135$(BUILDDIR)lfs: $(OBJ) 136 $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@ 137 138$(BUILDDIR)lfs.a: $(OBJ) 139 $(AR) rcs $@ $^ 140 141$(BUILDDIR)lfs.csv: $(OBJ) $(CGI) 142 ./scripts/code.py $(OBJ) -q $(CODEFLAGS) -o $@ 143 ./scripts/data.py $(OBJ) -q -m $@ $(DATAFLAGS) -o $@ 144 ./scripts/stack.py $(CGI) -q -m $@ $(STACKFLAGS) -o $@ 145 ./scripts/structs.py $(OBJ) -q -m $@ $(STRUCTSFLAGS) -o $@ 146 $(if $(COVERAGE),\ 147 ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info \ 148 -q -m $@ $(COVERAGEFLAGS) -o $@) 149 150$(BUILDDIR)%.o: %.c 151 $(CC) -c -MMD $(CFLAGS) $< -o $@ 152 153$(BUILDDIR)%.s: %.c 154 $(CC) -S $(CFLAGS) $< -o $@ 155 156# gcc depends on the output file for intermediate file names, so 157# we can't omit to .o output. We also need to serialize with the 158# normal .o rule because otherwise we can end up with multiprocess 159# problems with two instances of gcc modifying the same .o 160$(BUILDDIR)%.ci: %.c | $(BUILDDIR)%.o 161 $(CC) -c -MMD -fcallgraph-info=su $(CFLAGS) $< -o $| 162 163# clean everything 164.PHONY: clean 165clean: 166 rm -f $(BUILDDIR)lfs 167 rm -f $(BUILDDIR)lfs.a 168 rm -f $(BUILDDIR)lfs.csv 169 rm -f $(OBJ) 170 rm -f $(CGI) 171 rm -f $(DEP) 172 rm -f $(ASM) 173 rm -f $(BUILDDIR)tests/*.toml.* 174