| 1 | # ################################################################ |
| 2 | # Copyright (c) Meta Platforms, Inc. and affiliates. |
| 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 | |
| 11 | # Modules |
| 12 | ZSTD_LIB_COMPRESSION ?= 1 |
| 13 | ZSTD_LIB_DECOMPRESSION ?= 1 |
| 14 | ZSTD_LIB_DICTBUILDER ?= 1 |
| 15 | ZSTD_LIB_DEPRECATED ?= 0 |
| 16 | |
| 17 | # Input variables for libzstd.mk |
| 18 | ifeq ($(ZSTD_LIB_COMPRESSION), 0) |
| 19 | ZSTD_LIB_DICTBUILDER = 0 |
| 20 | ZSTD_LIB_DEPRECATED = 0 |
| 21 | endif |
| 22 | |
| 23 | ifeq ($(ZSTD_LIB_DECOMPRESSION), 0) |
| 24 | ZSTD_LEGACY_SUPPORT = 0 |
| 25 | ZSTD_LIB_DEPRECATED = 0 |
| 26 | endif |
| 27 | |
| 28 | include libzstd.mk |
| 29 | |
| 30 | ZSTD_FILES := $(ZSTD_COMMON_FILES) $(ZSTD_LEGACY_FILES) |
| 31 | |
| 32 | ifneq ($(ZSTD_LIB_COMPRESSION), 0) |
| 33 | ZSTD_FILES += $(ZSTD_COMPRESS_FILES) |
| 34 | endif |
| 35 | |
| 36 | ifneq ($(ZSTD_LIB_DECOMPRESSION), 0) |
| 37 | ZSTD_FILES += $(ZSTD_DECOMPRESS_FILES) |
| 38 | endif |
| 39 | |
| 40 | ifneq ($(ZSTD_LIB_DEPRECATED), 0) |
| 41 | ZSTD_FILES += $(ZSTD_DEPRECATED_FILES) |
| 42 | endif |
| 43 | |
| 44 | ifneq ($(ZSTD_LIB_DICTBUILDER), 0) |
| 45 | ZSTD_FILES += $(ZSTD_DICTBUILDER_FILES) |
| 46 | endif |
| 47 | |
| 48 | ZSTD_LOCAL_SRC := $(notdir $(ZSTD_FILES)) |
| 49 | ZSTD_LOCAL_OBJ0 := $(ZSTD_LOCAL_SRC:.c=.o) |
| 50 | ZSTD_LOCAL_OBJ := $(ZSTD_LOCAL_OBJ0:.S=.o) |
| 51 | |
| 52 | VERSION := $(ZSTD_VERSION) |
| 53 | |
| 54 | # Note: by default, the static library is built single-threaded and dynamic library is built |
| 55 | # multi-threaded. It is possible to force multi or single threaded builds by appending |
| 56 | # -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded). |
| 57 | .PHONY: default |
| 58 | default: lib-release |
| 59 | |
| 60 | CPPFLAGS_DYNLIB += -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded |
| 61 | LDFLAGS_DYNLIB += -pthread |
| 62 | CPPFLAGS_STATLIB += # static library build defaults to single-threaded |
| 63 | |
| 64 | |
| 65 | ifeq ($(findstring GCC,$(CCVER)),GCC) |
| 66 | decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize |
| 67 | endif |
| 68 | |
| 69 | |
| 70 | # macOS linker doesn't support -soname, and use different extension |
| 71 | # see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html |
| 72 | ifeq ($(UNAME), Darwin) |
| 73 | SHARED_EXT = dylib |
| 74 | SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) |
| 75 | SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) |
| 76 | SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) |
| 77 | else |
| 78 | ifeq ($(UNAME), AIX) |
| 79 | SONAME_FLAGS = |
| 80 | else |
| 81 | SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) |
| 82 | endif |
| 83 | SHARED_EXT = so |
| 84 | SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) |
| 85 | SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) |
| 86 | endif |
| 87 | |
| 88 | |
| 89 | .PHONY: all |
| 90 | all: lib |
| 91 | |
| 92 | |
| 93 | .PHONY: libzstd.a # must be run every time |
| 94 | libzstd.a: CPPFLAGS += $(CPPFLAGS_STATLIB) |
| 95 | |
| 96 | SET_CACHE_DIRECTORY = \ |
| 97 | +$(MAKE) --no-print-directory $@ \ |
| 98 | BUILD_DIR=obj/$(HASH_DIR) \ |
| 99 | CPPFLAGS="$(CPPFLAGS)" \ |
| 100 | CFLAGS="$(CFLAGS)" \ |
| 101 | LDFLAGS="$(LDFLAGS)" |
| 102 | |
| 103 | ifndef BUILD_DIR |
| 104 | # determine BUILD_DIR from compilation flags |
| 105 | |
| 106 | libzstd.a: |
| 107 | $(SET_CACHE_DIRECTORY) |
| 108 | |
| 109 | else |
| 110 | # BUILD_DIR is defined |
| 111 | |
| 112 | ZSTD_STATLIB_DIR := $(BUILD_DIR)/static |
| 113 | ZSTD_STATLIB := $(ZSTD_STATLIB_DIR)/libzstd.a |
| 114 | ZSTD_STATLIB_OBJ := $(addprefix $(ZSTD_STATLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) |
| 115 | $(ZSTD_STATLIB): ARFLAGS = rcs |
| 116 | $(ZSTD_STATLIB): | $(ZSTD_STATLIB_DIR) |
| 117 | $(ZSTD_STATLIB): $(ZSTD_STATLIB_OBJ) |
| 118 | # Check for multithread flag at target execution time |
| 119 | $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ |
| 120 | @echo compiling multi-threaded static library $(LIBVER),\ |
| 121 | @echo compiling single-threaded static library $(LIBVER)) |
| 122 | $(AR) $(ARFLAGS) $@ $^ |
| 123 | |
| 124 | libzstd.a: $(ZSTD_STATLIB) |
| 125 | cp -f $< $@ |
| 126 | |
| 127 | endif |
| 128 | |
| 129 | ifneq (,$(filter Windows%,$(TARGET_SYSTEM))) |
| 130 | |
| 131 | LIBZSTD = dll/libzstd.dll |
| 132 | $(LIBZSTD): $(ZSTD_FILES) |
| 133 | @echo compiling dynamic library $(LIBVER) |
| 134 | $(CC) $(FLAGS) -DZSTD_DLL_EXPORT=1 -Wl,--out-implib,dll/libzstd.dll.a -shared $^ -o $@ |
| 135 | |
| 136 | else # not Windows |
| 137 | |
| 138 | LIBZSTD = libzstd.$(SHARED_EXT_VER) |
| 139 | .PHONY: $(LIBZSTD) # must be run every time |
| 140 | $(LIBZSTD): CPPFLAGS += $(CPPFLAGS_DYNLIB) |
| 141 | $(LIBZSTD): CFLAGS += -fPIC -fvisibility=hidden |
| 142 | $(LIBZSTD): LDFLAGS += -shared $(LDFLAGS_DYNLIB) |
| 143 | |
| 144 | ifndef BUILD_DIR |
| 145 | # determine BUILD_DIR from compilation flags |
| 146 | |
| 147 | $(LIBZSTD): |
| 148 | $(SET_CACHE_DIRECTORY) |
| 149 | |
| 150 | else |
| 151 | # BUILD_DIR is defined |
| 152 | |
| 153 | ZSTD_DYNLIB_DIR := $(BUILD_DIR)/dynamic |
| 154 | ZSTD_DYNLIB := $(ZSTD_DYNLIB_DIR)/$(LIBZSTD) |
| 155 | ZSTD_DYNLIB_OBJ := $(addprefix $(ZSTD_DYNLIB_DIR)/,$(ZSTD_LOCAL_OBJ)) |
| 156 | |
| 157 | $(ZSTD_DYNLIB): | $(ZSTD_DYNLIB_DIR) |
| 158 | $(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ) |
| 159 | # Check for multithread flag at target execution time |
| 160 | $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ |
| 161 | @echo compiling multi-threaded dynamic library $(LIBVER),\ |
| 162 | @echo compiling single-threaded dynamic library $(LIBVER)) |
| 163 | $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ |
| 164 | @echo creating versioned links |
| 165 | ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) |
| 166 | ln -sf $@ libzstd.$(SHARED_EXT) |
| 167 | |
| 168 | $(LIBZSTD): $(ZSTD_DYNLIB) |
| 169 | cp -f $< $@ |
| 170 | |
| 171 | endif # ifndef BUILD_DIR |
| 172 | endif # if windows |
| 173 | |
| 174 | .PHONY: libzstd |
| 175 | libzstd : $(LIBZSTD) |
| 176 | |
| 177 | .PHONY: lib |
| 178 | lib : libzstd.a libzstd |
| 179 | |
| 180 | |
| 181 | # note : do not define lib-mt or lib-release as .PHONY |
| 182 | # make does not consider implicit pattern rule for .PHONY target |
| 183 | |
| 184 | %-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD |
| 185 | %-mt : CPPFLAGS_STATLIB := -DZSTD_MULTITHREAD |
| 186 | %-mt : LDFLAGS_DYNLIB := -pthread |
| 187 | %-mt : % |
| 188 | @echo multi-threaded build completed |
| 189 | |
| 190 | %-nomt : CPPFLAGS_DYNLIB := |
| 191 | %-nomt : LDFLAGS_DYNLIB := |
| 192 | %-nomt : CPPFLAGS_STATLIB := |
| 193 | %-nomt : % |
| 194 | @echo single-threaded build completed |
| 195 | |
| 196 | %-release : DEBUGFLAGS := |
| 197 | %-release : % |
| 198 | @echo release build completed |
| 199 | |
| 200 | |
| 201 | # Generate .h dependencies automatically |
| 202 | |
| 203 | DEPFLAGS = -MT $@ -MMD -MP -MF |
| 204 | |
| 205 | $(ZSTD_DYNLIB_DIR)/%.o : %.c $(ZSTD_DYNLIB_DIR)/%.d | $(ZSTD_DYNLIB_DIR) |
| 206 | @echo CC $@ |
| 207 | $(COMPILE.c) $(DEPFLAGS) $(ZSTD_DYNLIB_DIR)/$*.d $(OUTPUT_OPTION) $< |
| 208 | |
| 209 | $(ZSTD_STATLIB_DIR)/%.o : %.c $(ZSTD_STATLIB_DIR)/%.d | $(ZSTD_STATLIB_DIR) |
| 210 | @echo CC $@ |
| 211 | $(COMPILE.c) $(DEPFLAGS) $(ZSTD_STATLIB_DIR)/$*.d $(OUTPUT_OPTION) $< |
| 212 | |
| 213 | $(ZSTD_DYNLIB_DIR)/%.o : %.S | $(ZSTD_DYNLIB_DIR) |
| 214 | @echo AS $@ |
| 215 | $(COMPILE.S) $(OUTPUT_OPTION) $< |
| 216 | |
| 217 | $(ZSTD_STATLIB_DIR)/%.o : %.S | $(ZSTD_STATLIB_DIR) |
| 218 | @echo AS $@ |
| 219 | $(COMPILE.S) $(OUTPUT_OPTION) $< |
| 220 | |
| 221 | MKDIR ?= mkdir |
| 222 | $(BUILD_DIR) $(ZSTD_DYNLIB_DIR) $(ZSTD_STATLIB_DIR): |
| 223 | $(MKDIR) -p $@ |
| 224 | |
| 225 | DEPFILES := $(ZSTD_DYNLIB_OBJ:.o=.d) $(ZSTD_STATLIB_OBJ:.o=.d) |
| 226 | $(DEPFILES): |
| 227 | |
| 228 | include $(wildcard $(DEPFILES)) |
| 229 | |
| 230 | |
| 231 | # Special case : building library in single-thread mode _and_ without zstdmt_compress.c |
| 232 | ZSTDMT_FILES = compress/zstdmt_compress.c |
| 233 | ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(ZSTD_FILES)) |
| 234 | libzstd-nomt: CFLAGS += -fPIC -fvisibility=hidden |
| 235 | libzstd-nomt: LDFLAGS += -shared |
| 236 | libzstd-nomt: $(ZSTD_NOMT_FILES) |
| 237 | @echo compiling single-thread dynamic library $(LIBVER) |
| 238 | @echo files : $(ZSTD_NOMT_FILES) |
| 239 | $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ |
| 240 | |
| 241 | .PHONY: clean |
| 242 | clean: |
| 243 | $(RM) -r *.dSYM # macOS-specific |
| 244 | $(RM) core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc |
| 245 | $(RM) dll/libzstd.dll dll/libzstd.lib libzstd-nomt* |
| 246 | $(RM) -r obj/* |
| 247 | @echo Cleaning library completed |
| 248 | |
| 249 | #----------------------------------------------------------------------------- |
| 250 | # make install is validated only for below listed environments |
| 251 | #----------------------------------------------------------------------------- |
| 252 | ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) |
| 253 | |
| 254 | lib: libzstd.pc |
| 255 | |
| 256 | HAS_EXPLICIT_EXEC_PREFIX := $(if $(or $(EXEC_PREFIX),$(exec_prefix)),1,) |
| 257 | |
| 258 | DESTDIR ?= |
| 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 |
| 262 | prefix ?= /usr/local |
| 263 | PREFIX ?= $(prefix) |
| 264 | exec_prefix ?= $(PREFIX) |
| 265 | EXEC_PREFIX ?= $(exec_prefix) |
| 266 | libdir ?= $(EXEC_PREFIX)/lib |
| 267 | LIBDIR ?= $(libdir) |
| 268 | includedir ?= $(PREFIX)/include |
| 269 | INCLUDEDIR ?= $(includedir) |
| 270 | |
| 271 | PCINCDIR := $(patsubst $(PREFIX)%,%,$(INCLUDEDIR)) |
| 272 | PCLIBDIR := $(patsubst $(EXEC_PREFIX)%,%,$(LIBDIR)) |
| 273 | |
| 274 | # If we successfully stripped off a prefix, we'll add a reference to the |
| 275 | # relevant pc variable. |
| 276 | PCINCPREFIX := $(if $(findstring $(INCLUDEDIR),$(PCINCDIR)),,$${prefix}) |
| 277 | PCLIBPREFIX := $(if $(findstring $(LIBDIR),$(PCLIBDIR)),,$${exec_prefix}) |
| 278 | |
| 279 | # If no explicit EXEC_PREFIX was set by the caller, write it out as a reference |
| 280 | # to PREFIX, rather than as a resolved value. |
| 281 | PCEXEC_PREFIX := $(if $(HAS_EXPLICIT_EXEC_PREFIX),$(EXEC_PREFIX),$${prefix}) |
| 282 | |
| 283 | ifneq (,$(filter $(UNAME),FreeBSD NetBSD DragonFly)) |
| 284 | PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig |
| 285 | else |
| 286 | PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig |
| 287 | endif |
| 288 | |
| 289 | ifneq (,$(filter $(UNAME),SunOS)) |
| 290 | INSTALL ?= ginstall |
| 291 | else |
| 292 | INSTALL ?= install |
| 293 | endif |
| 294 | |
| 295 | INSTALL_PROGRAM ?= $(INSTALL) |
| 296 | INSTALL_DATA ?= $(INSTALL) -m 644 |
| 297 | |
| 298 | |
| 299 | libzstd.pc: libzstd.pc.in |
| 300 | @echo creating pkgconfig |
| 301 | @sed \ |
| 302 | -e 's|@PREFIX@|$(PREFIX)|' \ |
| 303 | -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ |
| 304 | -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ |
| 305 | -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ |
| 306 | -e 's|@VERSION@|$(VERSION)|' \ |
| 307 | -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \ |
| 308 | $< >$@ |
| 309 | |
| 310 | .PHONY: install |
| 311 | install: install-pc install-static install-shared install-includes |
| 312 | @echo zstd static and shared library installed |
| 313 | |
| 314 | .PHONY: install-pc |
| 315 | install-pc: libzstd.pc |
| 316 | [ -e $(DESTDIR)$(PKGCONFIGDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/ |
| 317 | $(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/ |
| 318 | |
| 319 | .PHONY: install-static |
| 320 | install-static: |
| 321 | # only generate libzstd.a if it's not already present |
| 322 | [ -e libzstd.a ] || $(MAKE) libzstd.a-release |
| 323 | [ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/ |
| 324 | @echo Installing static library |
| 325 | $(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR) |
| 326 | |
| 327 | .PHONY: install-shared |
| 328 | install-shared: |
| 329 | # only generate libzstd.so if it's not already present |
| 330 | [ -e $(LIBZSTD) ] || $(MAKE) libzstd-release |
| 331 | [ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/ |
| 332 | @echo Installing shared library |
| 333 | $(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR) |
| 334 | ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) |
| 335 | ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) |
| 336 | |
| 337 | .PHONY: install-includes |
| 338 | install-includes: |
| 339 | [ -e $(DESTDIR)$(INCLUDEDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/ |
| 340 | @echo Installing includes |
| 341 | $(INSTALL_DATA) zstd.h $(DESTDIR)$(INCLUDEDIR) |
| 342 | $(INSTALL_DATA) zstd_errors.h $(DESTDIR)$(INCLUDEDIR) |
| 343 | $(INSTALL_DATA) zdict.h $(DESTDIR)$(INCLUDEDIR) |
| 344 | |
| 345 | .PHONY: uninstall |
| 346 | uninstall: |
| 347 | $(RM) $(DESTDIR)$(LIBDIR)/libzstd.a |
| 348 | $(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) |
| 349 | $(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) |
| 350 | $(RM) $(DESTDIR)$(LIBDIR)/$(LIBZSTD) |
| 351 | $(RM) $(DESTDIR)$(PKGCONFIGDIR)/libzstd.pc |
| 352 | $(RM) $(DESTDIR)$(INCLUDEDIR)/zstd.h |
| 353 | $(RM) $(DESTDIR)$(INCLUDEDIR)/zstd_errors.h |
| 354 | $(RM) $(DESTDIR)$(INCLUDEDIR)/zdict.h |
| 355 | @echo zstd libraries successfully uninstalled |
| 356 | |
| 357 | endif |