1# ################################################################ 2# Copyright (c) Yann Collet, Facebook, Inc. 3# All rights reserved. 4# 5# This source code is licensed under both the BSD-style license (found in the 6# LICENSE file in the root directory of this source tree) and the GPLv2 (found 7# in the COPYING file in the root directory of this source tree). 8# You may select, at your option, one of the above-listed licenses. 9# ################################################################ 10# datagen : Synthetic and parametrable data generator, for tests 11# fullbench : Precisely measure speed for each zstd inner functions 12# fullbench32: Same as fullbench, but forced to compile in 32-bits mode 13# fuzzer : Test tool, to check zstd integrity on target platform 14# fuzzer32: Same as fuzzer, but forced to compile in 32-bits mode 15# paramgrill : parameter tester for zstd 16# test-zstd-speed.py : script for testing zstd speed difference between commits 17# versionsTest : compatibility test between zstd versions stored on Github (v0.1+) 18# zstreamtest : Fuzzer test tool for zstd streaming API 19# zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode 20# ########################################################################## 21 22ZSTDDIR = ../lib 23PRGDIR = ../programs 24PYTHON ?= python3 25TESTARTEFACT := versionsTest 26 27DEBUGLEVEL ?= 2 28export DEBUGLEVEL # transmit value to sub-makefiles 29DEBUGFLAGS = -g -DDEBUGLEVEL=$(DEBUGLEVEL) 30CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ 31 -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ 32 -DZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY=1 33ifeq ($(OS),Windows_NT) # MinGW assumed 34CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting 35endif 36CFLAGS ?= -O3 37CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ 38 -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ 39 -Wstrict-prototypes -Wundef \ 40 -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ 41 -Wredundant-decls -Wmissing-prototypes -Wno-deprecated-declarations 42CFLAGS += $(DEBUGFLAGS) 43CPPFLAGS += $(MOREFLAGS) 44 45 46ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c 47ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c 48ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c 49ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) 50ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c 51 52ZSTD_F1 := $(wildcard $(ZSTD_FILES)) 53ZSTD_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdm_,$(ZSTD_F1)) 54ZSTD_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdc_,$(ZSTD_OBJ1)) 55ZSTD_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdd_,$(ZSTD_OBJ2)) 56ZSTD_OBJECTS := $(ZSTD_OBJ3:.c=.o) 57 58ZSTDMT_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdmt_m_,$(ZSTD_F1)) 59ZSTDMT_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdmt_c_,$(ZSTDMT_OBJ1)) 60ZSTDMT_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdmt_d_,$(ZSTDMT_OBJ2)) 61ZSTDMT_OBJECTS := $(ZSTDMT_OBJ3:.c=.o) 62 63# Define *.exe as extension for Windows systems 64ifneq (,$(filter Windows%,$(OS))) 65EXT =.exe 66MULTITHREAD_CPP = -DZSTD_MULTITHREAD 67MULTITHREAD_LD = 68else 69EXT = 70MULTITHREAD_CPP = -DZSTD_MULTITHREAD 71MULTITHREAD_LD = -pthread 72endif 73MULTITHREAD = $(MULTITHREAD_CPP) $(MULTITHREAD_LD) 74 75VOID = /dev/null 76ZSTREAM_TESTTIME ?= -T90s 77FUZZERTEST ?= -T200s 78ZSTDRTTEST = --test-large-data 79DECODECORPUS_TESTTIME ?= -T30 80 81.PHONY: default 82default: fullbench 83 84.PHONY: all 85all: fullbench fuzzer zstreamtest paramgrill datagen decodecorpus roundTripCrash poolTests 86 87.PHONY: all32 88all32: fullbench32 fuzzer32 zstreamtest32 89 90.PHONY: allnothread 91allnothread: MULTITHREAD_CPP= 92allnothread: MULTITHREAD_LD= 93allnothread: fullbench fuzzer paramgrill datagen decodecorpus 94 95# note : broken : requires symbols unavailable from dynamic library 96.PHONY: dll 97dll: fuzzer-dll zstreamtest-dll 98 99.PHONY: zstd zstd32 zstd-nolegacy # only external makefile knows how to build or update them 100zstd zstd32 zstd-nolegacy: 101 $(MAKE) -C $(PRGDIR) $@ MOREFLAGS+="$(DEBUGFLAGS)" 102 103.PHONY: libzstd 104libzstd : 105 $(MAKE) -C $(ZSTDDIR) libzstd MOREFLAGS+="$(DEBUGFLAGS)" 106 107%-dll : libzstd 108%-dll : LDFLAGS += -L$(ZSTDDIR) -lzstd 109 110$(ZSTDDIR)/libzstd.a : 111 $(MAKE) -C $(ZSTDDIR) libzstd.a 112 113zstdm_%.o : $(ZSTDDIR)/common/%.c 114 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 115 116zstdc_%.o : $(ZSTDDIR)/compress/%.c 117 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 118 119zstdd_%.o : $(ZSTDDIR)/decompress/%.c 120 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 121 122zstdmt%.o : CPPFLAGS += $(MULTITHREAD_CPP) 123 124zstdmt_m_%.o : $(ZSTDDIR)/common/%.c 125 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 126 127zstdmt_c_%.o : $(ZSTDDIR)/compress/%.c 128 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 129 130zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.c 131 $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 132 133fullbench32: CPPFLAGS += -m32 134fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP) -Wno-deprecated-declarations 135fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD) 136fullbench fullbench32 : DEBUGFLAGS = -DNDEBUG # turn off assert() for speed measurements 137fullbench fullbench32 : $(ZSTD_FILES) 138fullbench fullbench32 : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c fullbench.c 139 $(LINK.c) $^ -o $@$(EXT) 140 141fullbench-lib : CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ 142fullbench-lib : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(ZSTDDIR)/libzstd.a fullbench.c 143 $(LINK.c) $^ -o $@$(EXT) 144 145# note : broken : requires symbols unavailable from dynamic library 146fullbench-dll: $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/benchfn.c $(PRGDIR)/timefn.c fullbench.c 147# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll 148 $(LINK.c) $^ $(LDLIBS) -o $@$(EXT) 149 150fuzzer : CPPFLAGS += $(MULTITHREAD_CPP) -Wno-deprecated-declarations 151fuzzer : LDFLAGS += $(MULTITHREAD_LD) 152fuzzer : $(ZSTDMT_OBJECTS) 153fuzzer fuzzer32 : $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c 154 155fuzzer32 : CFLAGS += -m32 $(MULTITHREAD) 156fuzzer32 : $(ZSTD_FILES) 157 $(LINK.c) $^ -o $@$(EXT) 158 159# note : broken : requires symbols unavailable from dynamic library 160fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c 161 $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) 162 163ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c seqgen.c zstreamtest.c 164ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES) 165ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES) 166zstreamtest32 : CFLAGS += -m32 167zstreamtest zstreamtest32 : CPPFLAGS += $(MULTITHREAD_CPP) 168zstreamtest zstreamtest32 : LDFLAGS += $(MULTITHREAD_LD) 169zstreamtest : $(ZSTDMT_OBJECTS) $(ZSTREAM_PROPER_FILES) 170zstreamtest32 : $(ZSTREAMFILES) 171zstreamtest zstreamtest32 : 172 $(LINK.c) $^ -o $@$(EXT) 173 174zstreamtest_asan : CFLAGS += -fsanitize=address 175zstreamtest_asan : $(ZSTREAMFILES) 176 $(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT) 177 178zstreamtest_tsan : CFLAGS += -fsanitize=thread 179zstreamtest_tsan : $(ZSTREAMFILES) 180 $(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT) 181 182# note : broken : requires symbols unavailable from dynamic library 183zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c # xxh symbols not exposed from dll 184zstreamtest-dll : $(ZSTREAM_LOCAL_FILES) 185 $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) 186 187paramgrill : DEBUGFLAGS = # turn off debug for speed measurements 188paramgrill : LDLIBS += -lm 189paramgrill : $(ZSTD_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/benchfn.c $(PRGDIR)/benchzstd.c $(PRGDIR)/datagen.c paramgrill.c 190 191datagen : $(PRGDIR)/datagen.c datagencli.c 192 $(LINK.c) $^ -o $@$(EXT) 193 194roundTripCrash: CFLAGS += $(MULTITHREAD) 195roundTripCrash : $(ZSTD_OBJECTS) roundTripCrash.c 196 197longmatch : $(ZSTD_OBJECTS) longmatch.c 198 199bigdict: CFLAGS += $(MULTITHREAD) 200bigdict: $(ZSTDMT_OBJECTS) $(PRGDIR)/datagen.c bigdict.c 201 202invalidDictionaries : $(ZSTD_OBJECTS) invalidDictionaries.c 203 204legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -DZSTD_LEGACY_SUPPORT=4 205legacy : $(ZSTD_FILES) $(wildcard $(ZSTDDIR)/legacy/*.c) legacy.c 206 207decodecorpus : LDLIBS += -lm 208decodecorpus : $(filter-out zstdc_zstd_compress.o, $(ZSTD_OBJECTS)) $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c decodecorpus.c 209 210poolTests : $(PRGDIR)/util.c $(PRGDIR)/timefn.c poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/error_private.c 211 $(LINK.c) $(MULTITHREAD) $^ -o $@$(EXT) 212 213.PHONY: versionsTest 214versionsTest: clean 215 $(PYTHON) test-zstd-versions.py 216 217.PHONY: automated_benchmarking 218automated_benchmarking: clean 219 $(PYTHON) automated_benchmarking.py 220 221# make checkTag 222checkTag.o : $(ZSTDDIR)/zstd.h 223 224.PHONY: clean 225clean: 226 $(MAKE) -C $(ZSTDDIR) clean 227 $(MAKE) -C $(PRGDIR) clean 228 $(RM) -fR $(TESTARTEFACT) 229 $(RM) -rf tmp* # some test directories are named tmp* 230 $(RM) core *.o *.tmp result* *.gcda dictionary *.zst \ 231 $(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \ 232 fullbench$(EXT) fullbench32$(EXT) \ 233 fullbench-lib$(EXT) fullbench-dll$(EXT) \ 234 fuzzer$(EXT) fuzzer32$(EXT) \ 235 fuzzer-dll$(EXT) zstreamtest-dll$(EXT) \ 236 zstreamtest$(EXT) zstreamtest32$(EXT) \ 237 datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \ 238 symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \ 239 decodecorpus$(EXT) checkTag$(EXT) bigdict$(EXT) 240 @echo Cleaning completed 241 242 243#---------------------------------------------------------------------------------- 244# valgrind tests are validated only for some posix platforms 245#---------------------------------------------------------------------------------- 246UNAME := $(shell uname) 247ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS)) 248HOST_OS = POSIX 249 250valgrindTest: VALGRIND = valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 251valgrindTest: zstd datagen fuzzer fullbench 252 @echo "\n ---- valgrind tests : memory analyzer ----" 253 $(VALGRIND) ./datagen -g50M > $(VOID) 254 $(VALGRIND) $(PRGDIR)/zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi 255 ./datagen -g80 | $(VALGRIND) $(PRGDIR)/zstd - -c > $(VOID) 256 ./datagen -g16KB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(VOID) 257 ./datagen -g2930KB | $(VALGRIND) $(PRGDIR)/zstd -5 -vf - -o tmp 258 $(VALGRIND) $(PRGDIR)/zstd -vdf tmp -c > $(VOID) 259 ./datagen -g64MB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(VOID) 260 @rm tmp 261 $(VALGRIND) ./fuzzer -T1mn -t1 262 $(VALGRIND) ./fullbench -i1 263 264endif 265 266 267ifneq (,$(filter MINGW% MSYS%,$(UNAME))) 268 HOST_OS = MSYS 269endif 270 271 272#----------------------------------------------------------------------------- 273# make tests validated only for below targets 274#----------------------------------------------------------------------------- 275ifneq (,$(filter $(HOST_OS),MSYS POSIX)) 276 277DIFF:=diff 278ifneq (,$(filter $(UNAME),SunOS)) 279 DIFF:=gdiff 280endif 281 282.PHONY: list 283list: 284 @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs 285 286.PHONY: shortest 287shortest: ZSTDRTTEST= # remove long tests 288shortest: test-zstd 289 290.PHONY: check 291check: shortest 292 293.PHONY: fuzztest 294fuzztest: test-fuzzer test-zstream test-decodecorpus 295 296.PHONY: test 297test: test-zstd test-fullbench test-fuzzer test-zstream test-invalidDictionaries test-legacy test-decodecorpus 298ifeq ($(QEMU_SYS),) 299test: test-pool 300endif 301 302.PHONY: test32 303test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zstream32 304 305.PHONY: test-all 306test-all: test test32 valgrindTest test-decodecorpus-cli 307 308.PHONY: test-zstd test-zstd32 test-zstd-nolegacy test-zstdgrep 309test-zstd: ZSTD = $(PRGDIR)/zstd 310test-zstd: zstd 311 312test-zstd32: ZSTD = $(PRGDIR)/zstd32 313test-zstd32: zstd32 314 315test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd-nolegacy 316test-zstd-nolegacy: zstd-nolegacy 317 318test-zstd test-zstd32 test-zstd-nolegacy: datagen 319 file $(ZSTD) 320 EXE_PREFIX="$(QEMU_SYS)" ZSTD_BIN="$(ZSTD)" DATAGEN_BIN=./datagen ./playTests.sh $(ZSTDRTTEST) 321 322test-fullbench: fullbench datagen 323 $(QEMU_SYS) ./fullbench -i1 324 $(QEMU_SYS) ./fullbench -i1 -P0 325 326test-fullbench32: fullbench32 datagen 327 $(QEMU_SYS) ./fullbench32 -i1 328 $(QEMU_SYS) ./fullbench32 -i1 -P0 329 330test-fuzzer: fuzzer 331 $(QEMU_SYS) ./fuzzer -v $(FUZZERTEST) $(FUZZER_FLAGS) 332 333test-fuzzer-stackmode: MOREFLAGS += -DZSTD_HEAPMODE=0 334test-fuzzer-stackmode: test-fuzzer 335 336test-fuzzer32: fuzzer32 337 $(QEMU_SYS) ./fuzzer32 -v $(FUZZERTEST) $(FUZZER_FLAGS) 338 339test-zstream: zstreamtest 340 $(QEMU_SYS) ./zstreamtest -v $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) 341 $(QEMU_SYS) ./zstreamtest --newapi -t1 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) 342 343test-zstream32: zstreamtest32 344 $(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) 345 346test-longmatch: longmatch 347 $(QEMU_SYS) ./longmatch 348 349test-bigdict: bigdict 350 $(QEMU_SYS) ./bigdict 351 352test-invalidDictionaries: invalidDictionaries 353 $(QEMU_SYS) ./invalidDictionaries 354 355test-legacy: legacy 356 $(QEMU_SYS) ./legacy 357 358test-decodecorpus: decodecorpus 359 $(QEMU_SYS) ./decodecorpus -t $(DECODECORPUS_TESTTIME) 360 361test-decodecorpus-cli: decodecorpus 362 @echo "\n ---- decodecorpus basic cli tests ----" 363 @mkdir testdir 364 ./decodecorpus -n5 -otestdir -ptestdir 365 @cd testdir && \ 366 $(ZSTD) -d z000000.zst -o tmp0 && \ 367 $(ZSTD) -d z000001.zst -o tmp1 && \ 368 $(ZSTD) -d z000002.zst -o tmp2 && \ 369 $(ZSTD) -d z000003.zst -o tmp3 && \ 370 $(ZSTD) -d z000004.zst -o tmp4 && \ 371 diff z000000 tmp0 && \ 372 diff z000001 tmp1 && \ 373 diff z000002 tmp2 && \ 374 diff z000003 tmp3 && \ 375 diff z000004 tmp4 && \ 376 rm ./* && \ 377 cd .. 378 @echo "\n ---- decodecorpus dictionary cli tests ----" 379 ./decodecorpus -n5 -otestdir -ptestdir --use-dict=1MB 380 @cd testdir && \ 381 $(ZSTD) -d z000000.zst -D dictionary -o tmp0 && \ 382 $(ZSTD) -d z000001.zst -D dictionary -o tmp1 && \ 383 $(ZSTD) -d z000002.zst -D dictionary -o tmp2 && \ 384 $(ZSTD) -d z000003.zst -D dictionary -o tmp3 && \ 385 $(ZSTD) -d z000004.zst -D dictionary -o tmp4 && \ 386 diff z000000 tmp0 && \ 387 diff z000001 tmp1 && \ 388 diff z000002 tmp2 && \ 389 diff z000003 tmp3 && \ 390 diff z000004 tmp4 && \ 391 cd .. 392 @rm -rf testdir 393 394test-pool: poolTests 395 $(QEMU_SYS) ./poolTests 396 397test-lz4: ZSTD = LD_LIBRARY_PATH=/usr/local/lib $(PRGDIR)/zstd 398test-lz4: ZSTD_LZ4 = LD_LIBRARY_PATH=/usr/local/lib ./lz4 399test-lz4: ZSTD_UNLZ4 = LD_LIBRARY_PATH=/usr/local/lib ./unlz4 400test-lz4: zstd decodecorpus datagen 401 [ -f lz4 ] || ln -s $(PRGDIR)/zstd lz4 402 [ -f unlz4 ] || ln -s $(PRGDIR)/zstd unlz4 403 404 ./decodecorpus -ptmp 405 # lz4 -> zstd 406 lz4 < tmp | \ 407 $(ZSTD) -d | \ 408 cmp - tmp 409 lz4 < tmp | \ 410 $(ZSTD_UNLZ4) | \ 411 cmp - tmp 412 # zstd -> lz4 413 $(ZSTD) --format=lz4 < tmp | \ 414 lz4 -d | \ 415 cmp - tmp 416 $(ZSTD_LZ4) < tmp | \ 417 lz4 -d | \ 418 cmp - tmp 419 # zstd -> zstd 420 $(ZSTD) --format=lz4 < tmp | \ 421 $(ZSTD) -d | \ 422 cmp - tmp 423 # zstd -> zstd 424 $(ZSTD) < tmp | \ 425 $(ZSTD) -d | \ 426 cmp - tmp 427 428 ./datagen -g384KB | $(ZSTD) --format=lz4 | $(ZSTD) -d > /dev/null 429 430 rm tmp lz4 unlz4 431 432endif 433