Makefile 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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)tests))
  10. endif
  11. # overridable target/src/tools/flags/etc
  12. ifneq ($(wildcard test.c main.c),)
  13. TARGET ?= $(BUILDDIR)lfs
  14. else
  15. TARGET ?= $(BUILDDIR)lfs.a
  16. endif
  17. CC ?= gcc
  18. AR ?= ar
  19. SIZE ?= size
  20. CTAGS ?= ctags
  21. NM ?= nm
  22. OBJDUMP ?= objdump
  23. LCOV ?= lcov
  24. SRC ?= $(wildcard *.c)
  25. OBJ := $(SRC:%.c=$(BUILDDIR)%.o)
  26. DEP := $(SRC:%.c=$(BUILDDIR)%.d)
  27. ASM := $(SRC:%.c=$(BUILDDIR)%.s)
  28. CGI := $(SRC:%.c=$(BUILDDIR)%.ci)
  29. ifdef DEBUG
  30. override CFLAGS += -O0
  31. else
  32. override CFLAGS += -Os
  33. endif
  34. ifdef TRACE
  35. override CFLAGS += -DLFS_YES_TRACE
  36. endif
  37. override CFLAGS += -g3
  38. override CFLAGS += -I.
  39. override CFLAGS += -std=c99 -Wall -pedantic
  40. override CFLAGS += -Wextra -Wshadow -Wjump-misses-init -Wundef
  41. ifdef VERBOSE
  42. override TESTFLAGS += -v
  43. override CALLSFLAGS += -v
  44. override CODEFLAGS += -v
  45. override DATAFLAGS += -v
  46. override STACKFLAGS += -v
  47. override STRUCTSFLAGS += -v
  48. override COVERAGEFLAGS += -v
  49. endif
  50. ifdef EXEC
  51. override TESTFLAGS += --exec="$(EXEC)"
  52. endif
  53. ifdef COVERAGE
  54. override TESTFLAGS += --coverage
  55. endif
  56. ifdef BUILDDIR
  57. override TESTFLAGS += --build-dir="$(BUILDDIR:/=)"
  58. override CALLSFLAGS += --build-dir="$(BUILDDIR:/=)"
  59. override CODEFLAGS += --build-dir="$(BUILDDIR:/=)"
  60. override DATAFLAGS += --build-dir="$(BUILDDIR:/=)"
  61. override STACKFLAGS += --build-dir="$(BUILDDIR:/=)"
  62. override STRUCTSFLAGS += --build-dir="$(BUILDDIR:/=)"
  63. override COVERAGEFLAGS += --build-dir="$(BUILDDIR:/=)"
  64. endif
  65. ifneq ($(NM),nm)
  66. override CODEFLAGS += --nm-tool="$(NM)"
  67. override DATAFLAGS += --nm-tool="$(NM)"
  68. endif
  69. ifneq ($(OBJDUMP),objdump)
  70. override STRUCTSFLAGS += --objdump-tool="$(OBJDUMP)"
  71. endif
  72. # commands
  73. .PHONY: all build
  74. all build: $(TARGET)
  75. .PHONY: asm
  76. asm: $(ASM)
  77. .PHONY: size
  78. size: $(OBJ)
  79. $(SIZE) -t $^
  80. .PHONY: tags
  81. tags:
  82. $(CTAGS) --totals --c-types=+p $(shell find -H -name '*.h') $(SRC)
  83. .PHONY: calls
  84. calls: $(CGI)
  85. ./scripts/calls.py $^ $(CALLSFLAGS)
  86. .PHONY: test
  87. test:
  88. ./scripts/test.py $(TESTFLAGS)
  89. .SECONDEXPANSION:
  90. test%: tests/test$$(firstword $$(subst \#, ,%)).toml
  91. ./scripts/test.py $@ $(TESTFLAGS)
  92. .PHONY: code
  93. code: $(OBJ)
  94. ./scripts/code.py $^ -S $(CODEFLAGS)
  95. .PHONY: data
  96. data: $(OBJ)
  97. ./scripts/data.py $^ -S $(DATAFLAGS)
  98. .PHONY: stack
  99. stack: $(CGI)
  100. ./scripts/stack.py $^ -S $(STACKFLAGS)
  101. .PHONY: structs
  102. structs: $(OBJ)
  103. ./scripts/structs.py $^ -S $(STRUCTSFLAGS)
  104. .PHONY: coverage
  105. coverage:
  106. ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info -s $(COVERAGEFLAGS)
  107. .PHONY: summary
  108. summary: $(BUILDDIR)lfs.csv
  109. ./scripts/summary.py -Y $^ $(SUMMARYFLAGS)
  110. # rules
  111. -include $(DEP)
  112. .SUFFIXES:
  113. $(BUILDDIR)lfs: $(OBJ)
  114. $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
  115. $(BUILDDIR)lfs.a: $(OBJ)
  116. $(AR) rcs $@ $^
  117. $(BUILDDIR)lfs.csv: $(OBJ) $(CGI)
  118. ./scripts/code.py $(OBJ) -q $(CODEFLAGS) -o $@
  119. ./scripts/data.py $(OBJ) -q -m $@ $(DATAFLAGS) -o $@
  120. ./scripts/stack.py $(CGI) -q -m $@ $(STACKFLAGS) -o $@
  121. ./scripts/structs.py $(OBJ) -q -m $@ $(STRUCTSFLAGS) -o $@
  122. $(if $(COVERAGE),\
  123. ./scripts/coverage.py $(BUILDDIR)tests/*.toml.info \
  124. -q -m $@ $(COVERAGEFLAGS) -o $@)
  125. $(BUILDDIR)%.o: %.c
  126. $(CC) -c -MMD $(CFLAGS) $< -o $@
  127. $(BUILDDIR)%.s: %.c
  128. $(CC) -S $(CFLAGS) $< -o $@
  129. # gcc depends on the output file for intermediate file names, so
  130. # we can't omit to .o output. We also need to serialize with the
  131. # normal .o rule because otherwise we can end up with multiprocess
  132. # problems with two instances of gcc modifying the same .o
  133. $(BUILDDIR)%.ci: %.c | $(BUILDDIR)%.o
  134. $(CC) -c -MMD -fcallgraph-info=su $(CFLAGS) $< -o $|
  135. # clean everything
  136. .PHONY: clean
  137. clean:
  138. rm -f $(BUILDDIR)lfs
  139. rm -f $(BUILDDIR)lfs.a
  140. rm -f $(BUILDDIR)lfs.csv
  141. rm -f $(OBJ)
  142. rm -f $(CGI)
  143. rm -f $(DEP)
  144. rm -f $(ASM)
  145. rm -f $(BUILDDIR)tests/*.toml.*