summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile191
1 files changed, 48 insertions, 143 deletions
diff --git a/Makefile b/Makefile
index a665890..d2e0c2d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,6 @@
1# $Id$ 1PREFIX?=/usr/local
2
3PREFIX?=..
4BINDIR?=$(PREFIX)/bin 2BINDIR?=$(PREFIX)/bin
3MANDIR?=$(PREFIX)/share/man
5STRIP?=strip 4STRIP?=strip
6 5
7#FEATURES+=-DWANT_V4_ONLY 6#FEATURES+=-DWANT_V4_ONLY
@@ -12,16 +11,6 @@ STRIP?=strip
12#FEATURES+=-DWANT_SYNC_LIVE 11#FEATURES+=-DWANT_SYNC_LIVE
13#FEATURES+=-DWANT_IP_FROM_QUERY_STRING 12#FEATURES+=-DWANT_IP_FROM_QUERY_STRING
14 13
15# If you want gzip support to be compiled in, uncomment the next include.
16# You can further modify the behaviour by setting DWANT_COMPRESSION_GZIP_ALWAYS
17# in Makefile.gzip
18include Makefile.gzip
19
20# If you want zstd support to be compiled in, uncomment the next include.
21# You can further modify the behaviour by setting DWANT_COMPRESSION_ZSTD_ALWAYS
22# in Makefile.zstd
23#include Makefile.zstd
24
25#FEATURES+=-DWANT_RESTRICT_STATS 14#FEATURES+=-DWANT_RESTRICT_STATS
26#FEATURES+=-DWANT_IP_FROM_PROXY 15#FEATURES+=-DWANT_IP_FROM_PROXY
27#FEATURES+=-DWANT_LOG_NUMWANT 16#FEATURES+=-DWANT_LOG_NUMWANT
@@ -31,155 +20,71 @@ include Makefile.gzip
31#FEATURES+=-DWANT_DEV_RANDOM 20#FEATURES+=-DWANT_DEV_RANDOM
32FEATURES+=-DWANT_FULLSCRAPE 21FEATURES+=-DWANT_FULLSCRAPE
33 22
34# opentracker takes its randomness from arc4random, which is part of libc on 23# Buckets the torrent table is split into, as a power of two, 8 to 16. More
35# the BSDs, on macOS and on glibc 2.36 and newer. On an older glibc or on musl 24# buckets make inserting a new torrent cheaper and cost memory, which is worth
36# it comes from libbsd instead, so uncomment the next include to link it. 25# it for a tracker carrying millions of torrents and not for one carrying
37#LDFLAGS+=-lbsd 26# thousands. DESIGN has the measurements.
27FEATURES+=-DOT_BUCKET_COUNT_BITS=10
38 28
39#FEATURES+=-D_DEBUG_HTTPERROR 29#FEATURES+=-D_DEBUG_HTTPERROR
40#FEATURES+=-D_DEBUG_RANDOMTORRENTS 30#FEATURES+=-D_DEBUG_RANDOMTORRENTS
41 31
42VERSION=1.0.0 32# Compression support, off unless included. Each file carries a second switch
43TARBALL_VERSION=test -r .tarball-version && read v < .tarball-version && echo "$$v" 33# to compress even where the client did not ask.
44HAVE_GIT=command -v git >/dev/null && test -d .git 34include Mk/gzip.mk
45GIT_VERSION=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --always --dirty 2>/dev/null; }'` 35#include Mk/zstd.mk
46OT_TAG=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --exact-match 2>/dev/null; }'`
47 36
48OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage 37# arc4random is part of libc on the BSDs, on macOS and on glibc 2.36 and
49OPTS_production=-O3 38# newer. On an older glibc or on musl it comes from libbsd instead.
39#OT_LDLIBS+=-lbsd
50 40
51CFLAGS+=-DOT_VERSION=\"$(VERSION)\" -DGIT_VERSION=\"$(GIT_VERSION)\" -DOT_TAG=\"$(OT_TAG)\" -Wall -pipe -pthread -Wextra -Wwrite-strings #-ansi -pedantic 41CFLAGS?=-O3
52LDFLAGS+=-pthread
53 42
54# Record feature flags as a dep to allow rebuild when they change 43OT_CFLAGS+=-Wall -Wextra -Wwrite-strings -pipe -pthread
55BUILDSTAMP=.buildstamp 44OT_LDFLAGS+=-pthread
56BUILDDEPS=Makefile $(BUILDSTAMP)
57 45
58$(BUILDSTAMP): FORCE 46OPTS_debug=-D_DEBUG -g -ggdb
59 @echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" | cmp -s - $@ 2>/dev/null || echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" > $@
60 47
61FORCE: 48COMPILE=$(CPPFLAGS) $(OT_CFLAGS) $(FEATURES)
49LINK=$(LDFLAGS) $(OT_LDFLAGS) $(LDLIBS) $(OT_LDLIBS)
62 50
63BINARY =opentracker 51BINARY=opentracker
64HEADERS=trackerlogic.h ot_urlencoded.h ot_batch.h ot_buf.h ot_event.h ot_fdstate.h ot_fmt.h ot_hex.h ot_ip.h ot_config.h ot_scan.h ot_socket.h ot_tcp.h ot_worker.h ot_workqueue.h ot_mutex.h ot_random.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h ot_rijndael.h 52HEADERS=src/trackerlogic.h src/ot_urlencoded.h src/ot_batch.h src/ot_buf.h src/ot_event.h src/ot_fdstate.h src/ot_fmt.h src/ot_hex.h src/ot_ip.h src/ot_config.h src/ot_scan.h src/ot_socket.h src/ot_tcp.h src/ot_worker.h src/ot_workqueue.h src/ot_mutex.h src/ot_random.h src/ot_stats.h src/ot_vector.h src/ot_clean.h src/ot_udp.h src/ot_iovec.h src/ot_fullscrape.h src/ot_accesslist.h src/ot_http.h src/ot_livesync.h src/ot_rijndael.h
65SOURCES=opentracker.c trackerlogic.c ot_urlencoded.c ot_batch.c ot_buf.c ot_event.c ot_fdstate.c ot_fmt.c ot_hex.c ot_ip.c ot_config.c ot_scan.c ot_socket.c ot_tcp.c ot_worker.c ot_workqueue.c ot_mutex.c ot_random.c ot_stats.c ot_vector.c ot_clean.c ot_udp.c ot_iovec.c ot_fullscrape.c ot_accesslist.c ot_http.c ot_livesync.c ot_rijndael.c 53SOURCES=src/opentracker.c src/trackerlogic.c src/ot_urlencoded.c src/ot_batch.c src/ot_buf.c src/ot_event.c src/ot_fdstate.c src/ot_fmt.c src/ot_hex.c src/ot_ip.c src/ot_config.c src/ot_scan.c src/ot_socket.c src/ot_tcp.c src/ot_worker.c src/ot_workqueue.c src/ot_mutex.c src/ot_random.c src/ot_stats.c src/ot_vector.c src/ot_clean.c src/ot_udp.c src/ot_iovec.c src/ot_fullscrape.c src/ot_accesslist.c src/ot_http.c src/ot_livesync.c src/ot_rijndael.c
54BINARIES=$(BINARY) $(BINARY).debug
66 55
67all: $(BINARY) $(BINARY).debug 56# Everything is built in one go from sources, so there are no object files to
57# carry a flag change over into the next build. The stamp holds the flags the
58# last build used, which covers FEATURES passed in the environment and a moved
59# HEAD. It is only written when they differ.
60BUILDSTAMP=.buildstamp
61BUILDDEPS=Makefile $(BUILDSTAMP)
68 62
69CFLAGS_production = $(CFLAGS) $(OPTS_production) $(FEATURES) 63all: $(BINARY) $(BINARY).debug
70CFLAGS_debug = $(CFLAGS) $(OPTS_debug) $(FEATURES)
71 64
72$(BINARY): $(SOURCES) $(HEADERS) $(BUILDDEPS) 65$(BINARY): $(SOURCES) $(HEADERS) $(BUILDDEPS)
73 $(CC) -o $@ $(CFLAGS_production) $(SOURCES) $(LDFLAGS) 66 $(CC) -o $@ $(CFLAGS) $(COMPILE) $(SOURCES) $(LINK)
74 $(STRIP) $@ 67 $(STRIP) $@
75$(BINARY).debug: $(SOURCES) $(HEADERS) $(BUILDDEPS)
76 $(CC) -o $@ $(CFLAGS_debug) $(SOURCES) $(LDFLAGS)
77
78# The proxy is out of service
79#
80# SOURCES_proxy=proxy.c ot_batch.c ot_fdstate.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c ot_ip.c ot_socket.c
81# CFLAGS_proxy = $(CFLAGS_production) -DWANT_SYNC_LIVE
82# CFLAGS_proxy_debug = $(CFLAGS_debug) -DWANT_SYNC_LIVE
83#
84# proxy: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS)
85# $(CC) -o $@ $(CFLAGS_proxy) $(SOURCES_proxy) $(LDFLAGS)
86# proxy.debug: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS)
87# $(CC) -o $@ $(CFLAGS_proxy_debug) $(SOURCES_proxy) $(LDFLAGS)
88
89# Unit tests. The modules under test are compiled straight into the test
90# binary, so a test may reach a static function by including the source if it
91# has to. tests/stubs.c supplies the few symbols those modules reference but
92# the tests never reach.
93TESTBIN=tests/runner
94TEST_SOURCES=tests/runner.c tests/test.c tests/stubs.c tests/t_urlencoded.c tests/t_iovec.c tests/t_vector.c tests/t_random.c tests/t_hex.c tests/t_accesslist.c tests/t_scan.c tests/t_buf.c tests/t_ip.c tests/t_socket.c tests/t_mutex.c tests/t_trackerlogic.c tests/t_workqueue.c tests/t_batch.c tests/t_fdstate.c tests/t_event.c tests/t_fmt.c
95TEST_UNITS=ot_urlencoded.c ot_fmt.c ot_event.c ot_batch.c ot_fdstate.c ot_buf.c ot_ip.c ot_socket.c ot_iovec.c ot_vector.c ot_random.c ot_hex.c ot_scan.c ot_accesslist.c ot_mutex.c ot_workqueue.c trackerlogic.c
96TEST_HEADERS=tests/test.h $(HEADERS)
97# Tests reach code that sits behind feature flags, so the units under test are
98# built with those features enabled. A test binary is not a production binary.
99FEATURES_test=$(FEATURES) -DWANT_ACCESSLIST_BLACK -DWANT_SYNC_LIVE
100CFLAGS_test = $(CFLAGS) -I. -g -O1 $(FEATURES_test)
101
102$(TESTBIN): $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS)
103 $(CC) -o $@ $(CFLAGS_test) $(TEST_SOURCES) $(TEST_UNITS)
104
105check: $(TESTBIN) $(BINARY)
106 ./$(TESTBIN)
107 68
108$(TESTBIN).poll: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) 69$(BINARY).debug: $(SOURCES) $(HEADERS) $(BUILDDEPS)
109 $(CC) -o $@ $(CFLAGS_test) -DOT_EVENT_FORCE_POLL $(TEST_SOURCES) $(TEST_UNITS) 70 $(CC) -o $@ $(OPTS_debug) $(COMPILE) $(SOURCES) $(LINK)
110
111check-poll: $(TESTBIN).poll
112 ./$(TESTBIN).poll ot_event
113
114# The same unit tests under the sanitizers. Use clang over $(CC) because the
115# two toolchains do not check the same things
116# Override CC_sanitize to use another compiler.
117CC_sanitize?=clang
118CFLAGS_sanitize=$(CFLAGS_test) -fsanitize=address,undefined -fno-omit-frame-pointer
119LDFLAGS_sanitize=$(LDFLAGS) -fsanitize=address,undefined
120
121$(TESTBIN).sanitize: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS)
122 $(CC_sanitize) -o $@ $(CFLAGS_sanitize) $(TEST_SOURCES) $(TEST_UNITS) $(LDFLAGS_sanitize)
123
124check-sanitize: $(TESTBIN).sanitize
125 ./$(TESTBIN).sanitize
126
127# Black box tests: these drive the real binary over the wire, so they cover
128# the event loop and the parsers working together, which the unit tests
129# cannot reach. Built with the sanitizers on, so the tracker reports its own
130# memory errors and the harness turns those into failures.
131PYTHON?=python3
132# The client timeout is cut right down so that tests can reach the expiry
133# sweep. tests/integration/test_expiry.py mirrors these two numbers.
134FEATURES_integration=$(FEATURES) -DWANT_IP_FROM_QUERY_STRING -DWANT_ACCESSLIST_BLACK -DWANT_DYNAMIC_ACCESSLIST -DWANT_KEEPALIVE -DOT_CLIENT_TIMEOUT=5 -DOT_CLIENT_TIMEOUT_CHECKINTERVAL=1
135CFLAGS_integration=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=address,undefined -fno-omit-frame-pointer
136LDFLAGS_integration=$(LDFLAGS) -fsanitize=address,undefined
137
138opentracker.integration: $(SOURCES) $(HEADERS) $(BUILDDEPS)
139 $(CC) -o $@ $(CFLAGS_integration) $(SOURCES) $(LDFLAGS_integration)
140
141check-integration: opentracker.integration
142 OPENTRACKER=./opentracker.integration $(PYTHON) -m unittest discover -s tests/integration
143
144# The same black box tests against a ThreadSanitizer build
145CFLAGS_tsan=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=thread -fno-omit-frame-pointer
146LDFLAGS_tsan=$(LDFLAGS) -fsanitize=thread
147
148opentracker.tsan: $(SOURCES) $(HEADERS) $(BUILDDEPS)
149 $(CC) -o $@ $(CFLAGS_tsan) $(SOURCES) $(LDFLAGS_tsan)
150
151check-tsan: opentracker.tsan
152 OPENTRACKER=./opentracker.tsan $(PYTHON) -m unittest discover -s tests/integration
153
154# Everything, cheapest first, so a quick failure comes back quickly.
155check-all:
156 $(MAKE) check
157 $(MAKE) check-poll
158 $(MAKE) check-sanitize
159 $(MAKE) check-integration
160 $(MAKE) check-tsan
161
162.PHONY: all FORCE dist check check-poll check-sanitize check-integration check-tsan check-all clean install
163 71
164BINARIES=opentracker opentracker.debug opentracker.integration opentracker.tsan $(TESTBIN) $(TESTBIN).sanitize $(TESTBIN).poll 72$(BUILDSTAMP): FORCE
73 @echo "$(CFLAGS) $(COMPILE) $(LINK)" | cmp -s - $@ 2>/dev/null || echo "$(CFLAGS) $(COMPILE) $(LINK)" > $@
165 74
166clean: 75clean:
167 rm -rf $(BINARIES) $(BINARIES:=.dSYM) $(BUILDSTAMP) *.o *~ 76 rm -rf $(BINARIES) $(BINARIES:=.dSYM) $(BUILDSTAMP) *.o *~ src/*.o src/*~
168 77
169install: 78install: $(BINARY)
170 install -m 755 opentracker $(DESTDIR)$(BINDIR) 79 install -d $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)$(MANDIR)/man5
80 install -m 755 $(BINARY) $(DESTDIR)$(BINDIR)
81 install -m 644 man1/opentracker.1 $(DESTDIR)$(MANDIR)/man1
82 install -m 644 man5/opentracker.conf.5 $(DESTDIR)$(MANDIR)/man5
83
84FORCE:
171 85
172# Roll a release: tag it v<something>, then make dist. The commit is written 86.PHONY: all clean install FORCE
173# into the tarball, so a build from it reports the same version this checkout
174# would, without a git to ask. The tarball is HEAD by construction, so the
175# working tree it was rolled from does not enter into the version.
176DISTNAME=opentracker-$(VERSION)
177 87
178dist: 88include Mk/tests.mk
179 @test "`git describe --tags --match 'v*' --exact-match 2>/dev/null`" = "v$(VERSION)" || \ 89include Mk/release.mk
180 { echo "HEAD must carry the tag v$(VERSION). Tag the release, or correct VERSION."; exit 1; } 90include Mk/proxy.mk
181 rm -rf $(DISTNAME) $(DISTNAME).tar.gz
182 git archive --format=tar --prefix=$(DISTNAME)/ HEAD | tar -xf -
183 git describe --tags --match "v*" --always > $(DISTNAME)/.tarball-version
184 tar -czf $(DISTNAME).tar.gz $(DISTNAME)
185 rm -rf $(DISTNAME)