Makefile 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. # NOTE: only tested in GNU/Linux.
  2. ## Binary dependencies.
  3. CC = gcc
  4. AR = ar
  5. LEXER = re2c
  6. PARSER = lemon
  7. ## Paths.
  8. PREFIX ?= /usr/local
  9. bindir = $(PREFIX)/bin
  10. libdir = $(PREFIX)/lib
  11. includedir = $(PREFIX)/include/lsup
  12. MDB_DIR = ext/openldap/libraries/liblmdb
  13. XXHASH_DIR = ext/xxHash
  14. CALLGRIND_DUMP = /tmp/lsup_callgrind.%p.out
  15. INCLUDE_BASE = . -Iinclude -I$(MDB_DIR) -I$(XXHASH_DIR) \
  16. -Iext/tpl/src -Iext/uthash/src -Iext/log/src
  17. INCLUDE = -I$(INCLUDE_BASE)
  18. CFLAGS += -Wall -fPIC -MMD -DLOG_USE_COLOR $(INCLUDE)
  19. DBG_CFLAGS = -Itest -O0 -g3 -DDEBUG
  20. # NOTE: -luuid is a Linux system library. Other OS's might need a different
  21. # link or a non-system library built.
  22. LDFLAGS = -L. -L$(libdir) -llmdb -lxxhash -luuid
  23. CODEC_DIR = src/codec
  24. CODEC_SRC = $(wildcard src/codec/*_grammar.c) \
  25. $(wildcard src/codec/*_parser.c)
  26. CODEC_OBJ = $(CODEC_SRC:.c=.o)
  27. CODEC_DBG_OBJ = $(CODEC_SRC:.c=_dbg.o)
  28. # External sources compiled in core object.
  29. EXT_SRC = $(wildcard ext/log/src/*.c) \
  30. $(wildcard ext/tpl/src/*.c)
  31. # External headers of libraries compiled in core.
  32. EXT_H = $(wildcard ext/log/src/*.h) \
  33. $(wildcard ext/tpl/src/*.h) \
  34. $(wildcard ext/uthash/src/*.h)
  35. LSUP_SRC = $(wildcard src/*.c)
  36. SRC = $(EXT_SRC) $(LSUP_SRC)
  37. TEST_SRC = $(wildcard test/*.c) test.c
  38. OBJ = $(LSUP_SRC:.c=.o) $(CODEC_OBJ)
  39. EXT_OBJ = $(EXT_SRC:.c=.o)
  40. DBG_OBJ = $(EXT_OBJ) $(CODEC_DBG_OBJ) $(LSUP_SRC:.c=_dbg.o)
  41. DEPLIBS = libxxhash liblmdb
  42. LIBS = liblsuprdf.a liblsuprdf.so
  43. DBG_LIBS = liblsuprdf_dbg.a liblsuprdf_dbg.so
  44. # For visual dep graph.
  45. DEPS := $(shell echo "${INCLUDE_BASE}" | sed -e 's/ -I/,/g')
  46. DOCS = docs
  47. ## Environment.
  48. export LD_LIBRARY_PATH = $(libdir):.
  49. ## Rules.
  50. .DEFAULT_GOAL := lib
  51. # Extract all rule comment into a help message.
  52. .PHONY: help
  53. help:
  54. @echo "Command overview:"; echo; \
  55. grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
  56. | sed -n 's/^\(.*\): \(.*\)##\(.*\)/\1::\3/p' \
  57. | column -t -s '::'
  58. lib: $(DEPLIBS) $(LIBS) ## Compile main library (static and dynamic linking).
  59. debug: $(DEPLIBS) $(DBG_LIBS) ## Compile main library with debug symbols.
  60. # Static library.
  61. liblsuprdf.a: $(OBJ)
  62. $(AR) rs $@ $^
  63. # Dynamic library.
  64. liblsuprdf.so: $(OBJ)
  65. $(CC) -shared $(LDFLAGS) -o $@ $^
  66. # Static debug library.
  67. liblsuprdf_dbg.a: $(DBG_OBJ)
  68. $(AR) rs $@ $^
  69. # Dynamic debug library.
  70. liblsuprdf_dbg.so: $(DBG_OBJ)
  71. $(CC) -shared $(LDFLAGS) -o $@ $^
  72. # Debug objects.
  73. %_dbg.o: %.c
  74. $(CC) $(CFLAGS) $(DBG_CFLAGS) $(LDFLAGS) -c $^ -o $@
  75. # Codecs.
  76. $(CODEC_OBJ): $(CODEC_SRC)
  77. # Parser C sources.
  78. %_parser.c: %_lexer.re %_grammar.c
  79. $(LEXER) $< -o $@ -T --case-ranges
  80. # Parser generators.
  81. %_grammar.c: %_grammar.y
  82. $(PARSER) $< -q -m -T$(CODEC_DIR)/lempar.c -d$(CODEC_DIR)
  83. # Ext libraries.
  84. .PHONY: libxxhash
  85. libxxhash:
  86. $(MAKE) -C $(XXHASH_DIR)
  87. .PHONY: liblmdb
  88. liblmdb:
  89. $(MAKE) -C $(MDB_DIR)
  90. install: lib ## Install library and dependencies to $PREFIX. May require sudo.
  91. cd $(MDB_DIR); PREFIX=$(PREFIX) make install
  92. cd $(XXHASH_DIR); PREFIX=$(PREFIX) make install
  93. mkdir -p $(DESTDIR)$(libdir)
  94. mkdir -p $(DESTDIR)$(includedir)
  95. cp liblsuprdf.{a,so} $(DESTDIR)$(libdir) && \
  96. cp include/*.h $(EXT_H) $(DESTDIR)$(includedir)
  97. debug_install: install debug ## Install standard and debug libraries.
  98. cp liblsuprdf_dbg.{a,so} $(DESTDIR)$(libdir)
  99. .PHONY: clean ## Clean up artifacts.
  100. clean:
  101. rm -rf src/*.[aod] ./*[aod] src/codec/*[aod]
  102. .PHONY: deepclean ## Clean up artifacts in external libraries as well.
  103. deepclean: clean
  104. cd $(MDB_DIR); make clean
  105. cd $(XXHASH_DIR); make clean
  106. .PHONY: uninstall ## Uninstall library (not the dependencies).
  107. uninstall:
  108. rm -f $(DESTDIR)$(libdir)/liblsuprdf*
  109. rm -rf $(DESTDIR)$(includedir)
  110. rm -f bin/test*
  111. # For testing, use debug symbols.
  112. bin/test: debug $(TEST_SRC)
  113. $(CC) $(CFLAGS) $(DBG_CFLAGS) -Itest $(LDFLAGS) -llsuprdf_dbg \
  114. test.c -o bin/test
  115. .PHONY: test
  116. test: bin/test ## Run a test suite.
  117. exec bin/test
  118. .PHONY: gdb_test
  119. gdb_test: bin/test ## Run a test suite within gdb.
  120. exec gdb bin/test
  121. lint:
  122. splint \
  123. $(INCLUDE) -Itest \
  124. -DUINT_MAX=0xFFFFFFFFUL \
  125. -nullpass \
  126. -posix-lib \
  127. test.c
  128. .PHONY: memcheck
  129. memcheck:
  130. valgrind \
  131. --leak-check=full --show-leak-kinds=all --track-origins=yes \
  132. --log-file=/tmp/lsup_valgrind.log \
  133. ./bin/test
  134. echo "Memcheck complete. Valgrind log is at /tmp/lsup_valgrind.log"
  135. memtest: bin/test memcheck ## Run a test suite using Valgrind. Output to separate file.
  136. # Profiling application.
  137. bin/profile: debug $(TEST_SRC)
  138. $(CC) $(CFLAGS) -g -DTESTING $(LDFLAGS) -lliblsuprdf_dbg \
  139. profile.c -o bin/profile
  140. .PHONY: profile
  141. profile: bin/profile ## Run a profiling session. Output can be inspected with KCachegrind.
  142. exec valgrind --tool=callgrind --callgrind-out-file="$(CALLGRIND_DUMP)" \
  143. bin/profile 10000 && \
  144. echo "Profile dump written at $(CALLGRIND_DUMP)"
  145. .PHONY: pytest
  146. pytest: ## Run a test suite for the Python package.
  147. pip3 install --user . && \
  148. python3 test/cpython_test.py
  149. # Requires cinclude2dot (https://www.flourish.org/cinclude2dot) and Graphviz.
  150. depgraph: src/* include/* ## Build a visual dependency graph of the code.
  151. cinclude2dot --merge=module --include=$(DEPS) \
  152. --exclude='test|ext' >| $(DOCS)/dev/deps.dot
  153. dot $(DOCS)/dev/deps.dot -Tpdf >| $(DOCS)/dev/deps.pdf