Makefile 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. ifdef BUILDDIR
  2. # make sure BUILDDIR ends with a slash
  3. override 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)runners \
  10. $(BUILDDIR)tests \
  11. $(BUILDDIR)benches))
  12. endif
  13. # overridable target/src/tools/flags/etc
  14. ifneq ($(wildcard test.c main.c),)
  15. TARGET ?= $(BUILDDIR)lfs
  16. else
  17. TARGET ?= $(BUILDDIR)lfs.a
  18. endif
  19. CC ?= gcc
  20. AR ?= ar
  21. SIZE ?= size
  22. CTAGS ?= ctags
  23. NM ?= nm
  24. OBJDUMP ?= objdump
  25. LCOV ?= lcov
  26. SRC ?= $(filter-out $(wildcard *.*.c),$(wildcard *.c))
  27. OBJ := $(SRC:%.c=$(BUILDDIR)%.o)
  28. DEP := $(SRC:%.c=$(BUILDDIR)%.d)
  29. ASM := $(SRC:%.c=$(BUILDDIR)%.s)
  30. CI := $(SRC:%.c=$(BUILDDIR)%.ci)
  31. GCDA := $(SRC:%.c=$(BUILDDIR)%.t.a.gcda)
  32. TESTS ?= $(wildcard tests/*.toml)
  33. TEST_SRC ?= $(SRC) \
  34. $(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
  35. runners/test_runner.c
  36. TEST_TC := $(TESTS:%.toml=$(BUILDDIR)%.t.c) $(TEST_SRC:%.c=$(BUILDDIR)%.t.c)
  37. TEST_TAC := $(TEST_TC:%.t.c=%.t.a.c)
  38. TEST_OBJ := $(TEST_TAC:%.t.a.c=%.t.a.o)
  39. TEST_DEP := $(TEST_TAC:%.t.a.c=%.t.a.d)
  40. TEST_CI := $(TEST_TAC:%.t.a.c=%.t.a.ci)
  41. TEST_GCNO := $(TEST_TAC:%.t.a.c=%.t.a.gcno)
  42. TEST_GCDA := $(TEST_TAC:%.t.a.c=%.t.a.gcda)
  43. BENCHES ?= $(wildcard benches/*.toml)
  44. BENCH_SRC ?= $(SRC) \
  45. $(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
  46. runners/bench_runner.c
  47. BENCH_BC := $(BENCHES:%.toml=$(BUILDDIR)%.b.c) $(BENCH_SRC:%.c=$(BUILDDIR)%.b.c)
  48. BENCH_BAC := $(BENCH_BC:%.b.c=%.b.a.c)
  49. BENCH_OBJ := $(BENCH_BAC:%.b.a.c=%.b.a.o)
  50. BENCH_DEP := $(BENCH_BAC:%.b.a.c=%.b.a.d)
  51. BENCH_CI := $(BENCH_BAC:%.b.a.c=%.b.a.ci)
  52. BENCH_GCNO := $(BENCH_BAC:%.b.a.c=%.b.a.gcno)
  53. BENCH_GCDA := $(BENCH_BAC:%.b.a.c=%.b.a.gcda)
  54. ifdef DEBUG
  55. override CFLAGS += -O0
  56. else
  57. override CFLAGS += -Os
  58. endif
  59. ifdef TRACE
  60. override CFLAGS += -DLFS_YES_TRACE
  61. endif
  62. override CFLAGS += -g3
  63. override CFLAGS += -I.
  64. override CFLAGS += -std=c99 -Wall -pedantic
  65. override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
  66. override CFLAGS += -ftrack-macro-expansion=0
  67. override TESTFLAGS += -b
  68. override BENCHFLAGS += -b
  69. # forward -j flag
  70. override TESTFLAGS += $(filter -j%,$(MAKEFLAGS))
  71. override BENCHFLAGS += $(filter -j%,$(MAKEFLAGS))
  72. ifdef VERBOSE
  73. override CODEFLAGS += -v
  74. override DATAFLAGS += -v
  75. override STACKFLAGS += -v
  76. override STRUCTFLAGS += -v
  77. override COVERAGEFLAGS += -v
  78. override TESTFLAGS += -v
  79. override TESTCFLAGS += -v
  80. override BENCHFLAGS += -v
  81. override BENCHCFLAGS += -v
  82. endif
  83. ifdef EXEC
  84. override TESTFLAGS += --exec="$(EXEC)"
  85. override BENCHFLAGS += --exec="$(EXEC)"
  86. endif
  87. ifdef BUILDDIR
  88. override CODEFLAGS += --build-dir="$(BUILDDIR:/=)"
  89. override DATAFLAGS += --build-dir="$(BUILDDIR:/=)"
  90. override STACKFLAGS += --build-dir="$(BUILDDIR:/=)"
  91. override STRUCTFLAGS += --build-dir="$(BUILDDIR:/=)"
  92. override COVERAGEFLAGS += --build-dir="$(BUILDDIR:/=)"
  93. endif
  94. ifneq ($(NM),nm)
  95. override CODEFLAGS += --nm-tool="$(NM)"
  96. override DATAFLAGS += --nm-tool="$(NM)"
  97. endif
  98. ifneq ($(OBJDUMP),objdump)
  99. override STRUCTFLAGS += --objdump-tool="$(OBJDUMP)"
  100. endif
  101. # commands
  102. .PHONY: all build
  103. all build: $(TARGET)
  104. .PHONY: asm
  105. asm: $(ASM)
  106. .PHONY: size
  107. size: $(OBJ)
  108. $(SIZE) -t $^
  109. .PHONY: tags
  110. tags:
  111. $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
  112. .PHONY: test-runner build-test
  113. test-runner build-test: override CFLAGS+=--coverage
  114. test-runner build-test: $(BUILDDIR)runners/test_runner
  115. rm -f $(TEST_GCDA)
  116. .PHONY: test
  117. test: test-runner
  118. ./scripts/test.py $(BUILDDIR)runners/test_runner $(TESTFLAGS)
  119. .PHONY: test-list
  120. test-list: test-runner
  121. ./scripts/test.py $(BUILDDIR)runners/test_runner $(TESTFLAGS) -l
  122. .PHONY: bench-runner build-bench
  123. bench-runner build-bench: $(BUILDDIR)runners/bench_runner
  124. .PHONY: bench
  125. bench: bench-runner
  126. ./scripts/bench.py $(BUILDDIR)runners/bench_runner $(BENCHFLAGS)
  127. .PHONY: bench-list
  128. bench-list: bench-runner
  129. ./scripts/bench.py $(BUILDDIR)runners/bench_runner $(BENCHFLAGS) -l
  130. .PHONY: code
  131. code: $(OBJ)
  132. ./scripts/code.py $^ -Ssize $(CODEFLAGS)
  133. .PHONY: data
  134. data: $(OBJ)
  135. ./scripts/data.py $^ -Ssize $(DATAFLAGS)
  136. .PHONY: stack
  137. stack: $(CI)
  138. ./scripts/stack.py $^ -Slimit -Sframe $(STACKFLAGS)
  139. .PHONY: struct
  140. struct: $(OBJ)
  141. ./scripts/struct_.py $^ -Ssize $(STRUCTFLAGS)
  142. .PHONY: coverage
  143. coverage: $(GCDA)
  144. ./scripts/coverage.py $^ -slines -sbranches $(COVERAGEFLAGS)
  145. .PHONY: summary sizes
  146. summary sizes: $(BUILDDIR)lfs.csv
  147. $(strip ./scripts/summary.py -Y $^ \
  148. -fcode=code_size \
  149. -fdata=data_size \
  150. -fstack=stack_limit \
  151. -fstruct=struct_size \
  152. --max=stack \
  153. $(SUMMARYFLAGS))
  154. # rules
  155. -include $(DEP)
  156. -include $(TEST_DEP)
  157. .SUFFIXES:
  158. .SECONDARY:
  159. $(BUILDDIR)lfs: $(OBJ)
  160. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  161. $(BUILDDIR)lfs.a: $(OBJ)
  162. $(AR) rcs $@ $^
  163. $(BUILDDIR)lfs.code.csv: $(OBJ)
  164. ./scripts/code.py $^ -q $(CODEFLAGS) -o $@
  165. $(BUILDDIR)lfs.data.csv: $(OBJ)
  166. ./scripts/data.py $^ -q $(CODEFLAGS) -o $@
  167. $(BUILDDIR)lfs.stack.csv: $(CI)
  168. ./scripts/stack.py $^ -q $(CODEFLAGS) -o $@
  169. $(BUILDDIR)lfs.struct.csv: $(OBJ)
  170. ./scripts/struct_.py $^ -q $(CODEFLAGS) -o $@
  171. $(BUILDDIR)lfs.coverage.csv: $(GCDA)
  172. ./scripts/coverage.py $^ -q $(COVERAGEFLAGS) -o $@
  173. $(BUILDDIR)lfs.csv: \
  174. $(BUILDDIR)lfs.code.csv \
  175. $(BUILDDIR)lfs.data.csv \
  176. $(BUILDDIR)lfs.stack.csv \
  177. $(BUILDDIR)lfs.struct.csv
  178. ./scripts/summary.py $^ -q $(SUMMARYFLAGS) -o $@
  179. $(BUILDDIR)runners/test_runner: $(TEST_OBJ)
  180. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  181. $(BUILDDIR)runners/bench_runner: $(BENCH_OBJ)
  182. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  183. # our main build rule generates .o, .d, and .ci files, the latter
  184. # used for stack analysis
  185. $(BUILDDIR)%.o $(BUILDDIR)%.ci: %.c
  186. $(CC) -c -MMD -fcallgraph-info=su $(CFLAGS) $< -o $(BUILDDIR)$*.o
  187. $(BUILDDIR)%.s: %.c
  188. $(CC) -S $(CFLAGS) $< -o $@
  189. $(BUILDDIR)%.a.c: %.c
  190. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  191. $(BUILDDIR)%.a.c: $(BUILDDIR)%.c
  192. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  193. $(BUILDDIR)%.t.c: %.toml
  194. ./scripts/test.py -c $< $(TESTCFLAGS) -o $@
  195. $(BUILDDIR)%.t.c: %.c $(TESTS)
  196. ./scripts/test.py -c $(TESTS) -s $< $(TESTCFLAGS) -o $@
  197. $(BUILDDIR)%.b.c: %.toml
  198. ./scripts/bench.py -c $< $(BENCHCFLAGS) -o $@
  199. $(BUILDDIR)%.b.c: %.c $(BENCHES)
  200. ./scripts/bench.py -c $(BENCHES) -s $< $(BENCHCFLAGS) -o $@
  201. # clean everything
  202. .PHONY: clean
  203. clean:
  204. rm -f $(BUILDDIR)lfs
  205. rm -f $(BUILDDIR)lfs.a
  206. $(strip rm -f \
  207. $(BUILDDIR)lfs.csv \
  208. $(BUILDDIR)lfs.code.csv \
  209. $(BUILDDIR)lfs.data.csv \
  210. $(BUILDDIR)lfs.stack.csv \
  211. $(BUILDDIR)lfs.struct.csv \
  212. $(BUILDDIR)lfs.coverage.csv)
  213. rm -f $(BUILDDIR)runners/test_runner
  214. rm -f $(BUILDDIR)runners/bench_runner
  215. rm -f $(OBJ)
  216. rm -f $(DEP)
  217. rm -f $(ASM)
  218. rm -f $(CI)
  219. rm -f $(TEST_TC)
  220. rm -f $(TEST_TAC)
  221. rm -f $(TEST_OBJ)
  222. rm -f $(TEST_DEP)
  223. rm -f $(TEST_CI)
  224. rm -f $(TEST_GCNO)
  225. rm -f $(TEST_GCDA)
  226. rm -f $(BENCH_BC)
  227. rm -f $(BENCH_BAC)
  228. rm -f $(BENCH_OBJ)
  229. rm -f $(BENCH_DEP)
  230. rm -f $(BENCH_CI)
  231. rm -f $(BENCH_GCNO)
  232. rm -f $(BENCH_GCDA)