1# ################################################################
2# Copyright (c) 2016-present, 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
10# Standard variables for installation
11DESTDIR ?=
12PREFIX  ?= /usr/local
13BINDIR  := $(DESTDIR)$(PREFIX)/bin
14
15ZSTDDIR = ../../lib
16PROGDIR = ../../programs
17
18# External program to use to run tests, e.g. qemu or valgrind
19TESTPROG  ?=
20# Flags to pass to the tests
21TESTFLAGS ?=
22
23# We use gcc/clang to generate the header dependencies of files
24DEPFLAGS = -MMD -MP -MF $*.Td
25POSTCOMPILE = mv -f $*.Td $*.d
26
27# CFLAGS, CXXFLAGS, CPPFLAGS, and LDFLAGS are for the users to override
28CFLAGS   ?= -O3 -Wall -Wextra
29CXXFLAGS ?= -O3 -Wall -Wextra -pedantic
30CPPFLAGS ?=
31LDFLAGS  ?=
32
33# Include flags
34PZSTD_INC  = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I.
35GTEST_INC  = -isystem googletest/googletest/include
36
37PZSTD_CPPFLAGS  = $(PZSTD_INC)
38PZSTD_CCXXFLAGS =
39PZSTD_CFLAGS    = $(PZSTD_CCXXFLAGS)
40PZSTD_CXXFLAGS  = $(PZSTD_CCXXFLAGS) -std=c++11
41PZSTD_LDFLAGS   =
42EXTRA_FLAGS     =
43ALL_CFLAGS      = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CFLAGS)   $(PZSTD_CFLAGS)
44ALL_CXXFLAGS    = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CXXFLAGS) $(PZSTD_CXXFLAGS)
45ALL_LDFLAGS     = $(EXTRA_FLAGS) $(LDFLAGS) $(PZSTD_LDFLAGS)
46
47
48# gtest libraries need to go before "-lpthread" because they depend on it.
49GTEST_LIB  = -L googletest/build/googlemock/gtest
50LIBS       =
51
52# Compilation commands
53LD_COMMAND  = $(CXX) $^          $(ALL_LDFLAGS) $(LIBS) -lpthread -o $@
54CC_COMMAND  = $(CC)  $(DEPFLAGS) $(ALL_CFLAGS)   -c $<  -o $@
55CXX_COMMAND = $(CXX) $(DEPFLAGS) $(ALL_CXXFLAGS) -c $<  -o $@
56
57# Get a list of all zstd files so we rebuild the static library when we need to
58ZSTDCOMMON_FILES := $(wildcard $(ZSTDDIR)/common/*.c) \
59                    $(wildcard $(ZSTDDIR)/common/*.h)
60ZSTDCOMP_FILES   := $(wildcard $(ZSTDDIR)/compress/*.c) \
61                    $(wildcard $(ZSTDDIR)/compress/*.h)
62ZSTDDECOMP_FILES := $(wildcard $(ZSTDDIR)/decompress/*.c) \
63                    $(wildcard $(ZSTDDIR)/decompress/*.h)
64ZSTDPROG_FILES   := $(wildcard $(PROGDIR)/*.c) \
65                    $(wildcard $(PROGDIR)/*.h)
66ZSTD_FILES       := $(wildcard $(ZSTDDIR)/*.h) \
67                    $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) \
68                    $(ZSTDPROG_FILES)
69
70# List all the pzstd source files so we can determine their dependencies
71PZSTD_SRCS  := $(wildcard *.cpp)
72PZSTD_TESTS := $(wildcard test/*.cpp)
73UTILS_TESTS := $(wildcard utils/test/*.cpp)
74ALL_SRCS    := $(PZSTD_SRCS) $(PZSTD_TESTS) $(UTILS_TESTS)
75
76
77# Define *.exe as extension for Windows systems
78ifneq (,$(filter Windows%,$(OS)))
79EXT =.exe
80else
81EXT =
82endif
83
84# Standard targets
85.PHONY: default
86default: all
87
88.PHONY: test-pzstd
89test-pzstd: TESTFLAGS=--gtest_filter=-*ExtremelyLarge*
90test-pzstd: clean googletest pzstd tests check
91
92.PHONY: test-pzstd32
93test-pzstd32: clean googletest32 all32 check
94
95.PHONY: test-pzstd-tsan
96test-pzstd-tsan: LDFLAGS=-fuse-ld=gold
97test-pzstd-tsan: TESTFLAGS=--gtest_filter=-*ExtremelyLarge*
98test-pzstd-tsan: clean googletest tsan check
99
100.PHONY: test-pzstd-asan
101test-pzstd-asan: LDFLAGS=-fuse-ld=gold
102test-pzstd-asan: TESTFLAGS=--gtest_filter=-*ExtremelyLarge*
103test-pzstd-asan: clean asan check
104
105.PHONY: check
106check:
107	$(TESTPROG) ./utils/test/BufferTest$(EXT) $(TESTFLAGS)
108	$(TESTPROG) ./utils/test/RangeTest$(EXT) $(TESTFLAGS)
109	$(TESTPROG) ./utils/test/ResourcePoolTest$(EXT) $(TESTFLAGS)
110	$(TESTPROG) ./utils/test/ScopeGuardTest$(EXT) $(TESTFLAGS)
111	$(TESTPROG) ./utils/test/ThreadPoolTest$(EXT) $(TESTFLAGS)
112	$(TESTPROG) ./utils/test/WorkQueueTest$(EXT) $(TESTFLAGS)
113	$(TESTPROG) ./test/OptionsTest$(EXT) $(TESTFLAGS)
114	$(TESTPROG) ./test/PzstdTest$(EXT) $(TESTFLAGS)
115
116.PHONY: install
117install: PZSTD_CPPFLAGS += -DNDEBUG
118install: pzstd$(EXT)
119	install -d -m 755 $(BINDIR)/
120	install -m 755 pzstd$(EXT) $(BINDIR)/pzstd$(EXT)
121
122.PHONY: uninstall
123uninstall:
124	$(RM) $(BINDIR)/pzstd$(EXT)
125
126# Targets for many different builds
127.PHONY: all
128all: PZSTD_CPPFLAGS += -DNDEBUG
129all: pzstd$(EXT)
130
131.PHONY: debug
132debug: EXTRA_FLAGS += -g
133debug: pzstd$(EXT) tests roundtrip
134
135.PHONY: tsan
136tsan: PZSTD_CCXXFLAGS += -fsanitize=thread -fPIC
137tsan: PZSTD_LDFLAGS   += -fsanitize=thread
138tsan: debug
139
140.PHONY: asan
141asan: EXTRA_FLAGS += -fsanitize=address
142asan: debug
143
144.PHONY: ubsan
145ubsan: EXTRA_FLAGS += -fsanitize=undefined
146ubsan: debug
147
148.PHONY: all32
149all32: EXTRA_FLAGS += -m32
150all32: all tests roundtrip
151
152.PHONY: debug32
153debug32: EXTRA_FLAGS += -m32
154debug32: debug
155
156.PHONY: asan32
157asan32: EXTRA_FLAGS += -m32
158asan32: asan
159
160.PHONY: tsan32
161tsan32: EXTRA_FLAGS += -m32
162tsan32: tsan
163
164.PHONY: ubsan32
165ubsan32: EXTRA_FLAGS += -m32
166ubsan32: ubsan
167
168# Run long round trip tests
169.PHONY: roundtripcheck
170roundtripcheck: roundtrip check
171	$(TESTPROG) ./test/RoundTripTest$(EXT) $(TESTFLAGS)
172
173# Build the main binary
174pzstd$(EXT): main.o Options.o Pzstd.o SkippableFrame.o $(ZSTDDIR)/libzstd.a
175	$(LD_COMMAND)
176
177# Target that depends on all the tests
178.PHONY: tests
179tests: EXTRA_FLAGS += -Wno-deprecated-declarations
180tests: $(patsubst %,%$(EXT),$(basename $(PZSTD_TESTS) $(UTILS_TESTS)))
181
182# Build the round trip tests
183.PHONY: roundtrip
184roundtrip: EXTRA_FLAGS += -Wno-deprecated-declarations
185roundtrip: test/RoundTripTest$(EXT)
186
187# Use the static library that zstd builds for simplicity and
188# so we get the compiler options correct
189$(ZSTDDIR)/libzstd.a: $(ZSTD_FILES)
190	CFLAGS="$(ALL_CFLAGS)" LDFLAGS="$(ALL_LDFLAGS)" $(MAKE) -C $(ZSTDDIR) libzstd.a
191
192# Rules to build the tests
193test/RoundTripTest$(EXT): test/RoundTripTest.o $(PROGDIR)/datagen.o Options.o \
194                          Pzstd.o SkippableFrame.o $(ZSTDDIR)/libzstd.a
195	$(LD_COMMAND)
196
197test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB)
198test/%Test$(EXT): LIBS += -lgtest -lgtest_main
199test/%Test$(EXT): test/%Test.o $(PROGDIR)/datagen.o Options.o Pzstd.o  \
200                  SkippableFrame.o $(ZSTDDIR)/libzstd.a
201	$(LD_COMMAND)
202
203utils/test/%Test$(EXT): PZSTD_LDFLAGS += $(GTEST_LIB)
204utils/test/%Test$(EXT): LIBS += -lgtest -lgtest_main
205utils/test/%Test$(EXT): utils/test/%Test.o
206	$(LD_COMMAND)
207
208
209GTEST_CMAKEFLAGS =
210
211# Install googletest
212.PHONY: googletest
213googletest: PZSTD_CCXXFLAGS += -fPIC
214googletest:
215	@$(RM) -rf googletest
216	@git clone https://github.com/google/googletest
217	@mkdir -p googletest/build
218	@cd googletest/build && cmake $(GTEST_CMAKEFLAGS) -DCMAKE_CXX_FLAGS="$(ALL_CXXFLAGS)" .. && $(MAKE)
219
220.PHONY: googletest32
221googletest32: PZSTD_CCXXFLAGS  += -m32
222googletest32: googletest
223
224.PHONY: googletest-mingw64
225googletest-mingw64: GTEST_CMAKEFLAGS += -G "MSYS Makefiles"
226googletest-mingw64: googletest
227
228.PHONY: clean
229clean:
230	$(RM) -f *.o pzstd$(EXT) *.Td *.d
231	$(RM) -f test/*.o test/*Test$(EXT) test/*.Td test/*.d
232	$(RM) -f utils/test/*.o utils/test/*Test$(EXT) utils/test/*.Td utils/test/*.d
233	$(RM) -f $(PROGDIR)/*.o $(PROGDIR)/*.Td $(PROGDIR)/*.d
234	$(MAKE) -C $(ZSTDDIR) clean
235	@echo Cleaning completed
236
237
238# Cancel implicit rules
239%.o: %.c
240%.o: %.cpp
241
242# Object file rules
243%.o: %.c
244	$(CC_COMMAND)
245	$(POSTCOMPILE)
246
247$(PROGDIR)/%.o: $(PROGDIR)/%.c
248	$(CC_COMMAND)
249	$(POSTCOMPILE)
250
251%.o: %.cpp
252	$(CXX_COMMAND)
253	$(POSTCOMPILE)
254
255test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC)
256test/%.o: test/%.cpp
257	$(CXX_COMMAND)
258	$(POSTCOMPILE)
259
260utils/test/%.o: PZSTD_CPPFLAGS += $(GTEST_INC)
261utils/test/%.o: utils/test/%.cpp
262	$(CXX_COMMAND)
263	$(POSTCOMPILE)
264
265# Dependency file stuff
266.PRECIOUS: %.d test/%.d utils/test/%.d
267
268# Include rules that specify header file dependencies
269-include $(patsubst %,%.d,$(basename $(ALL_SRCS)))
270