MAKEFLAGS += -rR
.SUFFIXES:
.SECONDEXPANSION:

ifndef top_srcdir
__dir_list   = . .. ../.. ../../.. ../../../.. ../../../../..
__dir_list  += ../../../../../.. ../../../../../../.. ../../../../../../../..
__dir_search = $(firstword $(foreach v,$1,$(if $(wildcard $v/$2),$v)) $3)
top_srcdir := $(call __dir_search,$(__dir_list),src/bele.h,NOT_FOUND)
endif
include $(wildcard $(top_srcdir)/Makevars.global ./Makevars.local)
vpath %.c $(top_srcdir)/src/stub/src/c

STUBS =
include $(top_srcdir)/src/stub/src/c/Makevars.lzma
ifneq ($(UPX_LZMA_VERSION),)
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
STUBS += lzma_d_cf.S lzma_d_cs.S
endif
endif

default.targets = all
ifeq ($(strip $(STUBS)),)
STUBS = NO_STUBS
all.targets =
endif
include $(top_srcdir)/src/stub/Makefile


# /***********************************************************************
# //
# ************************************************************************/

# enumerate the names of all environment variables
# FIXME: "origin" does not work for things like "export LC_ALL = C"
##__minienv_varlist = $(foreach v,$1,$(if $(findstring environment,$(origin $v)),$v))
__minienv_varlist = $(foreach v,$1,$(if $($v),$v))
# enumerate the names of all environment variables
__minienv_expand = $(foreach v,$(call __minienv_varlist,$1),$v='$($v)')

ifndef DOSBOX_EXE
DOSBOX_EXE := $(shell which dosbox 2>/dev/null)
endif
ifdef DOSBOX_EXE
ifndef DOSBOX
DOSBOX = $(DOSBOX_EXE)
DOSBOX = /usr/bin/time -p $(DOSBOX_EXE) -exit
endif
endif

ifndef WINE_EXE
WINE_EXE := $(shell which wine 2>/dev/null)
endif
ifndef WINEPATH_EXE
WINEPATH_EXE:= $(shell which winepath 2>/dev/null)
endif
ifdef WINE_EXE
##WINEENV = @env
WINEENV = @env -i $(call __minienv_expand,$(sort DISPLAY HOME LANG LC_ALL PATH USER TERM WINEDEBUG WINEPATH WINEPREFIX $(WINEENV_EXTRA_VARNAMES)))
ifdef WINEPREFIX
winedir_s = z:$(shell WINEPREFIX='$(WINEPREFIX)' $(WINEPATH_EXE) -s '$(realpath $1)')
winedir_w =   $(shell WINEPREFIX='$(WINEPREFIX)' $(WINEPATH_EXE) -w '$(realpath $1)')
else
winedir_s = z:$(shell $(WINEPATH_EXE) -s '$(realpath $1)')
winedir_w =   $(shell $(WINEPATH_EXE) -w '$(realpath $1)')
endif
else
WINEENV = false 'WINEENV'
winedir_s = $1
winedir_w = $1
endif

# work around limitations of wine's cmd.exe
define mkbat
	rm -f $1
	$(ECHO_E) '@set PATH=$3;%PATH%' >> $1
	$(ECHO_E) '@set INCLUDE=$4' >> $1
	$(ECHO_E) '@set LIB=$5' >> $1
	$(ECHO_E) '@set a=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
	$(ECHO_e) '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
	$(ECHO_e) '@shift\n@shift\n@shift\n@shift' >> $1
	$(ECHO_E) '@set b=%1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
	$(ECHO_e) '@shift\n@shift\n@shift\n@shift\n@shift' >> $1
	$(ECHO_e) '@shift\n@shift\n@shift\n@shift' >> $1
	$(ECHO_E) '$2 %a% %b% %1 %2 %3 %4 %5 %6 %7 %8 %9' >> $1
	$(UNIX2DOS) $1
endef

TMP_DEPS = tmp/.tmp-stamp tmp/bcc.bat tmp/bcc.rsp tmp/cl.bat tmp/cl.rsp tmp/dmc.bat tmp/dmc.rsp

tmp/bcc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@$(call mkbat,$@,bcc.exe,$(call winedir_w,$(BC502DIR)/bin))
tmp/cl.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@$(call mkbat,$@,cl.exe,$(call winedir_w,$(VC152DIR)/bin),$(call winedir_w,$(VC152DIR)/include),$(call winedir_w,$(VC152DIR)/lib))
tmp/dmc.bat: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@$(call mkbat,$@,dmc.exe,$(call winedir_w,$(DM849DIR)/bin))

tmp/bcc.rsp: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@rm -f $@
	@$(ECHO_E) '-D__INT_MAX__=32767' >> $@
	@$(ECHO_E) '-DWITH_LZMA=$(UPX_LZMA_VERSION)' >> $@
ifneq ($(findstring .$(UPX_LZMA_VERSION).,.0x449.0x457.),)
	@$(ECHO_E) '-I$(subst \,/,$(call winedir_w,$(UPX_LZMADIR)/C/Compress/Lzma))' >> $@
else
	@$(ECHO_E) '-I$(subst \,/,$(call winedir_w,$(UPX_LZMADIR)/C/7zip/Compress/LZMA_C))' >> $@
endif
	@$(ECHO_E) '-I$(top_srcdir)/src' >> $@
	@$(UNIX2DOS) $@

tmp/cl.rsp: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@rm -f $@
	@$(ECHO_E) '-D__INT_MAX__=32767' >> $@
	@$(ECHO_E) '-DWITH_LZMA=$(UPX_LZMA_VERSION)' >> $@
	@$(ECHO_E) '-I$(call winedir_w,$(UPX_LZMADIR))' >> $@
	@$(ECHO_E) '-I$(call winedir_w,$(top_srcdir)/src)' >> $@
	@$(UNIX2DOS) $@

tmp/dmc.rsp: tmp/.tmp-stamp $(MAKEFILE_LIST)
	@rm -f $@
	@$(ECHO_E) '-D__INT_MAX__=32767' >> $@
	@$(ECHO_E) '-DWITH_LZMA=$(UPX_LZMA_VERSION)' >> $@
	@$(ECHO_E) '-I$(call winedir_w,$(UPX_LZMADIR))' >> $@
	@$(ECHO_E) '-I$(call winedir_w,$(top_srcdir)/src)' >> $@
	@$(UNIX2DOS) $@


# /***********************************************************************
# // method-lzma
# ************************************************************************/

lzma_d_c% : tc_list = method-lzma arch-i086 default
lzma_d_c% : tc_bfdname =

# gcc
c := tc.arch-i086.gcc
$c += -MF /dev/null
$c += -Wall -W
$c += -DWITH_LZMA=$(UPX_LZMA_VERSION)
$c += -I$(UPX_LZMADIR)
$c += -I$(top_srcdir)/src

# Borland C/C++ 5.02
ifdef WINE_EXE
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
c := tc.method-lzma.bcc
$c  = $(WINEENV) $(WINE_EXE) cmd.exe /c tmp/bcc.bat
$c += -ms
$c += -O1 -1
$c += -w
$c += @tmp/bcc.rsp
endif
endif

# Digital Mars C/C++ 8.49
# http://www.digitalmars.com/download/freecompiler.html
ifdef WINE_EXE
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
c := tc.method-lzma.dmc
$c  = $(WINEENV) $(WINE_EXE) cmd.exe /c tmp/dmc.bat
$c += -ms -R
$c += -NS
$c += -w- -w7 -r
$c += -o -0
$c += @tmp/dmc.rsp
endif
endif

# Visual C/C++ 1.52 (8.00c)
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
c := tc.method-lzma.cl
$c  = $(WINEENV) $(WINE_EXE) cmd.exe /c tmp/cl.bat
$c += -nologo
$c += -AS -Gd
$c += -Gy
$c += -O2 -Gf -Gs -G0
$c += -W4
$c += @tmp/cl.rsp
endif

# Open Watcom C/C++ 1.6
# http://www.openwatcom.com/
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
c := tc.method-lzma.wcl
$c  = PATH='$(WATCOM)/binl:$(PATH)' $(WATCOM)/binl/wcl -zq -bt=dos
$c += -ms -ecc
$c += -zm -zc
$c += -os -s -0 -d0
$c += -w5 -we -fr=/dev/null
$c += -D__INT_MAX__=32767
$c += -DWITH_LZMA=$(UPX_LZMA_VERSION)
$c += -I$(UPX_LZMADIR)
$c += -I$(top_srcdir)/src
endif


ifneq ($(UPX_LZMA_VERSION),)
ifneq ($(wildcard $(WATCOM)/binl/wcl),)

# step 3: clean asm
lzma_d_c%.S : tmp/lzma_d_c%.i cleanasm.py $(MAKEFILE_LIST)
	$(PYTHON) cleanasm.py --label-prefix=$(LABEL_PREFIX) $< $@

# step 2: compile, strip and disasm
tmp/lzma_d_c%.i : tmp/lzma_d_c%.S $(MAKEFILE_LIST)
	$(call tc,gcc) -x assembler-with-cpp -c -o tmp/$T.o $<
	$(call tc,f-objstrip,tmp/$T.o)
	$(call tc,objdump) -b elf32-i386 -m i8086 -M intel -dr -j .text.LzmaDecode --no-show -w tmp/$T.o | $(RTRIM) | $(PERL) -pe 's/\bDWORD\b/dword/g; s/\bWORD\b/word/g; s/\bBYTE\b/byte/g; s/\bPTR\b/ptr/g;' > $@

# step 1: compile, disasm and convert to gas syntax
tmp/lzma_d_c%.S : lzma_d_c.c wdis2gas.py $(MAKEFILE_LIST) $(TMP_DEPS)
	rm -f tmp/$T*.i tmp/$T*.o tmp/$T*.obj tmp/$T*.S
# compile
ifdef WINE_EXE
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
##	$(call tc,bcc) $(PP_FLAGS) -c -otmp/$T_bc.obj $<
##	$(call tc,wdis) tmp/$T_bc.obj | $(RTRIM) > tmp/$T_bc.obj.disasm
endif
endif
ifdef WINE_EXE
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
	$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T_dm.obj $<
	$(call tc,wdis) tmp/$T_dm.obj | $(RTRIM) > tmp/$T_dm.obj.disasm
endif
endif
ifdef WINE_EXE
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
	$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T_vc.obj $<
	$(call tc,wdis) tmp/$T_vc.obj | $(RTRIM) > tmp/$T_vc.obj.disasm
endif
endif
ifneq ($(wildcard $(WATCOM)/binl/wcl),)
	$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T_wc.obj $<
	$(call tc,wdis) tmp/$T_wc.obj | $(RTRIM) > tmp/$T_wc.obj.disasm
endif
# convert
	$(PYTHON) wdis2gas.py tmp/$T_wc.obj.disasm $@

.PRECIOUS: tmp/lzma_d_c%.i tmp/lzma_d_c%.S

endif
endif

lzma_d_cf.% : PP_FLAGS = -DFAST
lzma_d_cs.% : PP_FLAGS = -DSMALL
lzma_d_cf.% : LABEL_PREFIX = .Lf
lzma_d_cs.% : LABEL_PREFIX = .Ls


# /***********************************************************************
# // cc_test
# ************************************************************************/

ifneq ($(wildcard $(WATCOM)/binl/wdis),)

CC_TEST_DEPS = $(MAKEFILE_LIST) $(TMP_DEPS)

ifdef WINE_EXE
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
cc_test_bc : tc_list = method-lzma arch-i086 default
cc_test_bc: cc_test.c $(CC_TEST_DEPS)
	$(call tc,bcc) $(PP_FLAGS) -c -otmp/$T.obj $<
	$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test-all: cc_test_bc
endif
endif

ifdef WINE_EXE
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
cc_test_dm : tc_list = method-lzma arch-i086 default
cc_test_dm: cc_test.c $(CC_TEST_DEPS)
	$(call tc,dmc) $(PP_FLAGS) -c -otmp/$T.obj $<
	$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test-all: cc_test_dm
endif
endif

ifdef WINE_EXE
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
cc_test_vc : tc_list = method-lzma arch-i086 default
cc_test_vc: cc_test.c $(CC_TEST_DEPS)
	$(call tc,cl) $(PP_FLAGS) -c -Fotmp/$T.obj $<
	$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test-all: cc_test_vc
endif
endif

ifneq ($(wildcard $(WATCOM)/binl/wcl),)
cc_test_wc : tc_list = method-lzma arch-i086 default
cc_test_wc: cc_test.c $(CC_TEST_DEPS)
	$(call tc,wcl) $(PP_FLAGS) -c -fo=tmp/$T.obj $<
	$(call tc,wdis) tmp/$T.obj | $(RTRIM) > tmp/$T.obj.disasm
cc_test-all: cc_test_wc
endif

.PHONY: cc_test-all

endif # wdis


# /***********************************************************************
# // l_test
# ************************************************************************/

L_TEST_DEPS = lzma_d_c.c $(MAKEFILE_LIST) $(TMP_DEPS)

tmp/l_test_gcc_i386.%  : tc_list = arch-i086 default
tmp/l_test_gcc_i386.out: l_test.c $(L_TEST_DEPS)
	$(call tc,gcc) -O0 -g -o $@ $<
	./$@
l_test-all: tmp/l_test_gcc_i386.out

ifdef WINE_EXE
ifneq ($(wildcard $(BC502DIR)/bin/bcc.exe),)
tmp/l_test_bc.%  : tc_list = method-lzma arch-i086 default
tmp/l_test_bc.exe: l_test.c $(L_TEST_DEPS)
	@rm -f l_test.o l_test.obj tmp/test.exe $@
	$(call tc,bcc) -o$(subst /,\\,$@) $<
	@rm -f l_test.o l_test.obj
ifdef DOSBOX
	cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
endif
##l_test-all: tmp/l_test_bc.exe
endif
endif

ifdef WINE_EXE
ifneq ($(wildcard $(DM849DIR)/bin/dmc.exe),)
tmp/l_test_dm.%  : tc_list = method-lzma arch-i086 default
tmp/l_test_dm.exe: l_test.c $(L_TEST_DEPS)
	@rm -f l_test.o l_test.obj tmp/test.exe $@
	$(call tc,dmc) -ml -o$(subst /,\\,$@) $<
	@rm -f l_test.o l_test.obj
ifdef DOSBOX
	cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
endif
l_test-all: tmp/l_test_dm.exe
endif
endif

ifdef WINE_EXE
ifneq ($(wildcard $(VC152DIR)/bin/cl.exe),)
tmp/l_test_vc.%  : tc_list = method-lzma arch-i086 default
tmp/l_test_vc.exe: l_test.c $(L_TEST_DEPS)
	@rm -f l_test.o l_test.obj tmp/test.exe $@
	$(call tc,cl) -Fe$(subst /,\\,$@) $<
	@rm -f l_test.o l_test.obj
ifdef DOSBOX
	cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
endif
l_test-all: tmp/l_test_vc.exe
endif
endif

ifneq ($(wildcard $(WATCOM)/binl/wcl),)
tmp/l_test_wc.%  : tc_list = method-lzma arch-i086 default
tmp/l_test_wc.exe: l_test.c $(L_TEST_DEPS)
	@rm -f l_test.o l_test.obj tmp/test.exe $@
	$(call tc,wcl) -fe=$@ $<
	@rm -f l_test.o l_test.obj
ifdef DOSBOX
	cp -p $@ tmp/test.exe && $(DOSBOX) tmp/test.exe
endif
l_test-all: tmp/l_test_wc.exe
endif

.PHONY: l_test-all

