1#
2# UPX Makefile - needs GNU make 3.81 or better
3#
4# Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
5#
6
7# build configuration options for this Makefile
8BUILD_TYPE_DEBUG    ?= 0
9BUILD_TYPE_SANITIZE ?= 0
10BUILD_USE_DEPEND    ?= 1
11
12MAKEFLAGS += -r
13.SUFFIXES:
14export SHELL = /bin/sh
15override ee = $($1) $(EXTRA_$1) $(upx_$1) $(upx_EXTRA_$1) $($(basename $(notdir $@)).$1)
16
17ifndef srcdir
18srcdir := $(dir $(lastword $(MAKEFILE_LIST)))
19srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,' || echo 'ERROR')
20endif
21ifndef top_srcdir
22top_srcdir := $(srcdir)/..
23endif
24include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
25ifneq ($(srcdir),.)
26vpath %.cpp .:$(srcdir)
27vpath %.h   .:$(srcdir)
28endif
29
30# toolchain
31CXX    ?= g++
32CXXLD   = $(CXX)
33exeext ?= .out
34libext ?= .a
35objext ?= .o
36
37upx_SOURCES := $(sort $(wildcard $(srcdir)/*.cpp))
38upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
39
40ifneq ($(wildcard $(top_srcdir)/.git/.),)
41UPX_VERSION_GITREV := $(strip $(shell cd '$(top_srcdir)' && git rev-parse --short=12 HEAD || echo 'ERROR'))
42ifneq ($(UPX_VERSION_GITREV),)
43GITREV_PLUS := $(strip $(shell cd '$(top_srcdir)' && git diff --exit-code HEAD >/dev/null && echo '' || echo '+'))
44DEFS += '-DUPX_VERSION_GITREV="$(UPX_VERSION_GITREV)$(GITREV_PLUS)"'
45endif
46endif
47
48# we need UCL and zlib - you can set envvar UPX_UCLDIR
49ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
50INCLUDES += -I$(UPX_UCLDIR)/include
51LIBS += -L$(UPX_UCLDIR)/lib
52endif
53LIBS += -lucl -lz
54# LZMA from https://github.com/upx/upx-lzma-sdk
55include $(top_srcdir)/src/stub/src/c/Makevars.lzma
56
57CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
58ifeq ($(BUILD_TYPE_DEBUG),1)
59CXXFLAGS_OPTIMIZE ?= -O0 -g
60else
61CXXFLAGS_OPTIMIZE ?= -O2
62endif
63CXXFLAGS += $(CXXFLAGS_OPTIMIZE)
64# protect against security threats caused by misguided C++ compiler "optimizations"
65# ifeq ($(findstring clang,$(CXX)),)
66# CXXFLAGS += -fno-delete-null-pointer-checks
67# endif
68CXXFLAGS += -fno-strict-aliasing -fwrapv
69CXXFLAGS += -funsigned-char
70CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wvla -Wwrite-strings
71CXXFLAGS_WERROR ?= -Werror
72CXXFLAGS += $(CXXFLAGS_WERROR)
73
74ifeq ($(BUILD_TYPE_SANITIZE),1)
75CXXFLAGS_SANITIZE ?= -fsanitize=address,undefined -fno-omit-frame-pointer -DACC_CFG_NO_UNALIGNED
76CXXFLAGS += $(CXXFLAGS_SANITIZE)
77# these are the only 2 objects that are actually speed-sensitive
78compress_lzma$(objext) filteri$(objext) : override CXXFLAGS_SANITIZE =
79endif
80
81# rules
82all: upx$(exeext) | ./.depend
83.DELETE_ON_ERROR: upx$(exeext) $(upx_OBJECTS) ./.depend
84
85upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
86	$($(notdir $@).PRE_LINK_STEP)
87	$(strip $(CXXLD) $(call ee,CXXFLAGS) $(call ee,LDFLAGS) -o $@ $(upx_OBJECTS) $(call ee,LDADD) $(call ee,LIBS))
88	$($(notdir $@).POST_LINK_STEP)
89	$(CHECK_WHITESPACE)
90
91%.o : %.cpp | ./.depend
92	$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -c $<)
93%.cpp.ii : %.cpp
94	$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -o $@ -E $<)
95
96ifeq ($(BUILD_USE_DEPEND),1)
97./.depend: $(sort $(wildcard $(srcdir)/*.cpp $(srcdir)/*.h)) $(MAKEFILE_LIST)
98	@rm -f $@
99	@echo "Updating $@"
100	@$(strip $(CXX) $(call ee,CPPFLAGS) $(call ee,CXXFLAGS) -MM) $(filter %.cpp,$^) > $@
101else
102./.depend:
103.PHONY: ./.depend
104endif
105
106CHECK_WHITESPACE =
107ifeq ($(shell uname),Linux)
108CHECK_WHITESPACE = $(top_srcdir)/src/stub/scripts/check_whitespace.sh $(top_srcdir)
109ifneq ($(wildcard $(top_srcdir)/.git/.),)
110CHECK_WHITESPACE = $(top_srcdir)/src/stub/scripts/check_whitespace_git.sh $(top_srcdir)
111endif
112check-whitespace : ; $(CHECK_WHITESPACE)
113endif
114.PHONY: check-whitespace
115
116mostlyclean clean distclean maintainer-clean:
117	rm -f *.d *.ii *.map *.o *.obj *.res ./.depend upx.exe upx.out upx.ttp upx$(exeext)
118
119./.depend compress_lzma$(objext) : INCLUDES += -I$(UPX_LZMADIR)
120
121compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
122p_mach$(objext)        : CXXFLAGS += -Wno-cast-align
123
124.PHONY: all mostlyclean clean distclean maintainer-clean
125
126ifeq ($(MAKECMDGOALS),mostlyclean)
127else ifeq ($(MAKECMDGOALS),clean)
128else ifeq ($(MAKECMDGOALS),distclean)
129else ifeq ($(MAKECMDGOALS),maintainer-clean)
130else ifeq ($(MAKECMDGOALS),clang-format)
131else ifeq ($(MAKECMDGOALS),check-whitespace)
132else
133ifeq ($(BUILD_USE_DEPEND),1)
134-include ./.depend
135endif
136help$(objext): $(MAKEFILE_LIST)
137endif
138
139# "make run-testsuite"
140# search for the UPX testsuite -- git clone https://github.com/upx/upx-testsuite.git
141# you also can override upx_testsuite_SRCDIR
142ifndef upx_testsuite_SRCDIR
143# search standard locations below $(top_srcdir)
144ifneq ($(wildcard $(top_srcdir)/../upx-testsuite.git/files/packed/.),)
145upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite.git
146else ifneq ($(wildcard $(top_srcdir)/../upx-testsuite/files/packed/.),)
147upx_testsuite_SRCDIR := $(top_srcdir)/../upx-testsuite
148endif
149endif
150# run the UPX testsuite
151# The expected (old) checksums are in $(top_srcdir)/.github/travis_testsuite_1-expected_sha256sums.sh
152# The   actual (new) checksums are in tmp-testsuite/testsuite_1/.sha256sums.recreate
153ifneq ($(wildcard $(upx_testsuite_SRCDIR)/files/packed/.),)
154ifneq ($(wildcard $(top_srcdir)/.github/travis_testsuite_1.sh),)
155run-testsuite: export upx_exe                := ./upx$(exeext)
156run-testsuite: export upx_testsuite_SRCDIR   := $(upx_testsuite_SRCDIR)
157run-testsuite: export upx_testsuite_BUILDDIR := ./tmp-testsuite
158run-testsuite: ./upx$(exeext)
159	time -p bash $(top_srcdir)/.github/travis_testsuite_1.sh
160.PHONY: run-testsuite
161endif
162endif
163
164# automatically format some C++ source code files
165ifeq ($(shell uname),Linux)
166CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
167CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
168CLANG_FORMAT_FILES += snprintf.cpp
169CLANG_FORMAT_FILES += stdcxx.cpp stdcxx.h
170CLANG_FORMAT_FILES += ui.cpp ui.h util.cpp util.h work.cpp
171clang-format:
172	$(top_srcdir)/src/stub/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(CLANG_FORMAT_FILES))
173.PHONY: clang-format
174endif
175
176# vim:set ts=8 sw=8 noet:
177