1#!/bin/bash
2#
3###############################################################################
4#
5# Build a binary package on Windows with MinGW and MSYS
6#
7# Set the paths where MinGW, Mingw-w32, or MinGW-w64 are installed. If both
8# MinGW and MinGW-w32 are specified, MinGW-w32 will be used. If there is no
9# 32-bit or 64-bit compiler at all, it is simply skipped.
10#
11# Optionally, 7-Zip is used to create the final .zip and .7z packages.
12# If you have installed it in the default directory, this script should
13# find it automatically. Otherwise adjust the path manually.
14#
15# If you want to use a cross-compiler e.g. on GNU/Linux, this script won't
16# work out of the box. You need to omit "make check" commands and replace
17# u2d with some other tool to convert newlines from LF to CR+LF. You will
18# also need to pass the --host option to configure.
19#
20###############################################################################
21#
22# Author: Lasse Collin
23#
24# This file has been put into the public domain.
25# You can do whatever you want with this file.
26#
27###############################################################################
28
29MINGW_DIR=/c/devel/tools/mingw
30MINGW_W32_DIR=/c/devel/tools/mingw-w32
31MINGW_W64_DIR=/c/devel/tools/mingw-w64
32
33for SEVENZ_EXE in "$PROGRAMW6432/7-Zip/7z.exe" "$PROGRAMFILES/7-Zip/7z.exe" \
34		"/c/Program Files/7-Zip/7z.exe"
35do
36	[ -x "$SEVENZ_EXE" ] && break
37done
38
39
40# Abort immediately if something goes wrong.
41set -e
42
43# White spaces in directory names may break things so catch them immediately.
44case $(pwd) in
45	' ' | '	' | '
46') echo "Error: White space in the directory name" >&2; exit 1 ;;
47esac
48
49# This script can be run either at the top-level directory of the package
50# or in the same directory containing this script.
51if [ ! -f windows/build.bash ]; then
52	cd ..
53	if [ ! -f windows/build.bash ]; then
54		echo "You are in a wrong directory." >&2
55		exit 1
56	fi
57fi
58
59# Run configure and copy the binaries to the given directory.
60#
61# The first argument is the directory where to copy the binaries.
62# The rest of the arguments are passed to configure.
63buildit()
64{
65	DESTDIR=$1
66	BUILD=$2
67	CFLAGS=$3
68
69	# Clean up if it was already configured.
70	[ -f Makefile ] && make distclean
71
72	# Build the size-optimized binaries. Note that I don't want to
73	# provide size-optimized liblzma (shared nor static), because
74	# that isn't thread-safe now, and depending on bunch of things,
75	# maybe it will never be on Windows (pthreads-win32 helps but
76	# static liblzma might bit a bit tricky with it).
77	./configure \
78		--prefix= \
79		--disable-nls \
80		--disable-threads \
81		--disable-shared \
82		--enable-small \
83		--build="$BUILD" \
84		CFLAGS="$CFLAGS -Os"
85	make check
86
87	mkdir -pv "$DESTDIR"
88	cp -v src/xzdec/{xz,lzma}dec.exe src/lzmainfo/lzmainfo.exe "$DESTDIR"
89
90	make distclean
91
92	# Build the normal speed-optimized binaries. Note that while
93	# --disable-threads has been documented to make some things
94	# thread-unsafe, it's not actually true with this combination
95	# of configure flags in XZ Utils 5.0.x. Things can (and probably
96	# will) change after 5.0.x, and this script will be updated too.
97	./configure \
98		--prefix= \
99		--disable-nls \
100		--disable-threads \
101		--build="$BUILD" \
102		CFLAGS="$CFLAGS -O2"
103	make -C src/liblzma
104	make -C src/xz LDFLAGS=-static
105	make -C tests check
106
107	cp -v src/xz/xz.exe src/liblzma/.libs/liblzma.a "$DESTDIR"
108	cp -v src/liblzma/.libs/liblzma-*.dll "$DESTDIR/liblzma.dll"
109
110	strip -v "$DESTDIR/"*.{exe,dll}
111	strip -vg "$DESTDIR/"*.a
112}
113
114# Copy files and convert newlines from LF to CR+LF. Optinally add a suffix
115# to the destination filename.
116#
117# The first argument is the destination directory. The second argument is
118# the suffix to append to the filenames; use empty string if no extra suffix
119# is wanted. The rest of the arguments are actual the filenames.
120txtcp()
121{
122	DESTDIR=$1
123	SUFFIX=$2
124	shift 2
125	for SRCFILE; do
126		DESTFILE="$DESTDIR/${SRCFILE##*/}$SUFFIX"
127		echo "Converting \`$SRCFILE' -> \`$DESTFILE'"
128		u2d < "$SRCFILE" > "$DESTFILE"
129	done
130}
131
132# FIXME: Make sure that we don't get i686 or i586 code from the runtime.
133# Actually i586 would be fine, but i686 probably not if the idea is to
134# support even Win95.
135#
136# FIXME: Using i486 in the configure triplet may be wrong.
137if [ -d "$MINGW_W32_DIR" ]; then
138	# 32-bit x86, Win95 or later, using MinGW-w32
139	PATH=$MINGW_W32_DIR/bin:$MINGW_W32_DIR/i686-w64-mingw32/bin:$PATH \
140			buildit \
141			pkg/bin_i486 \
142			i486-w64-mingw32 \
143			'-march=i486 -mtune=generic'
144elif [ -d "$MINGW_DIR" ]; then
145	# 32-bit x86, Win95 or later, using MinGW
146	PATH=$MINGW_DIR/bin:$PATH \
147			buildit \
148			pkg/bin_i486 \
149			i486-pc-mingw32 \
150			'-march=i486 -mtune=generic'
151fi
152
153if [ -d "$MINGW_W64_DIR" ]; then
154	# 64-bit x86, WinXP or later, using MinGW-w64
155	PATH=$MINGW_W64_DIR/bin:$MINGW_W64_DIR/x86_64-w64-mingw32/bin:$PATH \
156			buildit \
157			pkg/bin_x86-64 \
158			x86_64-w64-mingw32 \
159			'-march=x86-64 -mtune=generic'
160fi
161
162# Copy the headers, the .def file, and the docs.
163# They are the same for all architectures and builds.
164mkdir -pv pkg/{include/lzma,doc/{manuals,examples}}
165txtcp pkg/include "" src/liblzma/api/lzma.h
166txtcp pkg/include/lzma "" src/liblzma/api/lzma/*.h
167txtcp pkg/doc "" src/liblzma/liblzma.def
168txtcp pkg/doc .txt AUTHORS COPYING NEWS README THANKS TODO
169txtcp pkg/doc "" doc/*.txt windows/README-Windows.txt
170txtcp pkg/doc/manuals "" doc/man/txt/{xz,xzdec,lzmainfo}.txt
171cp -v doc/man/pdf-*/{xz,xzdec,lzmainfo}-*.pdf pkg/doc/manuals
172txtcp pkg/doc/examples "" doc/examples/*
173
174if [ -f windows/COPYING-Windows.txt ]; then
175	txtcp pkg/doc "" windows/COPYING-Windows.txt
176fi
177
178# Create the package. This requires 7z.exe from 7-Zip. If it wasn't found,
179# this step is skipped and you have to zip it yourself.
180VER=$(sh build-aux/version.sh)
181cd pkg
182if [ -x "$SEVENZ_EXE" ]; then
183	"$SEVENZ_EXE" a -tzip ../xz-$VER-windows.zip *
184	"$SEVENZ_EXE" a ../xz-$VER-windows.7z *
185else
186	echo
187	echo "NOTE: 7z.exe was not found. xz-$VER-windows.zip"
188	echo "      and xz-$VER-windows.7z were not created."
189	echo "      You can create them yourself from the pkg directory."
190fi
191
192if [ ! -f ../windows/COPYING-Windows.txt ]; then
193	echo
194	echo "NOTE: windows/COPYING-Windows.txt doesn't exists."
195	echo "      MinGW(-w64) runtime copyright information"
196	echo "      is not included in the package."
197fi
198
199echo
200echo "Build completed successfully."
201echo
202