1# ################################################################
2# Copyright (c) 2015-2020, 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
11Q = $(if $(filter 1,$(V) $(VERBOSE)),,@)
12
13# When cross-compiling from linux to windows, you might
14# need to specify this as "Windows." Fedora build fails
15# without it.
16#
17# Note: mingw-w64 build from linux to windows does not
18# fail on other tested distros (ubuntu, debian) even
19# without manually specifying the TARGET_SYSTEM.
20TARGET_SYSTEM ?= $(OS)
21
22# Version numbers
23LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h`
24LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h`
25LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h`
26LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT)
27LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
28LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
29LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
30LIBVER := $(shell echo $(LIBVER_SCRIPT))
31VERSION?= $(LIBVER)
32CCVER := $(shell $(CC) --version)
33
34CPPFLAGS+= -DXXH_NAMESPACE=ZSTD_
35ifeq ($(TARGET_SYSTEM),Windows_NT)   # MinGW assumed
36CPPFLAGS   += -D__USE_MINGW_ANSI_STDIO   # compatibility with %zu formatting
37endif
38DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
39            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
40            -Wstrict-prototypes -Wundef -Wpointer-arith \
41            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
42            -Wredundant-decls -Wmissing-prototypes -Wc++-compat
43CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)
44FLAGS    = $(CPPFLAGS) $(CFLAGS)
45
46HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0)
47GREP_OPTIONS ?=
48ifeq ($HAVE_COLORNEVER, 1)
49GREP_OPTIONS += --color=never
50endif
51GREP = grep $(GREP_OPTIONS)
52
53ZSTDCOMMON_FILES := $(sort $(wildcard common/*.c))
54ZSTDCOMP_FILES := $(sort $(wildcard compress/*.c))
55ZSTDDECOMP_FILES := $(sort $(wildcard decompress/*.c))
56ZDICT_FILES := $(sort $(wildcard dictBuilder/*.c))
57ZDEPR_FILES := $(sort $(wildcard deprecated/*.c))
58ZSTD_FILES := $(ZSTDCOMMON_FILES)
59
60ifeq ($(findstring GCC,$(CCVER)),GCC)
61decompress/zstd_decompress_block.o :	CFLAGS+=-fno-tree-vectorize
62endif
63
64# This is a helper variable that configures a bunch of other variables to new,
65# space-optimized defaults.
66ZSTD_LIB_MINIFY ?= 0
67ifneq ($(ZSTD_LIB_MINIFY), 0)
68	HAVE_CC_OZ ?= $(shell echo "" | $(CC) -Oz -x c -c - -o /dev/null 2> /dev/null && echo 1 || echo 0)
69	ZSTD_LEGACY_SUPPORT ?= 0
70	ZSTD_LIB_DEPRECATED ?= 0
71	HUF_FORCE_DECOMPRESS_X1 ?= 1
72	ZSTD_FORCE_DECOMPRESS_SHORT ?= 1
73	ZSTD_NO_INLINE ?= 1
74	ZSTD_STRIP_ERROR_STRINGS ?= 1
75	ifneq ($(HAVE_CC_OZ), 0)
76		# Some compilers (clang) support an even more space-optimized setting.
77		CFLAGS += -Oz
78	else
79		CFLAGS += -Os
80	endif
81	CFLAGS += -fno-stack-protector -fomit-frame-pointer -fno-ident \
82	          -DDYNAMIC_BMI2=0 -DNDEBUG
83else
84	CFLAGS += -O3
85endif
86
87# Modules
88ZSTD_LIB_COMPRESSION ?= 1
89ZSTD_LIB_DECOMPRESSION ?= 1
90ZSTD_LIB_DICTBUILDER ?= 1
91ZSTD_LIB_DEPRECATED ?= 1
92
93# Legacy support
94ZSTD_LEGACY_SUPPORT ?= 5
95ZSTD_LEGACY_MULTITHREADED_API ?= 0
96
97# Build size optimizations
98HUF_FORCE_DECOMPRESS_X1 ?= 0
99HUF_FORCE_DECOMPRESS_X2 ?= 0
100ZSTD_FORCE_DECOMPRESS_SHORT ?= 0
101ZSTD_FORCE_DECOMPRESS_LONG ?= 0
102ZSTD_NO_INLINE ?= 0
103ZSTD_STRIP_ERROR_STRINGS ?= 0
104
105ifeq ($(ZSTD_LIB_COMPRESSION), 0)
106	ZSTD_LIB_DICTBUILDER = 0
107	ZSTD_LIB_DEPRECATED = 0
108endif
109
110ifeq ($(ZSTD_LIB_DECOMPRESSION), 0)
111	ZSTD_LEGACY_SUPPORT = 0
112	ZSTD_LIB_DEPRECATED = 0
113endif
114
115ifneq ($(ZSTD_LIB_COMPRESSION), 0)
116	ZSTD_FILES += $(ZSTDCOMP_FILES)
117endif
118
119ifneq ($(ZSTD_LIB_DECOMPRESSION), 0)
120	ZSTD_FILES += $(ZSTDDECOMP_FILES)
121endif
122
123ifneq ($(ZSTD_LIB_DEPRECATED), 0)
124	ZSTD_FILES += $(ZDEPR_FILES)
125endif
126
127ifneq ($(ZSTD_LIB_DICTBUILDER), 0)
128	ZSTD_FILES += $(ZDICT_FILES)
129endif
130
131ifneq ($(HUF_FORCE_DECOMPRESS_X1), 0)
132	CFLAGS += -DHUF_FORCE_DECOMPRESS_X1
133endif
134
135ifneq ($(HUF_FORCE_DECOMPRESS_X2), 0)
136	CFLAGS += -DHUF_FORCE_DECOMPRESS_X2
137endif
138
139ifneq ($(ZSTD_FORCE_DECOMPRESS_SHORT), 0)
140	CFLAGS += -DZSTD_FORCE_DECOMPRESS_SHORT
141endif
142
143ifneq ($(ZSTD_FORCE_DECOMPRESS_LONG), 0)
144	CFLAGS += -DZSTD_FORCE_DECOMPRESS_LONG
145endif
146
147ifneq ($(ZSTD_NO_INLINE), 0)
148	CFLAGS += -DZSTD_NO_INLINE
149endif
150
151ifneq ($(ZSTD_STRIP_ERROR_STRINGS), 0)
152	CFLAGS += -DZSTD_STRIP_ERROR_STRINGS
153endif
154
155ifneq ($(ZSTD_LEGACY_MULTITHREADED_API), 0)
156	CFLAGS += -DZSTD_LEGACY_MULTITHREADED_API
157endif
158
159ifneq ($(ZSTD_LEGACY_SUPPORT), 0)
160ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0)
161	ZSTD_FILES += $(shell ls legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
162endif
163endif
164CPPFLAGS  += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
165
166ZSTD_OBJ   := $(patsubst %.c,%.o,$(ZSTD_FILES))
167
168# macOS linker doesn't support -soname, and use different extension
169# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
170ifeq ($(shell uname), Darwin)
171	SHARED_EXT = dylib
172	SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
173	SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT)
174	SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
175else
176	SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR)
177	SHARED_EXT = so
178	SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR)
179	SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
180endif
181
182
183.PHONY: default lib-all all clean install uninstall
184
185default: lib-release
186
187# alias
188lib-all: all
189
190all: lib
191
192libzstd.a: ARFLAGS = rcs
193libzstd.a: $(ZSTD_OBJ)
194	@echo compiling static library
195	$(Q)$(AR) $(ARFLAGS) $@ $^
196
197ifneq (,$(filter Windows%,$(TARGET_SYSTEM)))
198
199LIBZSTD = dll\libzstd.dll
200$(LIBZSTD): $(ZSTD_FILES)
201	@echo compiling dynamic library $(LIBVER)
202	$(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -Wl,--out-implib,dll\libzstd.dll.a -shared $^ -o $@
203
204else
205
206LIBZSTD = libzstd.$(SHARED_EXT_VER)
207$(LIBZSTD): LDFLAGS += -shared -fPIC -fvisibility=hidden
208$(LIBZSTD): $(ZSTD_FILES)
209	@echo compiling dynamic library $(LIBVER)
210	$(Q)$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
211	@echo creating versioned links
212	$(Q)ln -sf $@ libzstd.$(SHARED_EXT_MAJOR)
213	$(Q)ln -sf $@ libzstd.$(SHARED_EXT)
214
215endif
216
217.PHONY: libzstd
218libzstd : $(LIBZSTD)
219
220.PHONY: lib
221lib : libzstd.a libzstd
222
223.PHONY: lib-mt
224%-mt : CPPFLAGS += -DZSTD_MULTITHREAD
225%-mt : LDFLAGS  += -pthread
226%-mt : %
227	@echo multi-threading build completed
228
229.PHONY: lib-release
230%-release : DEBUGFLAGS :=
231%-release : %
232	@echo release build completed
233
234
235# Special case : building library in single-thread mode _and_ without zstdmt_compress.c
236ZSTDMT_FILES = compress/zstdmt_compress.c
237ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(ZSTD_FILES))
238libzstd-nomt: LDFLAGS += -shared -fPIC -fvisibility=hidden
239libzstd-nomt: $(ZSTD_NOMT_FILES)
240	@echo compiling single-thread dynamic library $(LIBVER)
241	@echo files : $(ZSTD_NOMT_FILES)
242	$(Q)$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
243
244clean:
245	$(Q)$(RM) -r *.dSYM   # macOS-specific
246	$(Q)$(RM) core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc
247	$(Q)$(RM) dll/libzstd.dll dll/libzstd.lib libzstd-nomt*
248	$(Q)$(RM) common/*.o compress/*.o decompress/*.o dictBuilder/*.o legacy/*.o deprecated/*.o
249	@echo Cleaning library completed
250
251#-----------------------------------------------------------------------------
252# make install is validated only for below listed environments
253#-----------------------------------------------------------------------------
254ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku))
255
256all: libzstd.pc
257
258DESTDIR     ?=
259# directory variables : GNU conventions prefer lowercase
260# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html
261# support both lower and uppercase (BSD), use uppercase in script
262prefix      ?= /usr/local
263PREFIX      ?= $(prefix)
264exec_prefix ?= $(PREFIX)
265EXEC_PREFIX ?= $(exec_prefix)
266libdir      ?= $(EXEC_PREFIX)/lib
267LIBDIR      ?= $(libdir)
268includedir  ?= $(PREFIX)/include
269INCLUDEDIR  ?= $(includedir)
270
271PCLIBDIR ?= $(shell echo "$(LIBDIR)" | sed -n -E -e "s@^$(EXEC_PREFIX)(/|$$)@@p")
272PCINCDIR ?= $(shell echo "$(INCLUDEDIR)" | sed -n -E -e "s@^$(PREFIX)(/|$$)@@p")
273
274ifeq (,$(PCLIBDIR))
275# Additional prefix check is required, since the empty string is technically a
276# valid PCLIBDIR
277ifeq (,$(shell echo "$(LIBDIR)" | sed -n -E -e "\\@^$(EXEC_PREFIX)(/|$$)@ p"))
278$(error configured libdir ($(LIBDIR)) is outside of prefix ($(PREFIX)), can't generate pkg-config file)
279endif
280endif
281
282ifeq (,$(PCINCDIR))
283# Additional prefix check is required, since the empty string is technically a
284# valid PCINCDIR
285ifeq (,$(shell echo "$(INCLUDEDIR)" | sed -n -E -e "\\@^$(PREFIX)(/|$$)@ p"))
286$(error configured includedir ($(INCLUDEDIR)) is outside of exec_prefix ($(EXEC_PREFIX)), can't generate pkg-config file)
287endif
288endif
289
290ifneq (,$(filter $(shell uname),FreeBSD NetBSD DragonFly))
291PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig
292else
293PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
294endif
295
296ifneq (,$(filter $(shell uname),SunOS))
297INSTALL ?= ginstall
298else
299INSTALL ?= install
300endif
301
302INSTALL_PROGRAM ?= $(INSTALL)
303INSTALL_DATA    ?= $(INSTALL) -m 644
304
305
306libzstd.pc:
307libzstd.pc: libzstd.pc.in
308	@echo creating pkgconfig
309	$(Q)@sed -E -e 's|@PREFIX@|$(PREFIX)|' \
310          -e 's|@LIBDIR@|$(PCLIBDIR)|' \
311          -e 's|@INCLUDEDIR@|$(PCINCDIR)|' \
312          -e 's|@VERSION@|$(VERSION)|' \
313          $< >$@
314
315install: install-pc install-static install-shared install-includes
316	@echo zstd static and shared library installed
317
318install-pc: libzstd.pc
319	$(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/
320	$(Q)$(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/
321
322install-static: libzstd.a
323	@echo Installing static library
324	$(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/
325	$(Q)$(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR)
326
327install-shared: libzstd
328	@echo Installing shared library
329	$(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/
330	$(Q)$(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR)
331	$(Q)ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
332	$(Q)ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
333
334install-includes:
335	@echo Installing includes
336	$(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/
337	$(Q)$(INSTALL_DATA) zstd.h $(DESTDIR)$(INCLUDEDIR)
338	$(Q)$(INSTALL_DATA) common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)
339	$(Q)$(INSTALL_DATA) deprecated/zbuff.h $(DESTDIR)$(INCLUDEDIR)     # prototypes generate deprecation warnings
340	$(Q)$(INSTALL_DATA) dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)
341
342uninstall:
343	$(Q)$(RM) $(DESTDIR)$(LIBDIR)/libzstd.a
344	$(Q)$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
345	$(Q)$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
346	$(Q)$(RM) $(DESTDIR)$(LIBDIR)/$(LIBZSTD)
347	$(Q)$(RM) $(DESTDIR)$(PKGCONFIGDIR)/libzstd.pc
348	$(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/zstd.h
349	$(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h
350	$(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/zbuff.h   # Deprecated streaming functions
351	$(Q)$(RM) $(DESTDIR)$(INCLUDEDIR)/zdict.h
352	@echo zstd libraries successfully uninstalled
353
354endif
355