Makefile 6.3 KB

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