Makefile 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. endif
  12. # overridable target/src/tools/flags/etc
  13. ifneq ($(wildcard test.c main.c),)
  14. TARGET ?= $(BUILDDIR)lfs
  15. else
  16. TARGET ?= $(BUILDDIR)lfs.a
  17. endif
  18. CC ?= gcc
  19. AR ?= ar
  20. SIZE ?= size
  21. CTAGS ?= ctags
  22. NM ?= nm
  23. OBJDUMP ?= objdump
  24. LCOV ?= lcov
  25. SRC ?= $(filter-out $(wildcard *.*.c),$(wildcard *.c))
  26. OBJ := $(SRC:%.c=$(BUILDDIR)%.o)
  27. DEP := $(SRC:%.c=$(BUILDDIR)%.d)
  28. ASM := $(SRC:%.c=$(BUILDDIR)%.s)
  29. CGI := $(SRC:%.c=$(BUILDDIR)%.ci)
  30. TESTS ?= $(wildcard tests_/*.toml)
  31. TEST_SRC ?= $(SRC) \
  32. $(filter-out $(wildcard bd/*.*.c),$(wildcard bd/*.c)) \
  33. runners/test_runner.c
  34. TEST_TSRC := $(TESTS:%.toml=$(BUILDDIR)%.t.c) $(TEST_SRC:%.c=$(BUILDDIR)%.t.c)
  35. TEST_TASRC := $(TEST_TSRC:%.t.c=%.t.a.c)
  36. TEST_TAOBJ := $(TEST_TASRC:%.t.a.c=%.t.a.o)
  37. TEST_TADEP := $(TEST_TASRC:%.t.a.c=%.t.a.d)
  38. ifdef DEBUG
  39. override CFLAGS += -O0
  40. else
  41. override CFLAGS += -Os
  42. endif
  43. ifdef TRACE
  44. override CFLAGS += -DLFS_YES_TRACE
  45. endif
  46. override CFLAGS += -g3
  47. override CFLAGS += -I.
  48. override CFLAGS += -std=c99 -Wall -pedantic
  49. override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
  50. override TESTFLAGS_ += -b
  51. # forward -j flag
  52. override TESTFLAGS_ += $(filter -j%,$(MAKEFLAGS))
  53. ifdef VERBOSE
  54. override TESTFLAGS += -v
  55. override CALLSFLAGS += -v
  56. override CODEFLAGS += -v
  57. override DATAFLAGS += -v
  58. override STACKFLAGS += -v
  59. override STRUCTSFLAGS += -v
  60. override COVERAGEFLAGS += -v
  61. override TESTFLAGS_ += -v
  62. override TESTCFLAGS_ += -v
  63. endif
  64. ifdef EXEC
  65. override TESTFLAGS_ += --exec="$(EXEC)"
  66. endif
  67. ifdef COVERAGE
  68. override TESTFLAGS += --coverage
  69. override TESTFLAGS_ += --coverage
  70. endif
  71. ifdef BUILDDIR
  72. override TESTFLAGS += --build-dir="$(BUILDDIR:/=)"
  73. override CALLSFLAGS += --build-dir="$(BUILDDIR:/=)"
  74. override CODEFLAGS += --build-dir="$(BUILDDIR:/=)"
  75. override DATAFLAGS += --build-dir="$(BUILDDIR:/=)"
  76. override STACKFLAGS += --build-dir="$(BUILDDIR:/=)"
  77. override STRUCTSFLAGS += --build-dir="$(BUILDDIR:/=)"
  78. override COVERAGEFLAGS += --build-dir="$(BUILDDIR:/=)"
  79. endif
  80. ifneq ($(NM),nm)
  81. override CODEFLAGS += --nm-tool="$(NM)"
  82. override DATAFLAGS += --nm-tool="$(NM)"
  83. endif
  84. ifneq ($(OBJDUMP),objdump)
  85. override STRUCTSFLAGS += --objdump-tool="$(OBJDUMP)"
  86. endif
  87. # commands
  88. .PHONY: all build
  89. all build: $(TARGET)
  90. .PHONY: asm
  91. asm: $(ASM)
  92. .PHONY: size
  93. size: $(OBJ)
  94. $(SIZE) -t $^
  95. .PHONY: tags
  96. tags:
  97. $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
  98. .PHONY: calls
  99. calls: $(CGI)
  100. ./scripts/calls.py $^ $(CALLSFLAGS)
  101. .PHONY: test
  102. test:
  103. ./scripts/test.py $(TESTFLAGS)
  104. .SECONDEXPANSION:
  105. test%: tests/test$$(firstword $$(subst \#, ,%)).toml
  106. ./scripts/test.py $@ $(TESTFLAGS)
  107. .PHONY: test_runner
  108. test_runner: $(BUILDDIR)runners/test_runner
  109. .PHONY: test_
  110. test_: test_runner
  111. ./scripts/test_.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS_)
  112. .PHONY: test_list
  113. test_list: test_runner
  114. ./scripts/test_.py --runner=$(BUILDDIR)runners/test_runner $(TESTFLAGS_) -l
  115. .PHONY: code
  116. code: $(OBJ)
  117. ./scripts/code.py $^ -S $(CODEFLAGS)
  118. .PHONY: data
  119. data: $(OBJ)
  120. ./scripts/data.py $^ -S $(DATAFLAGS)
  121. .PHONY: stack
  122. stack: $(CGI)
  123. ./scripts/stack.py $^ -S $(STACKFLAGS)
  124. .PHONY: structs
  125. structs: $(OBJ)
  126. ./scripts/structs.py $^ -S $(STRUCTSFLAGS)
  127. .PHONY: coverage
  128. coverage:
  129. ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info -s $(COVERAGEFLAGS)
  130. .PHONY: summary
  131. summary: $(BUILDDIR)lfs.csv
  132. ./scripts/summary.py -Y $^ $(SUMMARYFLAGS)
  133. # rules
  134. -include $(DEP)
  135. -include $(TEST_TADEP)
  136. .SUFFIXES:
  137. .SECONDARY:
  138. $(BUILDDIR)lfs: $(OBJ)
  139. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  140. $(BUILDDIR)lfs.a: $(OBJ)
  141. $(AR) rcs $@ $^
  142. $(BUILDDIR)lfs.csv: $(OBJ) $(CGI)
  143. ./scripts/code.py $(OBJ) -q $(CODEFLAGS) -o $@
  144. ./scripts/data.py $(OBJ) -q -m $@ $(DATAFLAGS) -o $@
  145. ./scripts/stack.py $(CGI) -q -m $@ $(STACKFLAGS) -o $@
  146. ./scripts/structs.py $(OBJ) -q -m $@ $(STRUCTSFLAGS) -o $@
  147. $(if $(COVERAGE),\
  148. ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info \
  149. -q -m $@ $(COVERAGEFLAGS) -o $@)
  150. $(BUILDDIR)runners/test_runner: $(TEST_TAOBJ)
  151. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  152. $(BUILDDIR)%.o: %.c
  153. $(CC) -c -MMD $(CFLAGS) $< -o $@
  154. $(BUILDDIR)%.s: %.c
  155. $(CC) -S $(CFLAGS) $< -o $@
  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. $(BUILDDIR)%.a.c: %.c
  163. ./scripts/explode_asserts.py $< -o $@
  164. $(BUILDDIR)%.a.c: $(BUILDDIR)%.c
  165. ./scripts/explode_asserts.py $< -o $@
  166. $(BUILDDIR)%.t.c: %.toml
  167. ./scripts/test_.py -c $< $(TESTCFLAGS_) -o $@
  168. $(BUILDDIR)%.t.c: %.c $(TESTS)
  169. ./scripts/test_.py -c $(TESTS) -s $< $(TESTCFLAGS_) -o $@
  170. # clean everything
  171. .PHONY: clean
  172. clean:
  173. rm -f $(BUILDDIR)lfs
  174. rm -f $(BUILDDIR)lfs.a
  175. rm -f $(BUILDDIR)lfs.csv
  176. rm -f $(BUILDDIR)runners/test_runner
  177. rm -f $(OBJ)
  178. rm -f $(CGI)
  179. rm -f $(DEP)
  180. rm -f $(ASM)
  181. rm -f $(BUILDDIR)tests/*.toml.*
  182. rm -f $(TEST_TSRC)
  183. rm -f $(TEST_TASRC)
  184. rm -f $(TEST_TAOBJ)
  185. rm -f $(TEST_TADEP)