Makefile 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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. VALGRIND ?= valgrind
  26. GDB ?= gdb
  27. PERF ?= perf
  28. SRC ?= $(filter-out $(wildcard *.*.c),$(wildcard *.c))
  29. OBJ := $(SRC:%.c=$(BUILDDIR)%.o)
  30. DEP := $(SRC:%.c=$(BUILDDIR)%.d)
  31. ASM := $(SRC:%.c=$(BUILDDIR)%.s)
  32. CI := $(SRC:%.c=$(BUILDDIR)%.ci)
  33. GCDA := $(SRC:%.c=$(BUILDDIR)%.t.a.gcda)
  34. TESTS ?= $(wildcard tests/*.toml)
  35. TEST_SRC ?= $(SRC) \
  36. $(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
  37. runners/test_runner.c
  38. TEST_RUNNER ?= $(BUILDDIR)runners/test_runner
  39. TEST_TC := $(TESTS:%.toml=$(BUILDDIR)%.t.c) \
  40. $(TEST_SRC:%.c=$(BUILDDIR)%.t.c)
  41. TEST_TAC := $(TEST_TC:%.t.c=%.t.a.c)
  42. TEST_OBJ := $(TEST_TAC:%.t.a.c=%.t.a.o)
  43. TEST_DEP := $(TEST_TAC:%.t.a.c=%.t.a.d)
  44. TEST_CI := $(TEST_TAC:%.t.a.c=%.t.a.ci)
  45. TEST_GCNO := $(TEST_TAC:%.t.a.c=%.t.a.gcno)
  46. TEST_GCDA := $(TEST_TAC:%.t.a.c=%.t.a.gcda)
  47. TEST_PERF := $(TEST_RUNNER:%=%.perf)
  48. TEST_TRACE := $(TEST_RUNNER:%=%.trace)
  49. BENCHES ?= $(wildcard benches/*.toml)
  50. BENCH_SRC ?= $(SRC) \
  51. $(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
  52. runners/bench_runner.c
  53. BENCH_RUNNER ?= $(BUILDDIR)runners/bench_runner
  54. BENCH_BC := $(BENCHES:%.toml=$(BUILDDIR)%.b.c) \
  55. $(BENCH_SRC:%.c=$(BUILDDIR)%.b.c)
  56. BENCH_BAC := $(BENCH_BC:%.b.c=%.b.a.c)
  57. BENCH_OBJ := $(BENCH_BAC:%.b.a.c=%.b.a.o)
  58. BENCH_DEP := $(BENCH_BAC:%.b.a.c=%.b.a.d)
  59. BENCH_CI := $(BENCH_BAC:%.b.a.c=%.b.a.ci)
  60. BENCH_GCNO := $(BENCH_BAC:%.b.a.c=%.b.a.gcno)
  61. BENCH_GCDA := $(BENCH_BAC:%.b.a.c=%.b.a.gcda)
  62. BENCH_PERF := $(BENCH_RUNNER:%=%.perf)
  63. BENCH_TRACE := $(BENCH_RUNNER:%=%.trace)
  64. ifdef DEBUG
  65. override CFLAGS += -O0
  66. else
  67. override CFLAGS += -Os
  68. endif
  69. ifdef TRACE
  70. override CFLAGS += -DLFS_YES_TRACE
  71. endif
  72. override CFLAGS += -g3
  73. override CFLAGS += -I.
  74. override CFLAGS += -std=c99 -Wall -pedantic
  75. override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
  76. override CFLAGS += -ftrack-macro-expansion=0
  77. ifdef YES_COV
  78. override CFLAGS += --coverage
  79. endif
  80. ifdef YES_PERF
  81. override CFLAGS += -fno-omit-frame-pointer
  82. endif
  83. ifdef YES_PERFBD
  84. override CFLAGS += -fno-omit-frame-pointer
  85. endif
  86. ifdef VERBOSE
  87. override CODEFLAGS += -v
  88. override DATAFLAGS += -v
  89. override STACKFLAGS += -v
  90. override STRUCTFLAGS += -v
  91. override COVFLAGS += -v
  92. override PERFFLAGS += -v
  93. override PERFBDFLAGS += -v
  94. endif
  95. # forward -j flag
  96. override PERFFLAGS += $(filter -j%,$(MAKEFLAGS))
  97. override PERFBDFLAGS += $(filter -j%,$(MAKEFLAGS))
  98. ifneq ($(NM),nm)
  99. override CODEFLAGS += --nm-tool="$(NM)"
  100. override DATAFLAGS += --nm-tool="$(NM)"
  101. endif
  102. ifneq ($(OBJDUMP),objdump)
  103. override CODEFLAGS += --objdump-tool="$(OBJDUMP)"
  104. override DATAFLAGS += --objdump-tool="$(OBJDUMP)"
  105. override STRUCTFLAGS += --objdump-tool="$(OBJDUMP)"
  106. override PERFFLAGS += --objdump-tool="$(OBJDUMP)"
  107. override PERFBDFLAGS += --objdump-tool="$(OBJDUMP)"
  108. endif
  109. ifneq ($(PERF),perf)
  110. override PERFFLAGS += --perf-tool="$(PERF)"
  111. endif
  112. override TESTFLAGS += -b
  113. override BENCHFLAGS += -b
  114. # forward -j flag
  115. override TESTFLAGS += $(filter -j%,$(MAKEFLAGS))
  116. override BENCHFLAGS += $(filter -j%,$(MAKEFLAGS))
  117. ifdef YES_PERF
  118. override TESTFLAGS += -p$(TEST_PERF)
  119. override BENCHFLAGS += -p$(BENCH_PERF)
  120. endif
  121. ifdef YES_PERFBD
  122. override TESTFLAGS += -t$(TEST_TRACE) --trace-backtrace --trace-freq=100
  123. endif
  124. ifndef NO_PERFBD
  125. override BENCHFLAGS += -t$(BENCH_TRACE) --trace-backtrace --trace-freq=100
  126. endif
  127. ifdef VERBOSE
  128. override TESTFLAGS += -v
  129. override TESTCFLAGS += -v
  130. override BENCHFLAGS += -v
  131. override BENCHCFLAGS += -v
  132. endif
  133. ifdef EXEC
  134. override TESTFLAGS += --exec="$(EXEC)"
  135. override BENCHFLAGS += --exec="$(EXEC)"
  136. endif
  137. ifneq ($(GDB),gdb)
  138. override TESTFLAGS += --gdb-tool="$(GDB)"
  139. override BENCHFLAGS += --gdb-tool="$(GDB)"
  140. endif
  141. ifneq ($(VALGRIND),valgrind)
  142. override TESTFLAGS += --valgrind-tool="$(VALGRIND)"
  143. override BENCHFLAGS += --valgrind-tool="$(VALGRIND)"
  144. endif
  145. ifneq ($(PERF),perf)
  146. override TESTFLAGS += --perf-tool="$(PERF)"
  147. override BENCHFLAGS += --perf-tool="$(PERF)"
  148. endif
  149. # commands
  150. .PHONY: all build
  151. all build: $(TARGET)
  152. .PHONY: asm
  153. asm: $(ASM)
  154. .PHONY: size
  155. size: $(OBJ)
  156. $(SIZE) -t $^
  157. .PHONY: tags
  158. tags:
  159. $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
  160. .PHONY: test-runner build-test
  161. ifndef NO_COV
  162. test-runner build-test: override CFLAGS+=--coverage
  163. endif
  164. ifdef YES_PERF
  165. bench-runner build-bench: override CFLAGS+=-fno-omit-frame-pointer
  166. endif
  167. ifdef YES_PERFBD
  168. bench-runner build-bench: override CFLAGS+=-fno-omit-frame-pointer
  169. endif
  170. # note we remove some binary dependent files during compilation,
  171. # otherwise it's way to easy to end up with outdated results
  172. test-runner build-test: $(TEST_RUNNER)
  173. ifndef NO_COV
  174. rm -f $(TEST_GCDA)
  175. endif
  176. ifdef YES_PERF
  177. rm -f $(TEST_PERF)
  178. endif
  179. ifdef YES_PERFBD
  180. rm -f $(TEST_TRACE)
  181. endif
  182. .PHONY: test
  183. test: test-runner
  184. ./scripts/test.py $(TEST_RUNNER) $(TESTFLAGS)
  185. .PHONY: test-list
  186. test-list: test-runner
  187. ./scripts/test.py $(TEST_RUNNER) $(TESTFLAGS) -l
  188. .PHONY: bench-runner build-bench
  189. ifdef YES_COV
  190. bench-runner build-bench: override CFLAGS+=--coverage
  191. endif
  192. ifdef YES_PERF
  193. bench-runner build-bench: override CFLAGS+=-fno-omit-frame-pointer
  194. endif
  195. ifndef NO_PERFBD
  196. bench-runner build-bench: override CFLAGS+=-fno-omit-frame-pointer
  197. endif
  198. # note we remove some binary dependent files during compilation,
  199. # otherwise it's way to easy to end up with outdated results
  200. bench-runner build-bench: $(BENCH_RUNNER)
  201. ifdef YES_COV
  202. rm -f $(BENCH_GCDA)
  203. endif
  204. ifdef YES_PERF
  205. rm -f $(BENCH_PERF)
  206. endif
  207. ifndef NO_PERFBD
  208. rm -f $(BENCH_TRACE)
  209. endif
  210. .PHONY: bench
  211. bench: bench-runner
  212. ./scripts/bench.py $(BENCH_RUNNER) $(BENCHFLAGS)
  213. .PHONY: bench-list
  214. bench-list: bench-runner
  215. ./scripts/bench.py $(BENCH_RUNNER) $(BENCHFLAGS) -l
  216. .PHONY: code
  217. code: $(OBJ)
  218. ./scripts/code.py $^ -Ssize $(CODEFLAGS)
  219. .PHONY: data
  220. data: $(OBJ)
  221. ./scripts/data.py $^ -Ssize $(DATAFLAGS)
  222. .PHONY: stack
  223. stack: $(CI)
  224. ./scripts/stack.py $^ -Slimit -Sframe $(STACKFLAGS)
  225. .PHONY: struct
  226. struct: $(OBJ)
  227. ./scripts/struct_.py $^ -Ssize $(STRUCTFLAGS)
  228. .PHONY: cov
  229. cov: $(GCDA)
  230. $(strip ./scripts/cov.py \
  231. $^ $(patsubst %,-F%,$(SRC)) \
  232. -slines -sbranches \
  233. $(COVFLAGS))
  234. .PHONY: perf
  235. perf: $(BENCH_PERF)
  236. $(strip ./scripts/perf.py \
  237. $^ $(patsubst %,-F%,$(SRC)) \
  238. -Scycles \
  239. $(PERFFLAGS))
  240. .PHONY: perfbd
  241. perfbd: $(BENCH_TRACE)
  242. $(strip ./scripts/perfbd.py \
  243. $(BENCH_RUNNER) $^ $(patsubst %,-F%,$(SRC)) \
  244. -Serased -Sproged -Sreaded \
  245. $(PERFBDFLAGS))
  246. .PHONY: summary sizes
  247. summary sizes: $(BUILDDIR)lfs.csv
  248. $(strip ./scripts/summary.py -Y $^ \
  249. -fcode=code_size \
  250. -fdata=data_size \
  251. -fstack=stack_limit \
  252. -fstruct=struct_size \
  253. --max=stack \
  254. $(SUMMARYFLAGS))
  255. # rules
  256. -include $(DEP)
  257. -include $(TEST_DEP)
  258. .SUFFIXES:
  259. .SECONDARY:
  260. $(BUILDDIR)lfs: $(OBJ)
  261. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  262. $(BUILDDIR)lfs.a: $(OBJ)
  263. $(AR) rcs $@ $^
  264. $(BUILDDIR)lfs.code.csv: $(OBJ)
  265. ./scripts/code.py $^ -q $(CODEFLAGS) -o $@
  266. $(BUILDDIR)lfs.data.csv: $(OBJ)
  267. ./scripts/data.py $^ -q $(CODEFLAGS) -o $@
  268. $(BUILDDIR)lfs.stack.csv: $(CI)
  269. ./scripts/stack.py $^ -q $(CODEFLAGS) -o $@
  270. $(BUILDDIR)lfs.struct.csv: $(OBJ)
  271. ./scripts/struct_.py $^ -q $(CODEFLAGS) -o $@
  272. $(BUILDDIR)lfs.cov.csv: $(GCDA)
  273. ./scripts/cov.py $^ $(patsubst %,-F%,$(SRC)) -q $(COVFLAGS) -o $@
  274. $(BUILDDIR)lfs.perf.csv: $(BENCH_PERF)
  275. ./scripts/perf.py $^ $(patsubst %,-F%,$(SRC)) -q $(PERFFLAGS) -o $@
  276. $(BUILDDIR)lfs.perfbd.csv: $(BENCH_TRACE)
  277. $(strip ./scripts/perfbd.py \
  278. $(BENCH_RUNNER) $^ $(patsubst %,-F%,$(SRC)) \
  279. -q $(PERFBDFLAGS) -o $@)
  280. $(BUILDDIR)lfs.csv: \
  281. $(BUILDDIR)lfs.code.csv \
  282. $(BUILDDIR)lfs.data.csv \
  283. $(BUILDDIR)lfs.stack.csv \
  284. $(BUILDDIR)lfs.struct.csv
  285. ./scripts/summary.py $^ -q $(SUMMARYFLAGS) -o $@
  286. $(BUILDDIR)runners/test_runner: $(TEST_OBJ)
  287. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  288. $(BUILDDIR)runners/bench_runner: $(BENCH_OBJ)
  289. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  290. # our main build rule generates .o, .d, and .ci files, the latter
  291. # used for stack analysis
  292. $(BUILDDIR)%.o $(BUILDDIR)%.ci: %.c
  293. $(CC) -c -MMD -fcallgraph-info=su $(CFLAGS) $< -o $(BUILDDIR)$*.o
  294. $(BUILDDIR)%.s: %.c
  295. $(CC) -S $(CFLAGS) $< -o $@
  296. $(BUILDDIR)%.a.c: %.c
  297. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  298. $(BUILDDIR)%.a.c: $(BUILDDIR)%.c
  299. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  300. $(BUILDDIR)%.t.c: %.toml
  301. ./scripts/test.py -c $< $(TESTCFLAGS) -o $@
  302. $(BUILDDIR)%.t.c: %.c $(TESTS)
  303. ./scripts/test.py -c $(TESTS) -s $< $(TESTCFLAGS) -o $@
  304. $(BUILDDIR)%.b.c: %.toml
  305. ./scripts/bench.py -c $< $(BENCHCFLAGS) -o $@
  306. $(BUILDDIR)%.b.c: %.c $(BENCHES)
  307. ./scripts/bench.py -c $(BENCHES) -s $< $(BENCHCFLAGS) -o $@
  308. # clean everything
  309. .PHONY: clean
  310. clean:
  311. rm -f $(BUILDDIR)lfs
  312. rm -f $(BUILDDIR)lfs.a
  313. $(strip rm -f \
  314. $(BUILDDIR)lfs.csv \
  315. $(BUILDDIR)lfs.code.csv \
  316. $(BUILDDIR)lfs.data.csv \
  317. $(BUILDDIR)lfs.stack.csv \
  318. $(BUILDDIR)lfs.struct.csv \
  319. $(BUILDDIR)lfs.cov.csv \
  320. $(BUILDDIR)lfs.perf.csv \
  321. $(BUILDDIR)lfs.perfbd.csv)
  322. rm -f $(OBJ)
  323. rm -f $(DEP)
  324. rm -f $(ASM)
  325. rm -f $(CI)
  326. rm -f $(TEST_RUNNER)
  327. rm -f $(TEST_TC)
  328. rm -f $(TEST_TAC)
  329. rm -f $(TEST_OBJ)
  330. rm -f $(TEST_DEP)
  331. rm -f $(TEST_CI)
  332. rm -f $(TEST_GCNO)
  333. rm -f $(TEST_GCDA)
  334. rm -f $(TEST_PERF)
  335. rm -f $(TEST_TRACE)
  336. rm -f $(BENCH_RUNNER)
  337. rm -f $(BENCH_BC)
  338. rm -f $(BENCH_BAC)
  339. rm -f $(BENCH_OBJ)
  340. rm -f $(BENCH_DEP)
  341. rm -f $(BENCH_CI)
  342. rm -f $(BENCH_GCNO)
  343. rm -f $(BENCH_GCDA)
  344. rm -f $(BENCH_PERF)
  345. rm -f $(BENCH_TRACE)