Makefile 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. # overrideable build dir, default is in-place
  2. BUILDDIR ?= .
  3. # overridable target/src/tools/flags/etc
  4. ifneq ($(wildcard test.c main.c),)
  5. TARGET ?= $(BUILDDIR)/lfs
  6. else
  7. TARGET ?= $(BUILDDIR)/liblfs.a
  8. endif
  9. CC ?= gcc
  10. AR ?= ar
  11. SIZE ?= size
  12. CTAGS ?= ctags
  13. NM ?= nm
  14. OBJDUMP ?= objdump
  15. VALGRIND ?= valgrind
  16. GDB ?= gdb
  17. PERF ?= perf
  18. # guess clang or gcc (clang sometimes masquerades as gcc because of
  19. # course it does)
  20. ifneq ($(shell $(CC) --version | grep clang),)
  21. NO_GCC = 1
  22. endif
  23. SRC ?= $(filter-out $(wildcard *.t.* *.b.*),$(wildcard *.c))
  24. OBJ := $(SRC:%.c=$(BUILDDIR)/%.o)
  25. DEP := $(SRC:%.c=$(BUILDDIR)/%.d)
  26. ASM := $(SRC:%.c=$(BUILDDIR)/%.s)
  27. CI := $(SRC:%.c=$(BUILDDIR)/%.ci)
  28. GCDA := $(SRC:%.c=$(BUILDDIR)/%.t.gcda)
  29. TESTS ?= $(wildcard tests/*.toml)
  30. TEST_SRC ?= $(SRC) \
  31. $(filter-out $(wildcard bd/*.t.* bd/*.b.*),$(wildcard bd/*.c)) \
  32. runners/test_runner.c
  33. TEST_RUNNER ?= $(BUILDDIR)/runners/test_runner
  34. TEST_A := $(TESTS:%.toml=$(BUILDDIR)/%.t.a.c) \
  35. $(TEST_SRC:%.c=$(BUILDDIR)/%.t.a.c)
  36. TEST_C := $(TEST_A:%.t.a.c=%.t.c)
  37. TEST_OBJ := $(TEST_C:%.t.c=%.t.o)
  38. TEST_DEP := $(TEST_C:%.t.c=%.t.d)
  39. TEST_CI := $(TEST_C:%.t.c=%.t.ci)
  40. TEST_GCNO := $(TEST_C:%.t.c=%.t.gcno)
  41. TEST_GCDA := $(TEST_C:%.t.c=%.t.gcda)
  42. TEST_PERF := $(TEST_RUNNER:%=%.perf)
  43. TEST_TRACE := $(TEST_RUNNER:%=%.trace)
  44. TEST_CSV := $(TEST_RUNNER:%=%.csv)
  45. BENCHES ?= $(wildcard benches/*.toml)
  46. BENCH_SRC ?= $(SRC) \
  47. $(filter-out $(wildcard bd/*.t.* bd/*.b.*),$(wildcard bd/*.c)) \
  48. runners/bench_runner.c
  49. BENCH_RUNNER ?= $(BUILDDIR)/runners/bench_runner
  50. BENCH_A := $(BENCHES:%.toml=$(BUILDDIR)/%.b.a.c) \
  51. $(BENCH_SRC:%.c=$(BUILDDIR)/%.b.a.c)
  52. BENCH_C := $(BENCH_A:%.b.a.c=%.b.c)
  53. BENCH_OBJ := $(BENCH_C:%.b.c=%.b.o)
  54. BENCH_DEP := $(BENCH_C:%.b.c=%.b.d)
  55. BENCH_CI := $(BENCH_C:%.b.c=%.b.ci)
  56. BENCH_GCNO := $(BENCH_C:%.b.c=%.b.gcno)
  57. BENCH_GCDA := $(BENCH_C:%.b.c=%.b.gcda)
  58. BENCH_PERF := $(BENCH_RUNNER:%=%.perf)
  59. BENCH_TRACE := $(BENCH_RUNNER:%=%.trace)
  60. BENCH_CSV := $(BENCH_RUNNER:%=%.csv)
  61. CFLAGS += -g3
  62. CFLAGS += -I.
  63. CFLAGS += -std=c99 -Wall -Wextra -pedantic
  64. CFLAGS += -Wmissing-prototypes
  65. ifndef NO_GCC
  66. CFLAGS += -fcallgraph-info=su
  67. CFLAGS += -ftrack-macro-expansion=0
  68. endif
  69. ifdef DEBUG
  70. CFLAGS += -O0
  71. else
  72. CFLAGS += -Os
  73. endif
  74. ifdef TRACE
  75. CFLAGS += -DLFS_YES_TRACE
  76. endif
  77. ifdef YES_COV
  78. CFLAGS += --coverage
  79. endif
  80. ifdef YES_PERF
  81. CFLAGS += -fno-omit-frame-pointer
  82. endif
  83. ifdef YES_PERFBD
  84. CFLAGS += -fno-omit-frame-pointer
  85. endif
  86. ifdef VERBOSE
  87. CODEFLAGS += -v
  88. DATAFLAGS += -v
  89. STACKFLAGS += -v
  90. STRUCTSFLAGS += -v
  91. COVFLAGS += -v
  92. PERFFLAGS += -v
  93. PERFBDFLAGS += -v
  94. endif
  95. # forward -j flag
  96. PERFFLAGS += $(filter -j%,$(MAKEFLAGS))
  97. PERFBDFLAGS += $(filter -j%,$(MAKEFLAGS))
  98. ifneq ($(NM),nm)
  99. CODEFLAGS += --nm-path="$(NM)"
  100. DATAFLAGS += --nm-path="$(NM)"
  101. endif
  102. ifneq ($(OBJDUMP),objdump)
  103. CODEFLAGS += --objdump-path="$(OBJDUMP)"
  104. DATAFLAGS += --objdump-path="$(OBJDUMP)"
  105. STRUCTSFLAGS += --objdump-path="$(OBJDUMP)"
  106. PERFFLAGS += --objdump-path="$(OBJDUMP)"
  107. PERFBDFLAGS += --objdump-path="$(OBJDUMP)"
  108. endif
  109. ifneq ($(PERF),perf)
  110. PERFFLAGS += --perf-path="$(PERF)"
  111. endif
  112. TESTFLAGS += -b
  113. BENCHFLAGS += -b
  114. # forward -j flag
  115. TESTFLAGS += $(filter -j%,$(MAKEFLAGS))
  116. BENCHFLAGS += $(filter -j%,$(MAKEFLAGS))
  117. ifdef YES_PERF
  118. TESTFLAGS += -p $(TEST_PERF)
  119. BENCHFLAGS += -p $(BENCH_PERF)
  120. endif
  121. ifdef YES_PERFBD
  122. TESTFLAGS += -t $(TEST_TRACE) --trace-backtrace --trace-freq=100
  123. endif
  124. ifndef NO_PERFBD
  125. BENCHFLAGS += -t $(BENCH_TRACE) --trace-backtrace --trace-freq=100
  126. endif
  127. ifdef YES_TESTMARKS
  128. TESTFLAGS += -o $(TEST_CSV)
  129. endif
  130. ifndef NO_BENCHMARKS
  131. BENCHFLAGS += -o $(BENCH_CSV)
  132. endif
  133. ifdef VERBOSE
  134. TESTFLAGS += -v
  135. TESTCFLAGS += -v
  136. BENCHFLAGS += -v
  137. BENCHCFLAGS += -v
  138. endif
  139. ifdef EXEC
  140. TESTFLAGS += --exec="$(EXEC)"
  141. BENCHFLAGS += --exec="$(EXEC)"
  142. endif
  143. ifneq ($(GDB),gdb)
  144. TESTFLAGS += --gdb-path="$(GDB)"
  145. BENCHFLAGS += --gdb-path="$(GDB)"
  146. endif
  147. ifneq ($(VALGRIND),valgrind)
  148. TESTFLAGS += --valgrind-path="$(VALGRIND)"
  149. BENCHFLAGS += --valgrind-path="$(VALGRIND)"
  150. endif
  151. ifneq ($(PERF),perf)
  152. TESTFLAGS += --perf-path="$(PERF)"
  153. BENCHFLAGS += --perf-path="$(PERF)"
  154. endif
  155. # this is a bit of a hack, but we want to make sure the BUILDDIR
  156. # directory structure is correct before we run any commands
  157. ifneq ($(BUILDDIR),.)
  158. $(if $(findstring n,$(MAKEFLAGS)),, $(shell mkdir -p \
  159. $(addprefix $(BUILDDIR)/,$(dir \
  160. $(SRC) \
  161. $(TESTS) \
  162. $(TEST_SRC) \
  163. $(BENCHES) \
  164. $(BENCH_SRC)))))
  165. endif
  166. # commands
  167. ## Build littlefs
  168. .PHONY: all build
  169. all build: $(TARGET)
  170. ## Build assembly files
  171. .PHONY: asm
  172. asm: $(ASM)
  173. ## Find the total size
  174. .PHONY: size
  175. size: $(OBJ)
  176. $(SIZE) -t $^
  177. ## Generate a ctags file
  178. .PHONY: tags
  179. tags:
  180. $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
  181. ## Show this help text
  182. .PHONY: help
  183. help:
  184. @$(strip awk '/^## / { \
  185. sub(/^## /,""); \
  186. getline rule; \
  187. while (rule ~ /^(#|\.PHONY|ifdef|ifndef)/) getline rule; \
  188. gsub(/:.*/, "", rule); \
  189. printf " "" %-25s %s\n", rule, $$0 \
  190. }' $(MAKEFILE_LIST))
  191. ## Find the per-function code size
  192. .PHONY: code
  193. code: CODEFLAGS+=-S
  194. code: $(OBJ) $(BUILDDIR)/lfs.code.csv
  195. ./scripts/code.py $(OBJ) $(CODEFLAGS)
  196. ## Compare per-function code size
  197. .PHONY: code-diff
  198. code-diff: $(OBJ)
  199. ./scripts/code.py $^ $(CODEFLAGS) -d $(BUILDDIR)/lfs.code.csv
  200. ## Find the per-function data size
  201. .PHONY: data
  202. data: DATAFLAGS+=-S
  203. data: $(OBJ) $(BUILDDIR)/lfs.data.csv
  204. ./scripts/data.py $(OBJ) $(DATAFLAGS)
  205. ## Compare per-function data size
  206. .PHONY: data-diff
  207. data-diff: $(OBJ)
  208. ./scripts/data.py $^ $(DATAFLAGS) -d $(BUILDDIR)/lfs.data.csv
  209. ## Find the per-function stack usage
  210. .PHONY: stack
  211. stack: STACKFLAGS+=-S
  212. stack: $(CI) $(BUILDDIR)/lfs.stack.csv
  213. ./scripts/stack.py $(CI) $(STACKFLAGS)
  214. ## Compare per-function stack usage
  215. .PHONY: stack-diff
  216. stack-diff: $(CI)
  217. ./scripts/stack.py $^ $(STACKFLAGS) -d $(BUILDDIR)/lfs.stack.csv
  218. ## Find function sizes
  219. .PHONY: funcs
  220. funcs: SUMMARYFLAGS+=-S
  221. funcs: \
  222. $(BUILDDIR)/lfs.code.csv \
  223. $(BUILDDIR)/lfs.data.csv \
  224. $(BUILDDIR)/lfs.stack.csv
  225. $(strip ./scripts/summary.py $^ \
  226. -bfunction \
  227. -fcode=code_size \
  228. -fdata=data_size \
  229. -fstack=stack_limit --max=stack \
  230. $(SUMMARYFLAGS))
  231. ## Compare function sizes
  232. .PHONY: funcs-diff
  233. funcs-diff: SHELL=/bin/bash
  234. funcs-diff: $(OBJ) $(CI)
  235. $(strip ./scripts/summary.py \
  236. <(./scripts/code.py $(OBJ) -q $(CODEFLAGS) -o-) \
  237. <(./scripts/data.py $(OBJ) -q $(DATAFLAGS) -o-) \
  238. <(./scripts/stack.py $(CI) -q $(STACKFLAGS) -o-) \
  239. -bfunction \
  240. -fcode=code_size \
  241. -fdata=data_size \
  242. -fstack=stack_limit --max=stack \
  243. $(SUMMARYFLAGS) -d <(./scripts/summary.py \
  244. $(BUILDDIR)/lfs.code.csv \
  245. $(BUILDDIR)/lfs.data.csv \
  246. $(BUILDDIR)/lfs.stack.csv \
  247. -q $(SUMMARYFLAGS) -o-))
  248. ## Find struct sizes
  249. .PHONY: structs
  250. structs: STRUCTSFLAGS+=-S
  251. structs: $(OBJ) $(BUILDDIR)/lfs.structs.csv
  252. ./scripts/structs.py $(OBJ) $(STRUCTSFLAGS)
  253. ## Compare struct sizes
  254. .PHONY: structs-diff
  255. structs-diff: $(OBJ)
  256. ./scripts/structs.py $^ $(STRUCTSFLAGS) -d $(BUILDDIR)/lfs.structs.csv
  257. ## Find the line/branch coverage after a test run
  258. .PHONY: cov
  259. cov: COVFLAGS+=-s
  260. cov: $(GCDA) $(BUILDDIR)/lfs.cov.csv
  261. $(strip ./scripts/cov.py $(GCDA) \
  262. $(patsubst %,-F%,$(SRC)) \
  263. $(COVFLAGS))
  264. ## Compare line/branch coverage
  265. .PHONY: cov-diff
  266. cov-diff: $(GCDA)
  267. $(strip ./scripts/cov.py $^ \
  268. $(patsubst %,-F%,$(SRC)) \
  269. $(COVFLAGS) -d $(BUILDDIR)/lfs.cov.csv)
  270. ## Find the perf results after bench run with YES_PERF
  271. .PHONY: perf
  272. perf: PERFFLAGS+=-S
  273. perf: $(BENCH_PERF) $(BUILDDIR)/lfs.perf.csv
  274. $(strip ./scripts/perf.py $(BENCH_PERF) \
  275. $(patsubst %,-F%,$(SRC)) \
  276. $(PERFFLAGS))
  277. ## Compare perf results
  278. .PHONY: perf-diff
  279. perf-diff: $(BENCH_PERF)
  280. $(strip ./scripts/perf.py $^ \
  281. $(patsubst %,-F%,$(SRC)) \
  282. $(PERFFLAGS) -d $(BUILDDIR)/lfs.perf.csv)
  283. ## Find the perfbd results after a bench run
  284. .PHONY: perfbd
  285. perfbd: PERFBDFLAGS+=-S
  286. perfbd: $(BENCH_TRACE) $(BUILDDIR)/lfs.perfbd.csv
  287. $(strip ./scripts/perfbd.py $(BENCH_RUNNER) $(BENCH_TRACE) \
  288. $(patsubst %,-F%,$(SRC)) \
  289. $(PERFBDFLAGS))
  290. ## Compare perfbd results
  291. .PHONY: perfbd-diff
  292. perfbd-diff: $(BENCH_TRACE)
  293. $(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
  294. $(patsubst %,-F%,$(SRC)) \
  295. $(PERFBDFLAGS) -d $(BUILDDIR)/lfs.perfbd.csv)
  296. ## Find a summary of compile-time sizes
  297. .PHONY: summary sizes
  298. summary sizes: \
  299. $(BUILDDIR)/lfs.code.csv \
  300. $(BUILDDIR)/lfs.data.csv \
  301. $(BUILDDIR)/lfs.stack.csv \
  302. $(BUILDDIR)/lfs.structs.csv
  303. $(strip ./scripts/summary.py $^ \
  304. -fcode=code_size \
  305. -fdata=data_size \
  306. -fstack=stack_limit --max=stack \
  307. -fstructs=struct_size \
  308. -Y $(SUMMARYFLAGS))
  309. ## Compare compile-time sizes
  310. .PHONY: summary-diff sizes-diff
  311. summary-diff sizes-diff: SHELL=/bin/bash
  312. summary-diff sizes-diff: $(OBJ) $(CI)
  313. $(strip ./scripts/summary.py \
  314. <(./scripts/code.py $(OBJ) -q $(CODEFLAGS) -o-) \
  315. <(./scripts/data.py $(OBJ) -q $(DATAFLAGS) -o-) \
  316. <(./scripts/stack.py $(CI) -q $(STACKFLAGS) -o-) \
  317. <(./scripts/structs.py $(OBJ) -q $(STRUCTSFLAGS) -o-) \
  318. -fcode=code_size \
  319. -fdata=data_size \
  320. -fstack=stack_limit --max=stack \
  321. -fstructs=struct_size \
  322. -Y $(SUMMARYFLAGS) -d <(./scripts/summary.py \
  323. $(BUILDDIR)/lfs.code.csv \
  324. $(BUILDDIR)/lfs.data.csv \
  325. $(BUILDDIR)/lfs.stack.csv \
  326. $(BUILDDIR)/lfs.structs.csv \
  327. -q $(SUMMARYFLAGS) -o-))
  328. ## Build the test-runner
  329. .PHONY: test-runner build-test
  330. test-runner build-test: CFLAGS+=-Wno-missing-prototypes
  331. ifndef NO_COV
  332. test-runner build-test: CFLAGS+=--coverage
  333. endif
  334. ifdef YES_PERF
  335. test-runner build-test: CFLAGS+=-fno-omit-frame-pointer
  336. endif
  337. ifdef YES_PERFBD
  338. test-runner build-test: CFLAGS+=-fno-omit-frame-pointer
  339. endif
  340. # note we remove some binary dependent files during compilation,
  341. # otherwise it's way to easy to end up with outdated results
  342. test-runner build-test: $(TEST_RUNNER)
  343. ifndef NO_COV
  344. rm -f $(TEST_GCDA)
  345. endif
  346. ifdef YES_PERF
  347. rm -f $(TEST_PERF)
  348. endif
  349. ifdef YES_PERFBD
  350. rm -f $(TEST_TRACE)
  351. endif
  352. ## Run the tests, -j enables parallel tests
  353. .PHONY: test
  354. test: test-runner
  355. ./scripts/test.py $(TEST_RUNNER) $(TESTFLAGS)
  356. ## List the tests
  357. .PHONY: test-list
  358. test-list: test-runner
  359. ./scripts/test.py $(TEST_RUNNER) $(TESTFLAGS) -l
  360. ## Summarize the testmarks
  361. .PHONY: testmarks
  362. testmarks: SUMMARYFLAGS+=-spassed
  363. testmarks: $(TEST_CSV) $(BUILDDIR)/lfs.test.csv
  364. $(strip ./scripts/summary.py $(TEST_CSV) \
  365. -bsuite \
  366. -fpassed=test_passed \
  367. $(SUMMARYFLAGS))
  368. ## Compare testmarks against a previous run
  369. .PHONY: testmarks-diff
  370. testmarks-diff: $(TEST_CSV)
  371. $(strip ./scripts/summary.py $^ \
  372. -bsuite \
  373. -fpassed=test_passed \
  374. $(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.test.csv)
  375. ## Build the bench-runner
  376. .PHONY: bench-runner build-bench
  377. bench-runner build-bench: CFLAGS+=-Wno-missing-prototypes
  378. ifdef YES_COV
  379. bench-runner build-bench: CFLAGS+=--coverage
  380. endif
  381. ifdef YES_PERF
  382. bench-runner build-bench: CFLAGS+=-fno-omit-frame-pointer
  383. endif
  384. ifndef NO_PERFBD
  385. bench-runner build-bench: CFLAGS+=-fno-omit-frame-pointer
  386. endif
  387. # note we remove some binary dependent files during compilation,
  388. # otherwise it's way to easy to end up with outdated results
  389. bench-runner build-bench: $(BENCH_RUNNER)
  390. ifdef YES_COV
  391. rm -f $(BENCH_GCDA)
  392. endif
  393. ifdef YES_PERF
  394. rm -f $(BENCH_PERF)
  395. endif
  396. ifndef NO_PERFBD
  397. rm -f $(BENCH_TRACE)
  398. endif
  399. ## Run the benchmarks, -j enables parallel benchmarks
  400. .PHONY: bench
  401. bench: bench-runner
  402. ./scripts/bench.py $(BENCH_RUNNER) $(BENCHFLAGS)
  403. ## List the benchmarks
  404. .PHONY: bench-list
  405. bench-list: bench-runner
  406. ./scripts/bench.py $(BENCH_RUNNER) $(BENCHFLAGS) -l
  407. ## Summarize the benchmarks
  408. .PHONY: benchmarks
  409. benchmarks: SUMMARYFLAGS+=-Serased -Sproged -Sreaded
  410. benchmarks: $(BENCH_CSV) $(BUILDDIR)/lfs.bench.csv
  411. $(strip ./scripts/summary.py $(BENCH_CSV) \
  412. -bsuite \
  413. -freaded=bench_readed \
  414. -fproged=bench_proged \
  415. -ferased=bench_erased \
  416. $(SUMMARYFLAGS))
  417. ## Compare benchmarks against a previous run
  418. .PHONY: benchmarks-diff
  419. benchmarks-diff: $(BENCH_CSV)
  420. $(strip ./scripts/summary.py $^ \
  421. -bsuite \
  422. -freaded=bench_readed \
  423. -fproged=bench_proged \
  424. -ferased=bench_erased \
  425. $(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.bench.csv)
  426. # rules
  427. -include $(DEP)
  428. -include $(TEST_DEP)
  429. -include $(BENCH_DEP)
  430. .SUFFIXES:
  431. .SECONDARY:
  432. $(BUILDDIR)/lfs: $(OBJ)
  433. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  434. $(BUILDDIR)/liblfs.a: $(OBJ)
  435. $(AR) rcs $@ $^
  436. $(BUILDDIR)/lfs.code.csv: $(OBJ)
  437. ./scripts/code.py $^ -q $(CODEFLAGS) -o $@
  438. $(BUILDDIR)/lfs.data.csv: $(OBJ)
  439. ./scripts/data.py $^ -q $(DATAFLAGS) -o $@
  440. $(BUILDDIR)/lfs.stack.csv: $(CI)
  441. ./scripts/stack.py $^ -q $(STACKFLAGS) -o $@
  442. $(BUILDDIR)/lfs.structs.csv: $(OBJ)
  443. ./scripts/structs.py $^ -q $(STRUCTSFLAGS) -o $@
  444. $(BUILDDIR)/lfs.cov.csv: $(GCDA)
  445. $(strip ./scripts/cov.py $^ \
  446. $(patsubst %,-F%,$(SRC)) \
  447. -q $(COVFLAGS) -o $@)
  448. $(BUILDDIR)/lfs.perf.csv: $(BENCH_PERF)
  449. $(strip ./scripts/perf.py $^ \
  450. $(patsubst %,-F%,$(SRC)) \
  451. -q $(PERFFLAGS) -o $@)
  452. $(BUILDDIR)/lfs.perfbd.csv: $(BENCH_TRACE)
  453. $(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
  454. $(patsubst %,-F%,$(SRC)) \
  455. -q $(PERFBDFLAGS) -o $@)
  456. $(BUILDDIR)/lfs.test.csv: $(TEST_CSV)
  457. cp $^ $@
  458. $(BUILDDIR)/lfs.bench.csv: $(BENCH_CSV)
  459. cp $^ $@
  460. $(BUILDDIR)/runners/test_runner: $(TEST_OBJ)
  461. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  462. $(BUILDDIR)/runners/bench_runner: $(BENCH_OBJ)
  463. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  464. # our main build rule generates .o, .d, and .ci files, the latter
  465. # used for stack analysis
  466. $(BUILDDIR)/%.o $(BUILDDIR)/%.ci: %.c
  467. $(CC) -c -MMD $(CFLAGS) $< -o $(BUILDDIR)/$*.o
  468. $(BUILDDIR)/%.o $(BUILDDIR)/%.ci: $(BUILDDIR)/%.c
  469. $(CC) -c -MMD $(CFLAGS) $< -o $(BUILDDIR)/$*.o
  470. $(BUILDDIR)/%.s: %.c
  471. $(CC) -S $(CFLAGS) $< -o $@
  472. $(BUILDDIR)/%.c: %.a.c
  473. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  474. $(BUILDDIR)/%.c: $(BUILDDIR)/%.a.c
  475. ./scripts/prettyasserts.py -p LFS_ASSERT $< -o $@
  476. $(BUILDDIR)/%.t.a.c: %.toml
  477. ./scripts/test.py -c $< $(TESTCFLAGS) -o $@
  478. $(BUILDDIR)/%.t.a.c: %.c $(TESTS)
  479. ./scripts/test.py -c $(TESTS) -s $< $(TESTCFLAGS) -o $@
  480. $(BUILDDIR)/%.b.a.c: %.toml
  481. ./scripts/bench.py -c $< $(BENCHCFLAGS) -o $@
  482. $(BUILDDIR)/%.b.a.c: %.c $(BENCHES)
  483. ./scripts/bench.py -c $(BENCHES) -s $< $(BENCHCFLAGS) -o $@
  484. ## Clean everything
  485. .PHONY: clean
  486. clean:
  487. rm -f $(BUILDDIR)/lfs
  488. rm -f $(BUILDDIR)/liblfs.a
  489. rm -f $(BUILDDIR)/lfs.code.csv
  490. rm -f $(BUILDDIR)/lfs.data.csv
  491. rm -f $(BUILDDIR)/lfs.stack.csv
  492. rm -f $(BUILDDIR)/lfs.structs.csv
  493. rm -f $(BUILDDIR)/lfs.cov.csv
  494. rm -f $(BUILDDIR)/lfs.perf.csv
  495. rm -f $(BUILDDIR)/lfs.perfbd.csv
  496. rm -f $(BUILDDIR)/lfs.test.csv
  497. rm -f $(BUILDDIR)/lfs.bench.csv
  498. rm -f $(OBJ)
  499. rm -f $(DEP)
  500. rm -f $(ASM)
  501. rm -f $(CI)
  502. rm -f $(TEST_RUNNER)
  503. rm -f $(TEST_A)
  504. rm -f $(TEST_C)
  505. rm -f $(TEST_OBJ)
  506. rm -f $(TEST_DEP)
  507. rm -f $(TEST_CI)
  508. rm -f $(TEST_GCNO)
  509. rm -f $(TEST_GCDA)
  510. rm -f $(TEST_PERF)
  511. rm -f $(TEST_TRACE)
  512. rm -f $(TEST_CSV)
  513. rm -f $(BENCH_RUNNER)
  514. rm -f $(BENCH_A)
  515. rm -f $(BENCH_C)
  516. rm -f $(BENCH_OBJ)
  517. rm -f $(BENCH_DEP)
  518. rm -f $(BENCH_CI)
  519. rm -f $(BENCH_GCNO)
  520. rm -f $(BENCH_GCDA)
  521. rm -f $(BENCH_PERF)
  522. rm -f $(BENCH_TRACE)
  523. rm -f $(BENCH_CSV)