diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-02 17:02:39 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-02 17:02:39 +0100 |
| commit | 3f3114921d643d347c8c9ad1e85de07d101c3e9f (patch) | |
| tree | 270eadb8a3a787ddc789919c4f1989f658303096 | |
| parent | 28d6bf03e1bb8c38fb7e09ade3c5a9c58d68182e (diff) | |
Split the Makefile into Mk fragments and fix the default target
| -rw-r--r-- | Makefile | 168 | ||||
| -rw-r--r-- | Mk/gzip.mk (renamed from Makefile.gzip) | 0 | ||||
| -rw-r--r-- | Mk/proxy.mk | 25 | ||||
| -rw-r--r-- | Mk/release.mk | 27 | ||||
| -rw-r--r-- | Mk/tests.mk | 72 | ||||
| -rw-r--r-- | Mk/zstd.mk (renamed from Makefile.zstd) | 0 |
6 files changed, 156 insertions, 136 deletions
| @@ -10,16 +10,6 @@ STRIP?=strip | |||
| 10 | #FEATURES+=-DWANT_SYNC_LIVE | 10 | #FEATURES+=-DWANT_SYNC_LIVE |
| 11 | #FEATURES+=-DWANT_IP_FROM_QUERY_STRING | 11 | #FEATURES+=-DWANT_IP_FROM_QUERY_STRING |
| 12 | 12 | ||
| 13 | # If you want gzip support to be compiled in, uncomment the next include. | ||
| 14 | # You can further modify the behaviour by setting DWANT_COMPRESSION_GZIP_ALWAYS | ||
| 15 | # in Makefile.gzip | ||
| 16 | include Makefile.gzip | ||
| 17 | |||
| 18 | # If you want zstd support to be compiled in, uncomment the next include. | ||
| 19 | # You can further modify the behaviour by setting DWANT_COMPRESSION_ZSTD_ALWAYS | ||
| 20 | # in Makefile.zstd | ||
| 21 | #include Makefile.zstd | ||
| 22 | |||
| 23 | #FEATURES+=-DWANT_RESTRICT_STATS | 13 | #FEATURES+=-DWANT_RESTRICT_STATS |
| 24 | #FEATURES+=-DWANT_IP_FROM_PROXY | 14 | #FEATURES+=-DWANT_IP_FROM_PROXY |
| 25 | #FEATURES+=-DWANT_LOG_NUMWANT | 15 | #FEATURES+=-DWANT_LOG_NUMWANT |
| @@ -29,155 +19,61 @@ include Makefile.gzip | |||
| 29 | #FEATURES+=-DWANT_DEV_RANDOM | 19 | #FEATURES+=-DWANT_DEV_RANDOM |
| 30 | FEATURES+=-DWANT_FULLSCRAPE | 20 | FEATURES+=-DWANT_FULLSCRAPE |
| 31 | 21 | ||
| 32 | # opentracker takes its randomness from arc4random, which is part of libc on | ||
| 33 | # the BSDs, on macOS and on glibc 2.36 and newer. On an older glibc or on musl | ||
| 34 | # it comes from libbsd instead, so uncomment the next include to link it. | ||
| 35 | #LDFLAGS+=-lbsd | ||
| 36 | |||
| 37 | #FEATURES+=-D_DEBUG_HTTPERROR | 22 | #FEATURES+=-D_DEBUG_HTTPERROR |
| 38 | #FEATURES+=-D_DEBUG_RANDOMTORRENTS | 23 | #FEATURES+=-D_DEBUG_RANDOMTORRENTS |
| 39 | 24 | ||
| 40 | VERSION=1.0.0 | 25 | # Compression support, off unless included. Each file carries a second switch |
| 41 | TARBALL_VERSION=test -r .tarball-version && read v < .tarball-version && echo "$$v" | 26 | # to compress even where the client did not ask. |
| 42 | HAVE_GIT=command -v git >/dev/null && test -d .git | 27 | include Mk/gzip.mk |
| 43 | GIT_VERSION=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --always --dirty 2>/dev/null; }'` | 28 | #include Mk/zstd.mk |
| 44 | OT_TAG=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --exact-match 2>/dev/null; }'` | ||
| 45 | 29 | ||
| 46 | OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage | 30 | # arc4random is part of libc on the BSDs, on macOS and on glibc 2.36 and |
| 47 | OPTS_production=-O3 | 31 | # newer. On an older glibc or on musl it comes from libbsd instead. |
| 32 | #LDFLAGS+=-lbsd | ||
| 48 | 33 | ||
| 49 | CFLAGS+=-DOT_VERSION=\"$(VERSION)\" -DGIT_VERSION=\"$(GIT_VERSION)\" -DOT_TAG=\"$(OT_TAG)\" -Wall -pipe -pthread -Wextra -Wwrite-strings #-ansi -pedantic | 34 | CFLAGS+=-Wall -Wextra -Wwrite-strings -pipe -pthread |
| 50 | LDFLAGS+=-pthread | 35 | LDFLAGS+=-pthread |
| 51 | 36 | ||
| 52 | # Record feature flags as a dep to allow rebuild when they change | 37 | OPTS_production=-O3 |
| 53 | BUILDSTAMP=.buildstamp | 38 | OPTS_debug=-D_DEBUG -g -ggdb |
| 54 | BUILDDEPS=Makefile $(BUILDSTAMP) | ||
| 55 | |||
| 56 | $(BUILDSTAMP): FORCE | ||
| 57 | @echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" | cmp -s - $@ 2>/dev/null || echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" > $@ | ||
| 58 | |||
| 59 | FORCE: | ||
| 60 | 39 | ||
| 61 | BINARY =opentracker | 40 | BINARY=opentracker |
| 62 | HEADERS=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 | 41 | HEADERS=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 |
| 63 | SOURCES=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 | 42 | SOURCES=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 |
| 43 | BINARIES=$(BINARY) $(BINARY).debug | ||
| 64 | 44 | ||
| 65 | all: $(BINARY) $(BINARY).debug | 45 | # Everything is built in one go from sources, so there are no object files to |
| 46 | # carry a flag change over into the next build. The stamp holds the flags the | ||
| 47 | # last build used, which covers FEATURES passed in the environment and a moved | ||
| 48 | # HEAD. It is only written when they differ. | ||
| 49 | BUILDSTAMP=.buildstamp | ||
| 50 | BUILDDEPS=Makefile $(BUILDSTAMP) | ||
| 51 | |||
| 52 | CFLAGS_production=$(CFLAGS) $(OPTS_production) $(FEATURES) | ||
| 53 | CFLAGS_debug=$(CFLAGS) $(OPTS_debug) $(FEATURES) | ||
| 66 | 54 | ||
| 67 | CFLAGS_production = $(CFLAGS) $(OPTS_production) $(FEATURES) | 55 | all: $(BINARY) $(BINARY).debug |
| 68 | CFLAGS_debug = $(CFLAGS) $(OPTS_debug) $(FEATURES) | ||
| 69 | 56 | ||
| 70 | $(BINARY): $(SOURCES) $(HEADERS) $(BUILDDEPS) | 57 | $(BINARY): $(SOURCES) $(HEADERS) $(BUILDDEPS) |
| 71 | $(CC) -o $@ $(CFLAGS_production) $(SOURCES) $(LDFLAGS) | 58 | $(CC) -o $@ $(CFLAGS_production) $(SOURCES) $(LDFLAGS) |
| 72 | $(STRIP) $@ | 59 | $(STRIP) $@ |
| 60 | |||
| 73 | $(BINARY).debug: $(SOURCES) $(HEADERS) $(BUILDDEPS) | 61 | $(BINARY).debug: $(SOURCES) $(HEADERS) $(BUILDDEPS) |
| 74 | $(CC) -o $@ $(CFLAGS_debug) $(SOURCES) $(LDFLAGS) | 62 | $(CC) -o $@ $(CFLAGS_debug) $(SOURCES) $(LDFLAGS) |
| 75 | 63 | ||
| 76 | # The proxy is out of service | 64 | $(BUILDSTAMP): FORCE |
| 77 | # | 65 | @echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" | cmp -s - $@ 2>/dev/null || echo "$(CFLAGS) $(FEATURES) $(LDFLAGS)" > $@ |
| 78 | # 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 | ||
| 79 | # CFLAGS_proxy = $(CFLAGS_production) -DWANT_SYNC_LIVE | ||
| 80 | # CFLAGS_proxy_debug = $(CFLAGS_debug) -DWANT_SYNC_LIVE | ||
| 81 | # | ||
| 82 | # proxy: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS) | ||
| 83 | # $(CC) -o $@ $(CFLAGS_proxy) $(SOURCES_proxy) $(LDFLAGS) | ||
| 84 | # proxy.debug: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS) | ||
| 85 | # $(CC) -o $@ $(CFLAGS_proxy_debug) $(SOURCES_proxy) $(LDFLAGS) | ||
| 86 | |||
| 87 | # Unit tests. The modules under test are compiled straight into the test | ||
| 88 | # binary, so a test may reach a static function by including the source if it | ||
| 89 | # has to. tests/stubs.c supplies the few symbols those modules reference but | ||
| 90 | # the tests never reach. | ||
| 91 | TESTBIN=tests/runner | ||
| 92 | TEST_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 | ||
| 93 | TEST_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 | ||
| 94 | TEST_HEADERS=tests/test.h $(HEADERS) | ||
| 95 | # Tests reach code that sits behind feature flags, so the units under test are | ||
| 96 | # built with those features enabled. A test binary is not a production binary. | ||
| 97 | FEATURES_test=$(FEATURES) -DWANT_ACCESSLIST_BLACK -DWANT_SYNC_LIVE | ||
| 98 | CFLAGS_test = $(CFLAGS) -I. -g -O1 $(FEATURES_test) | ||
| 99 | |||
| 100 | $(TESTBIN): $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 101 | $(CC) -o $@ $(CFLAGS_test) $(TEST_SOURCES) $(TEST_UNITS) | ||
| 102 | |||
| 103 | check: $(TESTBIN) $(BINARY) | ||
| 104 | ./$(TESTBIN) | ||
| 105 | |||
| 106 | $(TESTBIN).poll: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 107 | $(CC) -o $@ $(CFLAGS_test) -DOT_EVENT_FORCE_POLL $(TEST_SOURCES) $(TEST_UNITS) | ||
| 108 | |||
| 109 | check-poll: $(TESTBIN).poll | ||
| 110 | ./$(TESTBIN).poll ot_event | ||
| 111 | |||
| 112 | # The same unit tests under the sanitizers. Use clang over $(CC) because the | ||
| 113 | # two toolchains do not check the same things | ||
| 114 | # Override CC_sanitize to use another compiler. | ||
| 115 | CC_sanitize?=clang | ||
| 116 | CFLAGS_sanitize=$(CFLAGS_test) -fsanitize=address,undefined -fno-omit-frame-pointer | ||
| 117 | LDFLAGS_sanitize=$(LDFLAGS) -fsanitize=address,undefined | ||
| 118 | |||
| 119 | $(TESTBIN).sanitize: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 120 | $(CC_sanitize) -o $@ $(CFLAGS_sanitize) $(TEST_SOURCES) $(TEST_UNITS) $(LDFLAGS_sanitize) | ||
| 121 | |||
| 122 | check-sanitize: $(TESTBIN).sanitize | ||
| 123 | ./$(TESTBIN).sanitize | ||
| 124 | |||
| 125 | # Black box tests: these drive the real binary over the wire, so they cover | ||
| 126 | # the event loop and the parsers working together, which the unit tests | ||
| 127 | # cannot reach. Built with the sanitizers on, so the tracker reports its own | ||
| 128 | # memory errors and the harness turns those into failures. | ||
| 129 | PYTHON?=python3 | ||
| 130 | # The client timeout is cut right down so that tests can reach the expiry | ||
| 131 | # sweep. tests/integration/test_expiry.py mirrors these two numbers. | ||
| 132 | FEATURES_integration=$(FEATURES) -DWANT_IP_FROM_QUERY_STRING -DWANT_ACCESSLIST_BLACK -DWANT_DYNAMIC_ACCESSLIST -DWANT_KEEPALIVE -DOT_CLIENT_TIMEOUT=5 -DOT_CLIENT_TIMEOUT_CHECKINTERVAL=1 | ||
| 133 | CFLAGS_integration=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=address,undefined -fno-omit-frame-pointer | ||
| 134 | LDFLAGS_integration=$(LDFLAGS) -fsanitize=address,undefined | ||
| 135 | |||
| 136 | opentracker.integration: $(SOURCES) $(HEADERS) $(BUILDDEPS) | ||
| 137 | $(CC) -o $@ $(CFLAGS_integration) $(SOURCES) $(LDFLAGS_integration) | ||
| 138 | |||
| 139 | check-integration: opentracker.integration | ||
| 140 | OPENTRACKER=./opentracker.integration $(PYTHON) -m unittest discover -s tests/integration | ||
| 141 | |||
| 142 | # The same black box tests against a ThreadSanitizer build | ||
| 143 | CFLAGS_tsan=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=thread -fno-omit-frame-pointer | ||
| 144 | LDFLAGS_tsan=$(LDFLAGS) -fsanitize=thread | ||
| 145 | |||
| 146 | opentracker.tsan: $(SOURCES) $(HEADERS) $(BUILDDEPS) | ||
| 147 | $(CC) -o $@ $(CFLAGS_tsan) $(SOURCES) $(LDFLAGS_tsan) | ||
| 148 | |||
| 149 | check-tsan: opentracker.tsan | ||
| 150 | OPENTRACKER=./opentracker.tsan $(PYTHON) -m unittest discover -s tests/integration | ||
| 151 | |||
| 152 | # Everything, cheapest first, so a quick failure comes back quickly. | ||
| 153 | check-all: | ||
| 154 | $(MAKE) check | ||
| 155 | $(MAKE) check-poll | ||
| 156 | $(MAKE) check-sanitize | ||
| 157 | $(MAKE) check-integration | ||
| 158 | $(MAKE) check-tsan | ||
| 159 | |||
| 160 | .PHONY: all FORCE dist check check-poll check-sanitize check-integration check-tsan check-all clean install | ||
| 161 | |||
| 162 | BINARIES=opentracker opentracker.debug opentracker.integration opentracker.tsan $(TESTBIN) $(TESTBIN).sanitize $(TESTBIN).poll | ||
| 163 | 66 | ||
| 164 | clean: | 67 | clean: |
| 165 | rm -rf $(BINARIES) $(BINARIES:=.dSYM) $(BUILDSTAMP) *.o *~ | 68 | rm -rf $(BINARIES) $(BINARIES:=.dSYM) $(BUILDSTAMP) *.o *~ |
| 166 | 69 | ||
| 167 | install: | 70 | install: |
| 168 | install -m 755 opentracker $(DESTDIR)$(BINDIR) | 71 | install -m 755 $(BINARY) $(DESTDIR)$(BINDIR) |
| 72 | |||
| 73 | FORCE: | ||
| 169 | 74 | ||
| 170 | # Roll a release: tag it v<something>, then make dist. The commit is written | 75 | .PHONY: all clean install FORCE |
| 171 | # into the tarball, so a build from it reports the same version this checkout | ||
| 172 | # would, without a git to ask. The tarball is HEAD by construction, so the | ||
| 173 | # working tree it was rolled from does not enter into the version. | ||
| 174 | DISTNAME=opentracker-$(VERSION) | ||
| 175 | 76 | ||
| 176 | dist: | 77 | include Mk/tests.mk |
| 177 | @test "`git describe --tags --match 'v*' --exact-match 2>/dev/null`" = "v$(VERSION)" || \ | 78 | include Mk/release.mk |
| 178 | { echo "HEAD must carry the tag v$(VERSION). Tag the release, or correct VERSION."; exit 1; } | 79 | include Mk/proxy.mk |
| 179 | rm -rf $(DISTNAME) $(DISTNAME).tar.gz | ||
| 180 | git archive --format=tar --prefix=$(DISTNAME)/ HEAD | tar -xf - | ||
| 181 | git describe --tags --match "v*" --always > $(DISTNAME)/.tarball-version | ||
| 182 | tar -czf $(DISTNAME).tar.gz $(DISTNAME) | ||
| 183 | rm -rf $(DISTNAME) | ||
diff --git a/Makefile.gzip b/Mk/gzip.mk index 70d6d62..70d6d62 100644 --- a/Makefile.gzip +++ b/Mk/gzip.mk | |||
diff --git a/Mk/proxy.mk b/Mk/proxy.mk new file mode 100644 index 0000000..2e876e9 --- /dev/null +++ b/Mk/proxy.mk | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | # The proxy relays sync traffic between trackers and between multicast domains | ||
| 2 | # that cannot reach each other. It does not build; see the note at the top of | ||
| 3 | # proxy.c. Scheduled for v1.1.0, when these rules come back. | ||
| 4 | # | ||
| 5 | # LIBOWFAT_HEADERS=$(PREFIX)/libowfat | ||
| 6 | # LIBOWFAT_LIBRARY=$(PREFIX)/libowfat | ||
| 7 | # CFLAGS_libowfat=-I$(LIBOWFAT_HEADERS) | ||
| 8 | # LDFLAGS_libowfat=-L$(LIBOWFAT_LIBRARY) -lowfat | ||
| 9 | # | ||
| 10 | # 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 | ||
| 11 | # CFLAGS_proxy=$(CFLAGS_production) $(CFLAGS_libowfat) -DWANT_SYNC_LIVE | ||
| 12 | # CFLAGS_proxy_debug=$(CFLAGS_debug) $(CFLAGS_libowfat) -DWANT_SYNC_LIVE | ||
| 13 | # | ||
| 14 | # BINARIES+=proxy proxy.debug | ||
| 15 | # | ||
| 16 | # proxy: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS) | ||
| 17 | # $(CC) -o $@ $(CFLAGS_proxy) $(SOURCES_proxy) $(LDFLAGS) $(LDFLAGS_libowfat) | ||
| 18 | # proxy.debug: $(SOURCES_proxy) $(HEADERS) $(BUILDDEPS) | ||
| 19 | # $(CC) -o $@ $(CFLAGS_proxy_debug) $(SOURCES_proxy) $(LDFLAGS) $(LDFLAGS_libowfat) | ||
| 20 | |||
| 21 | proxy proxy.debug: | ||
| 22 | @echo "$@ is out of service until v1.1.0, see the note at the top of proxy.c" | ||
| 23 | @false | ||
| 24 | |||
| 25 | .PHONY: proxy proxy.debug | ||
diff --git a/Mk/release.mk b/Mk/release.mk new file mode 100644 index 0000000..63429ad --- /dev/null +++ b/Mk/release.mk | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | # .tarball-version is what dist wrote into the tarball | ||
| 2 | # In a checkout it is absent and git answers instead. A release is always | ||
| 3 | # tagged, so in a tarball both of these are that tag, and the gitweb link | ||
| 4 | # is to it. Between releases there is no tag and the version is the commit. | ||
| 5 | VERSION=1.0.0 | ||
| 6 | |||
| 7 | TARBALL_VERSION=test -r .tarball-version && read v < .tarball-version && echo "$$v" | ||
| 8 | HAVE_GIT=command -v git >/dev/null && test -d .git | ||
| 9 | GIT_VERSION=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --always --dirty 2>/dev/null; }'` | ||
| 10 | OT_TAG=`sh -c '$(TARBALL_VERSION) || { $(HAVE_GIT) && git describe --tags --match "v*" --exact-match 2>/dev/null; }'` | ||
| 11 | |||
| 12 | CFLAGS+=-DOT_VERSION=\"$(VERSION)\" -DGIT_VERSION=\"$(GIT_VERSION)\" -DOT_TAG=\"$(OT_TAG)\" | ||
| 13 | |||
| 14 | # Roll a release: tag it v$(VERSION), then make dist. The tarball is HEAD by | ||
| 15 | # construction, so the working tree it was rolled from does not enter into it. | ||
| 16 | DISTNAME=opentracker-$(VERSION) | ||
| 17 | |||
| 18 | dist: | ||
| 19 | @test "`git describe --tags --match 'v*' --exact-match 2>/dev/null`" = "v$(VERSION)" || \ | ||
| 20 | { echo "HEAD must carry the tag v$(VERSION). Tag the release, or correct VERSION."; exit 1; } | ||
| 21 | rm -rf $(DISTNAME) $(DISTNAME).tar.gz | ||
| 22 | git archive --format=tar --prefix=$(DISTNAME)/ HEAD | tar -xf - | ||
| 23 | git describe --tags --match "v*" --always > $(DISTNAME)/.tarball-version | ||
| 24 | tar -czf $(DISTNAME).tar.gz $(DISTNAME) | ||
| 25 | rm -rf $(DISTNAME) | ||
| 26 | |||
| 27 | .PHONY: dist | ||
diff --git a/Mk/tests.mk b/Mk/tests.mk new file mode 100644 index 0000000..d542044 --- /dev/null +++ b/Mk/tests.mk | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | BUILDDEPS+=Mk/tests.mk | ||
| 2 | |||
| 3 | # The modules under test are compiled straight into the test binary, so a test | ||
| 4 | # may reach a static function by including the source. tests/stubs.c supplies | ||
| 5 | # the few symbols those modules reference but the tests never reach. | ||
| 6 | TESTBIN=tests/runner | ||
| 7 | TEST_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 | ||
| 8 | TEST_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 | ||
| 9 | TEST_HEADERS=tests/test.h $(HEADERS) | ||
| 10 | |||
| 11 | # A test binary is not a production binary, so it is built with the features | ||
| 12 | # the tests need to reach. | ||
| 13 | FEATURES_test=$(FEATURES) -DWANT_ACCESSLIST_BLACK -DWANT_SYNC_LIVE | ||
| 14 | CFLAGS_test=$(CFLAGS) -I. -g -O1 $(FEATURES_test) | ||
| 15 | |||
| 16 | # clang over $(CC) because the two toolchains do not check the same things. | ||
| 17 | CC_sanitize?=clang | ||
| 18 | CFLAGS_sanitize=$(CFLAGS_test) -fsanitize=address,undefined -fno-omit-frame-pointer | ||
| 19 | LDFLAGS_sanitize=$(LDFLAGS) -fsanitize=address,undefined | ||
| 20 | |||
| 21 | # Black box tests drive the real binary over the wire, so they cover the event | ||
| 22 | # loop and the parsers working together. The client timeout is cut right down | ||
| 23 | # so a test can reach the expiry sweep; tests/integration/test_expiry.py | ||
| 24 | # mirrors these two numbers. | ||
| 25 | PYTHON?=python3 | ||
| 26 | FEATURES_integration=$(FEATURES) -DWANT_IP_FROM_QUERY_STRING -DWANT_ACCESSLIST_BLACK -DWANT_DYNAMIC_ACCESSLIST -DWANT_KEEPALIVE -DOT_CLIENT_TIMEOUT=5 -DOT_CLIENT_TIMEOUT_CHECKINTERVAL=1 | ||
| 27 | CFLAGS_integration=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=address,undefined -fno-omit-frame-pointer | ||
| 28 | LDFLAGS_integration=$(LDFLAGS) -fsanitize=address,undefined | ||
| 29 | CFLAGS_tsan=$(CFLAGS) $(OPTS_debug) $(FEATURES_integration) -fsanitize=thread -fno-omit-frame-pointer | ||
| 30 | LDFLAGS_tsan=$(LDFLAGS) -fsanitize=thread | ||
| 31 | |||
| 32 | BINARIES+=$(TESTBIN) $(TESTBIN).poll $(TESTBIN).sanitize opentracker.integration opentracker.tsan | ||
| 33 | |||
| 34 | $(TESTBIN): $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 35 | $(CC) -o $@ $(CFLAGS_test) $(TEST_SOURCES) $(TEST_UNITS) | ||
| 36 | |||
| 37 | $(TESTBIN).poll: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 38 | $(CC) -o $@ $(CFLAGS_test) -DOT_EVENT_FORCE_POLL $(TEST_SOURCES) $(TEST_UNITS) | ||
| 39 | |||
| 40 | $(TESTBIN).sanitize: $(TEST_SOURCES) $(TEST_UNITS) $(TEST_HEADERS) $(BUILDDEPS) | ||
| 41 | $(CC_sanitize) -o $@ $(CFLAGS_sanitize) $(TEST_SOURCES) $(TEST_UNITS) $(LDFLAGS_sanitize) | ||
| 42 | |||
| 43 | opentracker.integration: $(SOURCES) $(HEADERS) $(BUILDDEPS) | ||
| 44 | $(CC) -o $@ $(CFLAGS_integration) $(SOURCES) $(LDFLAGS_integration) | ||
| 45 | |||
| 46 | opentracker.tsan: $(SOURCES) $(HEADERS) $(BUILDDEPS) | ||
| 47 | $(CC) -o $@ $(CFLAGS_tsan) $(SOURCES) $(LDFLAGS_tsan) | ||
| 48 | |||
| 49 | check: $(TESTBIN) $(BINARY) | ||
| 50 | ./$(TESTBIN) | ||
| 51 | |||
| 52 | check-poll: $(TESTBIN).poll | ||
| 53 | ./$(TESTBIN).poll ot_event | ||
| 54 | |||
| 55 | check-sanitize: $(TESTBIN).sanitize | ||
| 56 | ./$(TESTBIN).sanitize | ||
| 57 | |||
| 58 | check-integration: opentracker.integration | ||
| 59 | OPENTRACKER=./opentracker.integration $(PYTHON) -m unittest discover -s tests/integration | ||
| 60 | |||
| 61 | check-tsan: opentracker.tsan | ||
| 62 | OPENTRACKER=./opentracker.tsan $(PYTHON) -m unittest discover -s tests/integration | ||
| 63 | |||
| 64 | # Cheapest first, so a quick failure comes back quickly. | ||
| 65 | check-all: | ||
| 66 | $(MAKE) check | ||
| 67 | $(MAKE) check-poll | ||
| 68 | $(MAKE) check-sanitize | ||
| 69 | $(MAKE) check-integration | ||
| 70 | $(MAKE) check-tsan | ||
| 71 | |||
| 72 | .PHONY: check check-poll check-sanitize check-integration check-tsan check-all | ||
diff --git a/Makefile.zstd b/Mk/zstd.mk index 2bb56be..2bb56be 100644 --- a/Makefile.zstd +++ b/Mk/zstd.mk | |||
