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