Makefile 9.6 KB

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