1 # ################################################################
2 # Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
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 # zstd : Command Line Utility, supporting gzip-like arguments
11 # zstd32 : Same as zstd, but forced to compile in 32-bits mode
12 # zstd_nolegacy : zstd without support of decompression of legacy versions
13 # zstd-small : minimal zstd without dictionary builder and benchmark
14 # zstd-compress : compressor-only version of zstd
15 # zstd-decompress : decompressor-only version of zstd
16 # ##########################################################################
21 LIBVER_SRC
:= $(ZSTDDIR
)/zstd.h
22 LIBVER_MAJOR_SCRIPT
:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
23 LIBVER_MINOR_SCRIPT
:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
24 LIBVER_PATCH_SCRIPT
:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)`
25 LIBVER_SCRIPT
:= $(LIBVER_MAJOR_SCRIPT
).
$(LIBVER_MINOR_SCRIPT
).
$(LIBVER_PATCH_SCRIPT
)
26 LIBVER_MAJOR
:= $(shell echo
$(LIBVER_MAJOR_SCRIPT
))
27 LIBVER_MINOR
:= $(shell echo
$(LIBVER_MINOR_SCRIPT
))
28 LIBVER_PATCH
:= $(shell echo
$(LIBVER_PATCH_SCRIPT
))
29 LIBVER
:= $(shell echo
$(LIBVER_SCRIPT
))
31 ZSTD_VERSION
= $(LIBVER
)
33 HAVE_COLORNEVER
= $(shell echo a | grep
--color
=never a
> /dev
/null
2> /dev
/null
&& echo
1 || echo
0)
35 ifeq ($HAVE_COLORNEVER, 1)
36 GREP_OPTIONS
+= --color
=never
38 GREP
= grep
$(GREP_OPTIONS
)
40 ifeq ($(shell $(CC
) -v
2>&1 |
$(GREP
) -c
"gcc version "), 1)
41 ALIGN_LOOP
= -falign-loops
=32
46 CPPFLAGS
+= -DXXH_NAMESPACE
=ZSTD_
47 ifeq ($(OS
),Windows_NT
) # MinGW assumed
48 CPPFLAGS
+= -D__USE_MINGW_ANSI_STDIO
# compatibility with %zu formatting
51 DEBUGFLAGS
+=-Wall
-Wextra
-Wcast-qual
-Wcast-align
-Wshadow \
52 -Wstrict-aliasing
=1 -Wswitch-enum
-Wdeclaration-after-statement \
53 -Wstrict-prototypes
-Wundef
-Wpointer-arith \
54 -Wvla
-Wformat
=2 -Winit-self
-Wfloat-equal
-Wwrite-strings \
55 -Wredundant-decls
-Wmissing-prototypes
-Wc
++-compat
56 CFLAGS
+= $(DEBUGFLAGS
) $(MOREFLAGS
)
57 FLAGS
= $(CPPFLAGS
) $(CFLAGS
) $(LDFLAGS
)
60 ZSTDCOMMON_FILES
:= $(ZSTDDIR
)/common
/*.c
61 ZSTDCOMP_FILES
:= $(ZSTDDIR
)/compress
/*.c
62 ZSTDDECOMP_FILES
:= $(ZSTDDIR
)/decompress
/*.c
63 ZSTD_FILES
:= $(ZSTDDECOMP_FILES
) $(ZSTDCOMMON_FILES
) $(ZSTDCOMP_FILES
)
64 ZDICT_FILES
:= $(ZSTDDIR
)/dictBuilder
/*.c
65 ZSTDDECOMP_O
= $(ZSTDDIR
)/decompress
/zstd_decompress.o
67 ZSTD_LEGACY_SUPPORT ?
= 5
69 ifneq ($(ZSTD_LEGACY_SUPPORT
), 0)
70 ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT
) -lt
8; echo
$$?
), 0)
71 ZSTDLEGACY_FILES
+= $(shell ls
$(ZSTDDIR
)/legacy
/*.c |
$(GREP
) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
76 # Sort files in alphabetical order for reproducible builds
77 ZSTDLIB_FILES
:= $(sort $(wildcard $(ZSTD_FILES
)) $(wildcard $(ZSTDLEGACY_FILES
)) $(wildcard $(ZDICT_FILES
)))
79 ZSTD_CLI_FILES
:= $(wildcard *.c
)
80 ZSTD_CLI_OBJ
:= $(patsubst %.c
,%.o
,$(ZSTD_CLI_FILES
))
82 # Define *.exe as extension for Windows systems
83 ifneq (,$(filter Windows
%,$(OS
)))
85 RES64_FILE
= windres
/zstd64.res
86 RES32_FILE
= windres
/zstd32.res
87 ifneq (,$(filter x86_64
%,$(shell $(CC
) -dumpmachine
)))
88 RES_FILE
= $(RES64_FILE
)
90 RES_FILE
= $(RES32_FILE
)
98 # Make 4.3 doesn't support '\#' anymore (https://lwn.net/Articles/810071/)
102 NO_THREAD_MSG
:= ==> no threads
, building without multithreading support
103 HAVE_PTHREAD
:= $(shell printf
'$(NUM_SYMBOL)include <pthread.h>\nint main(void) { return 0; }' > have_pthread.c
&& $(CC
) $(FLAGS
) -o have_pthread
$(EXT
) have_pthread.c
-pthread
2> $(VOID
) && rm have_pthread
$(EXT
) && echo
1 || echo
0; rm have_pthread.c
)
104 HAVE_THREAD
:= $(shell [ "$(HAVE_PTHREAD)" -eq
"1" -o
-n
"$(filter Windows%,$(OS))" ] && echo
1 || echo
0)
105 ifeq ($(HAVE_THREAD
), 1)
106 THREAD_MSG
:= ==> building with threading support
107 THREAD_CPP
:= -DZSTD_MULTITHREAD
108 THREAD_LD
:= -pthread
110 THREAD_MSG
:= $(NO_THREAD_MSG
)
114 NO_ZLIB_MSG
:= ==> no zlib
, building zstd without .gz support
115 HAVE_ZLIB
:= $(shell printf
'$(NUM_SYMBOL)include <zlib.h>\nint main(void) { return 0; }' > have_zlib.c
&& $(CC
) $(FLAGS
) -o have_zlib
$(EXT
) have_zlib.c
-lz
2> $(VOID
) && rm have_zlib
$(EXT
) && echo
1 || echo
0; rm have_zlib.c
)
116 ifeq ($(HAVE_ZLIB
), 1)
117 ZLIB_MSG
:= ==> building zstd with .gz compression support
118 ZLIBCPP
= -DZSTD_GZCOMPRESS
-DZSTD_GZDECOMPRESS
121 ZLIB_MSG
:= $(NO_ZLIB_MSG
)
125 NO_LZMA_MSG
:= ==> no liblzma
, building zstd without .xz
/.lzma support
126 HAVE_LZMA
:= $(shell printf
'$(NUM_SYMBOL)include <lzma.h>\nint main(void) { return 0; }' > have_lzma.c
&& $(CC
) $(FLAGS
) -o have_lzma
$(EXT
) have_lzma.c
-llzma
2> $(VOID
) && rm have_lzma
$(EXT
) && echo
1 || echo
0; rm have_lzma.c
)
127 ifeq ($(HAVE_LZMA
), 1)
128 LZMA_MSG
:= ==> building zstd with .xz
/.lzma compression support
129 LZMACPP
= -DZSTD_LZMACOMPRESS
-DZSTD_LZMADECOMPRESS
132 LZMA_MSG
:= $(NO_LZMA_MSG
)
136 NO_LZ4_MSG
:= ==> no liblz4
, building zstd without .lz4 support
137 HAVE_LZ4
:= $(shell printf
'$(NUM_SYMBOL)include <lz4frame.h>\n$(NUM_SYMBOL)include <lz4.h>\nint main(void) { return 0; }' > have_lz4.c
&& $(CC
) $(FLAGS
) -o have_lz4
$(EXT
) have_lz4.c
-llz4
2> $(VOID
) && rm have_lz4
$(EXT
) && echo
1 || echo
0; rm have_lz4.c
)
138 ifeq ($(HAVE_LZ4
), 1)
139 LZ4_MSG
:= ==> building zstd with .lz4 compression support
140 LZ4CPP
= -DZSTD_LZ4COMPRESS
-DZSTD_LZ4DECOMPRESS
143 LZ4_MSG
:= $(NO_LZ4_MSG
)
146 # explicit backtrace enable/disable for Linux & Darwin
147 ifeq ($(BACKTRACE
), 0)
148 DEBUGFLAGS
+= -DBACKTRACE_ENABLE
=0
150 ifeq (,$(filter Windows
%, $(OS
)))
151 ifeq ($(BACKTRACE
), 1)
152 DEBUGFLAGS
+= -DBACKTRACE_ENABLE
=1
153 DEBUGFLAGS_LD
+= -rdynamic
159 default
: zstd-release
165 allVariants
: zstd zstd-compress zstd-decompress zstd-small zstd-nolegacy zstd-dictBuilder
167 $(ZSTDDECOMP_O
): CFLAGS
+= $(ALIGN_LOOP
)
169 zstd
: CPPFLAGS
+= $(THREAD_CPP
) $(ZLIBCPP
) $(LZMACPP
) $(LZ4CPP
)
170 zstd
: LDFLAGS
+= $(THREAD_LD
) $(ZLIBLD
) $(LZMALD
) $(LZ4LD
) $(DEBUGFLAGS_LD
)
171 zstd
: CPPFLAGS
+= -DZSTD_LEGACY_SUPPORT
=$(ZSTD_LEGACY_SUPPORT
)
172 ifneq (,$(filter Windows
%,$(OS
)))
175 zstd
: $(ZSTDLIB_FILES
) $(ZSTD_CLI_OBJ
)
176 @echo
"$(THREAD_MSG)"
180 $(CC
) $(FLAGS
) $^
-o
$@
$(EXT
) $(LDFLAGS
)
183 zstd-release
: DEBUGFLAGS
:= -DBACKTRACE_ENABLE
=0
184 zstd-release
: DEBUGFLAGS_LD
:=
187 zstd32
: CPPFLAGS
+= $(THREAD_CPP
)
188 zstd32
: LDFLAGS
+= $(THREAD_LD
)
189 zstd32
: CPPFLAGS
+= -DZSTD_LEGACY_SUPPORT
=$(ZSTD_LEGACY_SUPPORT
)
190 ifneq (,$(filter Windows
%,$(OS
)))
191 zstd32
: $(RES32_FILE
)
193 zstd32
: $(ZSTDLIB_FILES
) $(ZSTD_CLI_FILES
)
194 $(CC
) -m32
$(FLAGS
) $^
-o
$@
$(EXT
)
196 ## zstd-nolegacy: same scope as zstd, with just support of legacy formats removed
197 zstd-nolegacy
: LDFLAGS
+= $(THREAD_LD
) $(ZLIBLD
) $(LZMALD
) $(LZ4LD
) $(DEBUGFLAGS_LD
)
198 zstd-nolegacy
: $(ZSTD_FILES
) $(ZDICT_FILES
) $(ZSTD_CLI_OBJ
)
199 $(CC
) $(FLAGS
) $^
-o
$@
$(EXT
) $(LDFLAGS
)
201 zstd-nomt
: THREAD_CPP
:=
202 zstd-nomt
: THREAD_LD
:=
203 zstd-nomt
: THREAD_MSG
:= - multi-threading disabled
206 zstd-nogz
: ZLIBCPP
:=
207 zstd-nogz
: ZLIBLD
:=
208 zstd-nogz
: ZLIB_MSG
:= - gzip support is disabled
211 zstd-noxz
: LZMACPP
:=
212 zstd-noxz
: LZMALD
:=
213 zstd-noxz
: LZMA_MSG
:= - xz
/lzma support is disabled
216 ## zstd-dll: zstd executable linked to dynamic library libzstd (must already exist)
217 # note : the following target doesn't link
218 # because zstd uses non-public symbols from libzstd
219 # such as XXH64 (for benchmark),
220 # ZDICT_trainFromBuffer_unsafe_legacy (for dictionary builder)
221 # and ZSTD_cycleLog (likely for --patch-from).
222 # It's unclear at this stage if this is a scenario that must be supported
224 zstd-dll
: LDFLAGS
+= -L
$(ZSTDDIR
) -lzstd
225 zstd-dll
: ZSTDLIB_FILES
=
226 zstd-dll
: $(ZSTD_CLI_OBJ
)
227 $(CC
) $(FLAGS
) $^
-o
$@
$(EXT
) $(LDFLAGS
)
230 ## zstd-pgo: zstd executable optimized with pgo. `gcc` only.
233 $(MAKE
) zstd MOREFLAGS
=-fprofile-generate
234 .
/zstd
-b19i1
$(PROFILE_WITH
)
235 .
/zstd
-b16i1
$(PROFILE_WITH
)
236 .
/zstd
-b9i2
$(PROFILE_WITH
)
237 .
/zstd
-b
$(PROFILE_WITH
)
238 .
/zstd
-b7i2
$(PROFILE_WITH
)
239 .
/zstd
-b5
$(PROFILE_WITH
)
240 $(RM
) zstd
*.o
$(ZSTDDECOMP_O
) $(ZSTDDIR
)/compress
/*.o
241 case
$(CC
) in
*clang
*) if
! [ -e default.profdata
]; then llvm-profdata merge
-output
=default.profdata default
*.profraw
; fi
;; esac
242 $(MAKE
) zstd MOREFLAGS
=-fprofile-use
244 ## zstd-small: minimal target, supporting only zstd compression and decompression. no bench. no legacy. no other format.
245 zstd-small
: CFLAGS
= -Os
-s
246 zstd-frugal zstd-small
: $(ZSTD_FILES
) zstdcli.c util.c timefn.c fileio.c
247 $(CC
) $(FLAGS
) -DZSTD_NOBENCH
-DZSTD_NODICT
$^
-o
$@
$(EXT
)
249 zstd-decompress
: $(ZSTDCOMMON_FILES
) $(ZSTDDECOMP_FILES
) zstdcli.c util.c timefn.c fileio.c
250 $(CC
) $(FLAGS
) -DZSTD_NOBENCH
-DZSTD_NODICT
-DZSTD_NOCOMPRESS
$^
-o
$@
$(EXT
)
252 zstd-compress
: $(ZSTDCOMMON_FILES
) $(ZSTDCOMP_FILES
) zstdcli.c util.c timefn.c fileio.c
253 $(CC
) $(FLAGS
) -DZSTD_NOBENCH
-DZSTD_NODICT
-DZSTD_NODECOMPRESS
$^
-o
$@
$(EXT
)
255 ## zstd-dictBuilder: executable supporting dictionary creation and compression (only)
256 zstd-dictBuilder
: CPPFLAGS
+= -DZSTD_NOBENCH
-DZSTD_NODECOMPRESS
257 zstd-dictBuilder
: $(ZSTDCOMMON_FILES
) $(ZSTDCOMP_FILES
) $(ZDICT_FILES
) zstdcli.c util.c timefn.c fileio.c dibio.c
258 $(CC
) $(FLAGS
) $^
-o
$@
$(EXT
)
264 generate_res
: $(RES64_FILE
) $(RES32_FILE
)
266 ifneq (,$(filter Windows
%,$(OS
)))
268 # http://stackoverflow.com/questions/708238/how-do-i-add-an-icon-to-a-mingw-gcc-compiled-executable
269 $(RES64_FILE
): windres
/zstd.rc
270 $(RC
) -o
$@
-I ..
/lib
-I windres
-i
$< -O coff
-F pe-x86-64
271 $(RES32_FILE
): windres
/zstd.rc
272 $(RC
) -o
$@
-I ..
/lib
-I windres
-i
$< -O coff
-F pe-i386
277 $(MAKE
) -C
$(ZSTDDIR
) clean
278 @
$(RM
) $(ZSTDDIR
)/decompress
/*.o
$(ZSTDDIR
)/decompress
/zstd_decompress.gcda
279 @
$(RM
) core
*.o tmp
* result
* *.gcda dictionary
*.zst \
280 zstd
$(EXT
) zstd32
$(EXT
) zstd-compress
$(EXT
) zstd-decompress
$(EXT
) \
281 zstd-small
$(EXT
) zstd-frugal
$(EXT
) zstd-nolegacy
$(EXT
) zstd4
$(EXT
) \
282 zstd-dictBuilder
$(EXT
) *.gcda default
*.profraw default.profdata have_zlib
$(EXT
)
283 @echo Cleaning completed
286 MD2ROFF_FLAGS
= --roff
--warnings
--manual
="User Commands" --organization
="zstd $(ZSTD_VERSION)"
288 zstd
.1: zstd
.1.md ..
/lib
/zstd.h
289 cat
$< |
$(MD2ROFF
) $(MD2ROFF_FLAGS
) | sed
-n
'/^\.\\\".*/!p' > $@
291 zstdgrep
.1: zstdgrep
.1.md ..
/lib
/zstd.h
292 cat
$< |
$(MD2ROFF
) $(MD2ROFF_FLAGS
) | sed
-n
'/^\.\\\".*/!p' > $@
294 zstdless
.1: zstdless
.1.md ..
/lib
/zstd.h
295 cat
$< |
$(MD2ROFF
) $(MD2ROFF_FLAGS
) | sed
-n
'/^\.\\\".*/!p' > $@
298 man
: zstd
.1 zstdgrep
.1 zstdless
.1
307 preview-man
: clean-man man
312 #-----------------------------------------------------------------------------
313 # make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets
314 #-----------------------------------------------------------------------------
315 ifneq (,$(filter $(shell uname
),Linux Darwin GNU
/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku
))
317 HAVE_COLORNEVER
= $(shell echo a | egrep
--color
=never a
> /dev
/null
2> /dev
/null
&& echo
1 || echo
0)
319 ifeq ($HAVE_COLORNEVER, 1)
320 EGREP_OPTIONS
+= --color
=never
322 EGREP
= egrep
$(EGREP_OPTIONS
)
325 # Print a two column output of targets and their description. To add a target description, put a
326 # comment in the Makefile with the format "## <TARGET>: <DESCRIPTION>". For example:
328 ## list: Print all targets and their descriptions (if provided)
331 @TARGETS
=$$($(MAKE
) -pRrq
-f
$(lastword
$(MAKEFILE_LIST
)) : 2>/dev
/null \
332 |
$(AWK
) -v RS
= -F
: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
333 |
$(EGREP
) -v
-e
'^[^[:alnum:]]' |
sort); \
335 printf
"Target Name\tDescription\n"; \
336 printf
"%0.s-" {1.
.16}; printf
"\t"; printf
"%0.s-" {1.
.40}; printf
"\n"; \
337 for target in
$$TARGETS; do \
338 line
=$$($(EGREP
) "^##[[:space:]]+$$target:" $(lastword
$(MAKEFILE_LIST
))); \
339 description
=$$(echo
$$line |
$(AWK
) '{i=index($$0,":"); print substr($$0,i+1)}' | xargs
); \
340 printf
"$$target\t$$description\n"; \
342 } | column
-t
-s
$$'\t'
346 # directory variables : GNU conventions prefer lowercase
347 # see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html
348 # support both lower and uppercase (BSD), use uppercase in script
351 exec_prefix ?
= $(PREFIX
)
352 bindir ?
= $(exec_prefix)/bin
354 datarootdir ?
= $(PREFIX
)/share
355 mandir ?
= $(datarootdir
)/man
356 man1dir ?
= $(mandir)/man1
358 ifneq (,$(filter $(shell uname
),OpenBSD FreeBSD NetBSD DragonFly SunOS
))
359 MANDIR ?
= $(PREFIX
)/man
360 MAN1DIR ?
= $(MANDIR
)/man1
362 MAN1DIR ?
= $(man1dir)
365 ifneq (,$(filter $(shell uname
),SunOS
))
371 INSTALL_PROGRAM ?
= $(INSTALL
)
372 INSTALL_SCRIPT ?
= $(INSTALL_PROGRAM
)
373 INSTALL_DATA ?
= $(INSTALL
) -m
644
374 INSTALL_MAN ?
= $(INSTALL_DATA
)
378 @echo Installing binaries
379 @
$(INSTALL
) -d
-m
755 $(DESTDIR
)$(BINDIR
)/ $(DESTDIR
)$(MAN1DIR
)/
380 @
$(INSTALL_PROGRAM
) zstd
$(EXT
) $(DESTDIR
)$(BINDIR
)/zstd
$(EXT
)
381 @ln
-sf zstd
$(EXT
) $(DESTDIR
)$(BINDIR
)/zstdcat
$(EXT
)
382 @ln
-sf zstd
$(EXT
) $(DESTDIR
)$(BINDIR
)/unzstd
$(EXT
)
383 @ln
-sf zstd
$(EXT
) $(DESTDIR
)$(BINDIR
)/zstdmt
$(EXT
)
384 @
$(INSTALL_SCRIPT
) zstdless
$(DESTDIR
)$(BINDIR
)/zstdless
385 @
$(INSTALL_SCRIPT
) zstdgrep
$(DESTDIR
)$(BINDIR
)/zstdgrep
386 @echo Installing man pages
387 @
$(INSTALL_MAN
) zstd
.1 $(DESTDIR
)$(MAN1DIR
)/zstd
.1
388 @ln
-sf zstd
.1 $(DESTDIR
)$(MAN1DIR
)/zstdcat
.1
389 @ln
-sf zstd
.1 $(DESTDIR
)$(MAN1DIR
)/unzstd
.1
390 @
$(INSTALL_MAN
) zstdgrep
.1 $(DESTDIR
)$(MAN1DIR
)/zstdgrep
.1
391 @
$(INSTALL_MAN
) zstdless
.1 $(DESTDIR
)$(MAN1DIR
)/zstdless
.1
392 @echo zstd installation completed
396 @
$(RM
) $(DESTDIR
)$(BINDIR
)/zstdgrep
397 @
$(RM
) $(DESTDIR
)$(BINDIR
)/zstdless
398 @
$(RM
) $(DESTDIR
)$(BINDIR
)/zstdcat
399 @
$(RM
) $(DESTDIR
)$(BINDIR
)/unzstd
400 @
$(RM
) $(DESTDIR
)$(BINDIR
)/zstdmt
401 @
$(RM
) $(DESTDIR
)$(BINDIR
)/zstd
402 @
$(RM
) $(DESTDIR
)$(MAN1DIR
)/zstdless
.1
403 @
$(RM
) $(DESTDIR
)$(MAN1DIR
)/zstdgrep
.1
404 @
$(RM
) $(DESTDIR
)$(MAN1DIR
)/zstdcat
.1
405 @
$(RM
) $(DESTDIR
)$(MAN1DIR
)/unzstd
.1
406 @
$(RM
) $(DESTDIR
)$(MAN1DIR
)/zstd
.1
407 @echo zstd programs successfully uninstalled