1# ################################################################ 2# Copyright (c) 2015-present, 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# ########################################################################## 9# zstd : Command Line Utility, supporting gzip-like arguments 10# zstd32 : Same as zstd, but forced to compile in 32-bits mode 11# zstd_nolegacy : zstd without support of decompression of legacy versions 12# zstd-small : minimal zstd without dictionary builder and benchmark 13# zstd-compress : compressor-only version of zstd 14# zstd-decompress : decompressor-only version of zstd 15# ########################################################################## 16 17ZSTDDIR = ../lib 18 19# Version numbers 20LIBVER_SRC := $(ZSTDDIR)/zstd.h 21LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` 22LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` 23LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` 24LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT) 25LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT)) 26LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT)) 27LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT)) 28LIBVER := $(shell echo $(LIBVER_SCRIPT)) 29 30ZSTD_VERSION = $(LIBVER) 31 32GREP = grep --color=never 33 34ifeq ($(shell $(CC) -v 2>&1 | $(GREP) -c "gcc version "), 1) 35ALIGN_LOOP = -falign-loops=32 36else 37ALIGN_LOOP = 38endif 39 40CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ 41 -I$(ZSTDDIR)/dictBuilder \ 42 -DXXH_NAMESPACE=ZSTD_ 43ifeq ($(OS),Windows_NT) # MinGW assumed 44CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting 45endif 46CFLAGS ?= -O3 47DEBUGFLAGS+=-Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ 48 -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ 49 -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \ 50 -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ 51 -Wredundant-decls -Wmissing-prototypes 52CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) 53FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) 54 55 56ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c 57ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c 58ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c 59ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) 60ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c 61ZSTDDECOMP_O = $(ZSTDDIR)/decompress/zstd_decompress.o 62 63ZSTD_LEGACY_SUPPORT ?= 5 64ZSTDLEGACY_FILES := 65ifneq ($(ZSTD_LEGACY_SUPPORT), 0) 66ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0) 67 ZSTDLEGACY_FILES += $(shell ls $(ZSTDDIR)/legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') 68endif 69 CPPFLAGS += -I$(ZSTDDIR)/legacy 70else 71endif 72 73# Sort files in alphabetical order for reproducible builds 74ZSTDLIB_FILES := $(sort $(wildcard $(ZSTD_FILES)) $(wildcard $(ZSTDLEGACY_FILES)) $(wildcard $(ZDICT_FILES))) 75 76# Define *.exe as extension for Windows systems 77ifneq (,$(filter Windows%,$(OS))) 78EXT =.exe 79RES64_FILE = windres/zstd64.res 80RES32_FILE = windres/zstd32.res 81ifneq (,$(filter x86_64%,$(shell $(CC) -dumpmachine))) 82 RES_FILE = $(RES64_FILE) 83else 84 RES_FILE = $(RES32_FILE) 85endif 86else 87EXT = 88endif 89 90VOID = /dev/null 91 92# thread detection 93NO_THREAD_MSG := ==> no threads, building without multithreading support 94HAVE_PTHREAD := $(shell printf '\#include <pthread.h>\nint main(void) { return 0; }' | $(CC) $(FLAGS) -o have_pthread$(EXT) -x c - -pthread 2> $(VOID) && rm have_pthread$(EXT) && echo 1 || echo 0) 95HAVE_THREAD := $(shell [ "$(HAVE_PTHREAD)" -eq "1" -o -n "$(filter Windows%,$(OS))" ] && echo 1 || echo 0) 96ifeq ($(HAVE_THREAD), 1) 97THREAD_MSG := ==> building with threading support 98THREAD_CPP := -DZSTD_MULTITHREAD 99THREAD_LD := -pthread 100else 101THREAD_MSG := $(NO_THREAD_MSG) 102endif 103 104# zlib detection 105NO_ZLIB_MSG := ==> no zlib, building zstd without .gz support 106HAVE_ZLIB := $(shell printf '\#include <zlib.h>\nint main(void) { return 0; }' | $(CC) $(FLAGS) -o have_zlib$(EXT) -x c - -lz 2> $(VOID) && rm have_zlib$(EXT) && echo 1 || echo 0) 107ifeq ($(HAVE_ZLIB), 1) 108ZLIB_MSG := ==> building zstd with .gz compression support 109ZLIBCPP = -DZSTD_GZCOMPRESS -DZSTD_GZDECOMPRESS 110ZLIBLD = -lz 111else 112ZLIB_MSG := $(NO_ZLIB_MSG) 113endif 114 115# lzma detection 116NO_LZMA_MSG := ==> no liblzma, building zstd without .xz/.lzma support 117HAVE_LZMA := $(shell printf '\#include <lzma.h>\nint main(void) { return 0; }' | $(CC) $(FLAGS) -o have_lzma$(EXT) -x c - -llzma 2> $(VOID) && rm have_lzma$(EXT) && echo 1 || echo 0) 118ifeq ($(HAVE_LZMA), 1) 119LZMA_MSG := ==> building zstd with .xz/.lzma compression support 120LZMACPP = -DZSTD_LZMACOMPRESS -DZSTD_LZMADECOMPRESS 121LZMALD = -llzma 122else 123LZMA_MSG := $(NO_LZMA_MSG) 124endif 125 126# lz4 detection 127NO_LZ4_MSG := ==> no liblz4, building zstd without .lz4 support 128HAVE_LZ4 := $(shell printf '\#include <lz4frame.h>\n\#include <lz4.h>\nint main(void) { return 0; }' | $(CC) $(FLAGS) -o have_lz4$(EXT) -x c - -llz4 2> $(VOID) && rm have_lz4$(EXT) && echo 1 || echo 0) 129ifeq ($(HAVE_LZ4), 1) 130LZ4_MSG := ==> building zstd with .lz4 compression support 131LZ4CPP = -DZSTD_LZ4COMPRESS -DZSTD_LZ4DECOMPRESS 132LZ4LD = -llz4 133else 134LZ4_MSG := $(NO_LZ4_MSG) 135endif 136 137# explicit backtrace enable/disable for Linux & Darwin 138ifeq ($(BACKTRACE), 0) 139DEBUGFLAGS += -DBACKTRACE_ENABLE=0 140endif 141ifeq (,$(filter Windows%, $(OS))) 142ifeq ($(BACKTRACE), 1) 143DEBUGFLAGS += -DBACKTRACE_ENABLE=1 144DEBUGFLAGS_LD += -rdynamic 145endif 146endif 147 148 149.PHONY: default 150default: zstd-release 151 152.PHONY: all 153all: zstd 154 155.PHONY: allVariants 156allVariants: zstd zstd-compress zstd-decompress zstd-small zstd-nolegacy 157 158$(ZSTDDECOMP_O): CFLAGS += $(ALIGN_LOOP) 159 160zstd : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP) $(LZMACPP) $(LZ4CPP) 161zstd : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD) 162zstd : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) 163zstd : $(ZSTDLIB_FILES) zstdcli.o fileio.o bench.o datagen.o dibio.o 164 @echo "$(THREAD_MSG)" 165 @echo "$(ZLIB_MSG)" 166 @echo "$(LZMA_MSG)" 167 @echo "$(LZ4_MSG)" 168ifneq (,$(filter Windows%,$(OS))) 169 windres/generate_res.bat 170endif 171 $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS) 172 173.PHONY: zstd-release 174zstd-release: DEBUGFLAGS := -DBACKTRACE_ENABLE=0 175zstd-release: DEBUGFLAGS_LD := 176zstd-release: zstd 177 178zstd32 : CPPFLAGS += $(THREAD_CPP) 179zstd32 : LDFLAGS += $(THREAD_LD) 180zstd32 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) 181zstd32 : $(ZSTDLIB_FILES) zstdcli.c fileio.c bench.c datagen.c dibio.c 182ifneq (,$(filter Windows%,$(OS))) 183 windres/generate_res.bat 184endif 185 $(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT) 186 187zstd-nolegacy : $(ZSTD_FILES) $(ZDICT_FILES) zstdcli.o fileio.c bench.o datagen.o dibio.o 188 $(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS) 189 190zstd-nomt : THREAD_CPP := 191zstd-nomt : THREAD_LD := 192zstd-nomt : THREAD_MSG := - multi-threading disabled 193zstd-nomt : zstd 194 195zstd-nogz : ZLIBCPP := 196zstd-nogz : ZLIBLD := 197zstd-nogz : ZLIB_MSG := - gzip support is disabled 198zstd-nogz : zstd 199 200zstd-noxz : LZMACPP := 201zstd-noxz : LZMALD := 202zstd-noxz : LZMA_MSG := - xz/lzma support is disabled 203zstd-noxz : zstd 204 205 206zstd-pgo : MOREFLAGS = -fprofile-generate 207zstd-pgo : clean zstd 208 ./zstd -b19i1 $(PROFILE_WITH) 209 ./zstd -b16i1 $(PROFILE_WITH) 210 ./zstd -b9i2 $(PROFILE_WITH) 211 ./zstd -b $(PROFILE_WITH) 212 ./zstd -b7i2 $(PROFILE_WITH) 213 ./zstd -b5 $(PROFILE_WITH) 214 $(RM) zstd 215 $(RM) $(ZSTDDECOMP_O) 216 $(MAKE) zstd MOREFLAGS=-fprofile-use 217 218# minimal target, with only zstd compression and decompression. no bench. no legacy. 219zstd-small: CFLAGS = -Os -s 220zstd-frugal zstd-small: $(ZSTD_FILES) zstdcli.c fileio.c 221 $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o $@$(EXT) 222 223zstd-decompress: $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) zstdcli.c fileio.c 224 $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS $^ -o $@$(EXT) 225 226zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c 227 $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT) 228 229zstdmt: zstd 230 ln -sf zstd zstdmt 231 232.PHONY: generate_res 233generate_res: 234 windres/generate_res.bat 235 236.PHONY: clean 237clean: 238 $(MAKE) -C $(ZSTDDIR) clean 239 @$(RM) $(ZSTDDIR)/decompress/*.o $(ZSTDDIR)/decompress/zstd_decompress.gcda 240 @$(RM) core *.o tmp* result* *.gcda dictionary *.zst \ 241 zstd$(EXT) zstd32$(EXT) zstd-compress$(EXT) zstd-decompress$(EXT) \ 242 zstd-small$(EXT) zstd-frugal$(EXT) zstd-nolegacy$(EXT) zstd4$(EXT) \ 243 *.gcda default.profraw have_zlib$(EXT) 244 @echo Cleaning completed 245 246MD2ROFF = ronn 247MD2ROFF_FLAGS = --roff --warnings --manual="User Commands" --organization="zstd $(ZSTD_VERSION)" 248 249zstd.1: zstd.1.md ../lib/zstd.h 250 cat $< | $(MD2ROFF) $(MD2ROFF_FLAGS) | sed -n '/^\.\\\".*/!p' > $@ 251 252zstdgrep.1: zstdgrep.1.md ../lib/zstd.h 253 cat $< | $(MD2ROFF) $(MD2ROFF_FLAGS) | sed -n '/^\.\\\".*/!p' > $@ 254 255zstdless.1: zstdless.1.md ../lib/zstd.h 256 cat $< | $(MD2ROFF) $(MD2ROFF_FLAGS) | sed -n '/^\.\\\".*/!p' > $@ 257 258.PHONY: man 259man: zstd.1 zstdgrep.1 zstdless.1 260 261.PHONY: clean-man 262clean-man: 263 rm zstd.1 264 rm zstdgrep.1 265 rm zstdless.1 266 267.PHONY: preview-man 268preview-man: clean-man man 269 man ./zstd.1 270 man ./zstdgrep.1 271 man ./zstdless.1 272 273#----------------------------------------------------------------------------- 274# make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets 275#----------------------------------------------------------------------------- 276ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku)) 277 278EGREP = egrep --color=never 279 280# Print a two column output of targets and their description. To add a target description, put a 281# comment in the Makefile with the format "## <TARGET>: <DESCRIPTION>". For example: 282# 283## list: Print all targets and their descriptions (if provided) 284.PHONY: list 285list: 286 @TARGETS=$$($(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null \ 287 | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \ 288 | $(EGREP) -v -e '^[^[:alnum:]]' | sort); \ 289 { \ 290 printf "Target Name\tDescription\n"; \ 291 printf "%0.s-" {1..16}; printf "\t"; printf "%0.s-" {1..40}; printf "\n"; \ 292 for target in $$TARGETS; do \ 293 line=$$($(EGREP) "^##[[:space:]]+$$target:" $(lastword $(MAKEFILE_LIST))); \ 294 description=$$(echo $$line | awk '{i=index($$0,":"); print substr($$0,i+1)}' | xargs); \ 295 printf "$$target\t$$description\n"; \ 296 done \ 297 } | column -t -s $$'\t' 298 299 300DESTDIR ?= 301# directory variables : GNU conventions prefer lowercase 302# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html 303# support both lower and uppercase (BSD), use uppercase in script 304prefix ?= /usr/local 305PREFIX ?= $(prefix) 306exec_prefix ?= $(PREFIX) 307bindir ?= $(exec_prefix)/bin 308BINDIR ?= $(bindir) 309datarootdir ?= $(PREFIX)/share 310mandir ?= $(datarootdir)/man 311man1dir ?= $(mandir)/man1 312 313ifneq (,$(filter $(shell uname),OpenBSD FreeBSD NetBSD DragonFly SunOS)) 314MANDIR ?= $(PREFIX)/man 315MAN1DIR ?= $(MANDIR)/man1 316else 317MAN1DIR ?= $(man1dir) 318endif 319 320ifneq (,$(filter $(shell uname),SunOS)) 321INSTALL ?= ginstall 322else 323INSTALL ?= install 324endif 325 326INSTALL_PROGRAM ?= $(INSTALL) 327INSTALL_SCRIPT ?= $(INSTALL_PROGRAM) 328INSTALL_DATA ?= $(INSTALL) -m 644 329INSTALL_MAN ?= $(INSTALL_DATA) 330 331.PHONY: install 332install: zstd 333 @echo Installing binaries 334 @$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MAN1DIR)/ 335 @$(INSTALL_PROGRAM) zstd $(DESTDIR)$(BINDIR)/zstd 336 @ln -sf zstd $(DESTDIR)$(BINDIR)/zstdcat 337 @ln -sf zstd $(DESTDIR)$(BINDIR)/unzstd 338 @ln -sf zstd $(DESTDIR)$(BINDIR)/zstdmt 339 @$(INSTALL_SCRIPT) zstdless $(DESTDIR)$(BINDIR)/zstdless 340 @$(INSTALL_SCRIPT) zstdgrep $(DESTDIR)$(BINDIR)/zstdgrep 341 @echo Installing man pages 342 @$(INSTALL_MAN) zstd.1 $(DESTDIR)$(MAN1DIR)/zstd.1 343 @ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/zstdcat.1 344 @ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/unzstd.1 345 @$(INSTALL_MAN) zstdgrep.1 $(DESTDIR)$(MAN1DIR)/zstdgrep.1 346 @$(INSTALL_MAN) zstdless.1 $(DESTDIR)$(MAN1DIR)/zstdless.1 347 @echo zstd installation completed 348 349.PHONY: uninstall 350uninstall: 351 @$(RM) $(DESTDIR)$(BINDIR)/zstdgrep 352 @$(RM) $(DESTDIR)$(BINDIR)/zstdless 353 @$(RM) $(DESTDIR)$(BINDIR)/zstdcat 354 @$(RM) $(DESTDIR)$(BINDIR)/unzstd 355 @$(RM) $(DESTDIR)$(BINDIR)/zstd 356 @$(RM) $(DESTDIR)$(MAN1DIR)/zstdless.1 357 @$(RM) $(DESTDIR)$(MAN1DIR)/zstdgrep.1 358 @$(RM) $(DESTDIR)$(MAN1DIR)/zstdcat.1 359 @$(RM) $(DESTDIR)$(MAN1DIR)/unzstd.1 360 @$(RM) $(DESTDIR)$(MAN1DIR)/zstd.1 361 @echo zstd programs successfully uninstalled 362 363endif 364