aboutsummaryrefslogtreecommitdiff
path: root/windows
diff options
context:
space:
mode:
Diffstat (limited to 'windows')
-rw-r--r--windows/build.bash191
1 files changed, 112 insertions, 79 deletions
diff --git a/windows/build.bash b/windows/build.bash
index 5ae93a2e..b4d3dc7b 100644
--- a/windows/build.bash
+++ b/windows/build.bash
@@ -3,20 +3,27 @@
###############################################################################
#
-# Build a binary package on Windows with MinGW and MSYS
+# This build a XZ Utils binary package using the GNU Autotools build system
#
-# Set the paths where MinGW, Mingw-w32, or MinGW-w64 are installed. If both
-# MinGW and MinGW-w32 are specified, MinGW-w32 will be used. If there is no
-# 32-bit or 64-bit compiler at all, it is simply skipped.
+# NOTE: This requires files that are generated as part of "make mydist".
+# So if building from xz.git, create a distribution tarball first,
+# extract it, and run this script from there.
+#
+# These were tested and known to work:
+# - Cross-compilation with MinGW-w64 v10.0.0 and GCC 12.2.0 from
+# GNU/Linux ("make check" will be skipped)
+# - MSYS2 with MinGW-w64 and GCC
+# - MSYS 1.0.11 (from 2009) with MinGW-w64 v11.0.0 and GCC 13.1.0
#
# Optionally, 7-Zip is used to create the final .zip and .7z packages.
-# If you have installed it in the default directory, this script should
-# find it automatically. Otherwise adjust the path manually.
+# If the 7z tool is in PATH or if you have installed it in the default
+# directory on Windows, this script should find it automatically.
+#
+# Before running this script, copy COPYING.MinGW-w64-runtime.txt to
+# the 'windows' directory.
#
-# If you want to use a cross-compiler e.g. on GNU/Linux, this script won't
-# work out of the box. You need to omit "make check" commands and replace
-# u2d with some other tool to convert newlines from LF to CR+LF. You will
-# also need to pass the --host option to configure.
+# NOTE: MinGW-w64 includes getopt_long(). The GNU getopt_long() (LGPLv2.1)
+# included in XZ Utils isn't used when building with MinGW-w64.
#
###############################################################################
#
@@ -24,17 +31,6 @@
#
###############################################################################
-MINGW_DIR=/c/devel/tools/mingw
-MINGW_W32_DIR=/c/devel/tools/mingw-w32
-MINGW_W64_DIR=/c/devel/tools/mingw-w64
-
-for SEVENZ_EXE in "$PROGRAMW6432/7-Zip/7z.exe" "$PROGRAMFILES/7-Zip/7z.exe" \
- "/c/Program Files/7-Zip/7z.exe"
-do
- [ -x "$SEVENZ_EXE" ] && break
-done
-
-
# Abort immediately if something goes wrong.
set -e
@@ -49,11 +45,34 @@ esac
if [ ! -f windows/build.bash ]; then
cd ..
if [ ! -f windows/build.bash ]; then
- echo "You are in a wrong directory." >&2
+ echo "ERROR: You are in a wrong directory. This script" >&2
+ echo "can be run either at the top-level directory of" >&2
+ echo "the package or in the same directory containing" >&2
+ echo "this script." >&2
exit 1
fi
fi
+# COPYING.MinGW-w64-runtime.txt needs to be manually copied from MinGW-w64.
+if [ ! -f windows/COPYING.MinGW-w64-runtime.txt ]; then
+ echo "ERROR: The file 'windows/COPYING.MinGW-w64-runtime.txt'" >&2
+ echo "doesn't exists. Copy it from MinGW-w64 so that the" >&2
+ echo "copyright and license notices of the MinGW-w64 runtime" >&2
+ echo "can be included in the package." >&2
+ echo "(Or create an empty file if only doing a test build.)" >&2
+ exit 1
+fi
+
+# Number of jobs for "make":
+MAKE_JOBS=$(nproc 2> /dev/null || echo 1)
+
+# "make check" has to be skipped when cross-compiling.
+if [ "x$(uname -o)" = xMsys ]; then
+ IS_NATIVE_BUILD=true
+else
+ IS_NATIVE_BUILD=false
+fi
+
# Run configure and copy the binaries to the given directory.
#
# The first argument is the directory where to copy the binaries.
@@ -61,9 +80,26 @@ fi
buildit()
{
DESTDIR=$1
- BUILD=$2
+ TRIPLET=$2
CFLAGS=$3
+ # In the MinGW-w64 + GCC toolchains running natively on Windows,
+ # $TRIPLET-windres and $TRIPLET-strip commands might not exist.
+ # Only the short names "windres" and "strip" might be available.
+ # If both i686 and x86_64 toolchains are in PATH, wrong windres.exe
+ # will be used for one of the builds, making the build fail. The
+ # workaround is to put the directory of $TRIPLET-gcc to the front
+ # of PATH if $TRIPLET-windres or $TRIPLET-strip is missing.
+ OLD_PATH=$PATH
+ if type -P "$TRIPLET-windres" > /dev/null \
+ && type -P "$TRIPLET-strip" > /dev/null; then
+ STRIP=$TRIPLET-strip
+ else
+ STRIP=strip
+ GCC_DIR=$(type -P "$TRIPLET-gcc")
+ PATH=${GCC_DIR%/*}:$PATH
+ fi
+
# Clean up if it was already configured.
[ -f Makefile ] && make distclean
@@ -80,9 +116,13 @@ buildit()
--disable-threads \
--disable-shared \
--enable-small \
- --build="$BUILD" \
+ --host="$TRIPLET" \
CFLAGS="$CFLAGS -Os"
- make check
+ make -j"$MAKE_JOBS"
+
+ if "$IS_NATIVE_BUILD"; then
+ make -j"$MAKE_JOBS" check
+ fi
mkdir -pv "$DESTDIR"
cp -v src/xzdec/{xz,lzma}dec.exe src/lzmainfo/lzmainfo.exe "$DESTDIR"
@@ -97,17 +137,20 @@ buildit()
--disable-dependency-tracking \
--disable-nls \
--disable-scripts \
- --build="$BUILD" \
+ --host="$TRIPLET" \
CFLAGS="$CFLAGS -O2"
- make -C src/liblzma
- make -C src/xz LDFLAGS=-static
- make -C tests check
+ make -j"$MAKE_JOBS" -C src/liblzma
+ make -j"$MAKE_JOBS" -C src/xz LDFLAGS=-static
+
+ if "$IS_NATIVE_BUILD"; then
+ make -j"$MAKE_JOBS" -C tests check
+ fi
- cp -v src/xz/xz.exe src/liblzma/.libs/liblzma.a "$DESTDIR"
- cp -v src/liblzma/.libs/liblzma-*.dll "$DESTDIR/liblzma.dll"
+ cp -v src/xz/xz.exe "$DESTDIR"
+ cp -v src/liblzma/.libs/liblzma-5.dll "$DESTDIR/liblzma.dll"
+ "$STRIP" -v "$DESTDIR/"*.{exe,dll}
- strip -v "$DESTDIR/"*.{exe,dll}
- strip -vg "$DESTDIR/"*.a
+ PATH=$OLD_PATH
}
# Copy files and convert newlines from LF to CR+LF. Optionally add a suffix
@@ -115,7 +158,7 @@ buildit()
#
# The first argument is the destination directory. The second argument is
# the suffix to append to the filenames; use empty string if no extra suffix
-# is wanted. The rest of the arguments are actual the filenames.
+# is wanted. The rest of the arguments are the actual filenames.
txtcp()
{
DESTDIR=$1
@@ -124,39 +167,32 @@ txtcp()
for SRCFILE; do
DESTFILE="$DESTDIR/${SRCFILE##*/}$SUFFIX"
echo "Converting '$SRCFILE' -> '$DESTFILE'"
- u2d < "$SRCFILE" > "$DESTFILE"
+ sed s/\$/$'\r'/ < "$SRCFILE" > "$DESTFILE"
done
}
-if [ -d "$MINGW_W32_DIR" ]; then
- # 32-bit x86, Win2k or later, using MinGW-w32
- PATH=$MINGW_W32_DIR/bin:$MINGW_W32_DIR/i686-w64-mingw32/bin:$PATH \
- buildit \
- pkg/bin_i686 \
- i686-w64-mingw32 \
+if type -P i686-w64-mingw32-gcc > /dev/null; then
+ # 32-bit x86, Win2k or later
+ buildit pkg/bin_i686 i686-w64-mingw32 \
'-march=i686 -mtune=generic'
- # 32-bit x86 with SSE2, Win2k or later, using MinGW-w32
- PATH=$MINGW_W32_DIR/bin:$MINGW_W32_DIR/i686-w64-mingw32/bin:$PATH \
- buildit \
- pkg/bin_i686-sse2 \
- i686-w64-mingw32 \
- '-march=i686 -msse2 -mfpmath=sse -mtune=generic'
-elif [ -d "$MINGW_DIR" ]; then
- # 32-bit x86, Win2k or later, using MinGW
- PATH=$MINGW_DIR/bin:$PATH \
- buildit \
- pkg/bin_i486 \
- i486-pc-mingw32 \
- '-march=i486 -mtune=generic'
+
+ # 32-bit x86 with SSE2, Win2k or later
+ buildit pkg/bin_i686-sse2 i686-w64-mingw32 \
+ '-march=i686 -msse2 -mtune=generic'
+else
+ echo
+ echo "i686-w64-mingw32-gcc is not in PATH, skipping 32-bit x86 builds"
+ echo
fi
-if [ -d "$MINGW_W64_DIR" ]; then
- # x86-64, Windows Vista or later, using MinGW-w64
- PATH=$MINGW_W64_DIR/bin:$MINGW_W64_DIR/x86_64-w64-mingw32/bin:$PATH \
- buildit \
- pkg/bin_x86-64 \
- x86_64-w64-mingw32 \
+if type -P x86_64-w64-mingw32-gcc > /dev/null; then
+ # x86-64, Windows Vista or later
+ buildit pkg/bin_x86-64 x86_64-w64-mingw32 \
'-march=x86-64 -mtune=generic'
+else
+ echo
+ echo "x86_64-w64-mingw32-gcc is not in PATH, skipping x86-64 build"
+ echo
fi
# Copy the headers, the .def file, and the docs.
@@ -165,38 +201,35 @@ mkdir -pv pkg/{include/lzma,doc/{api,manuals,examples}}
txtcp pkg/include "" src/liblzma/api/lzma.h
txtcp pkg/include/lzma "" src/liblzma/api/lzma/*.h
txtcp pkg/doc "" src/liblzma/liblzma.def
-txtcp pkg/doc .txt AUTHORS COPYING NEWS README THANKS TODO
+txtcp pkg/doc .txt AUTHORS COPYING NEWS README THANKS
txtcp pkg/doc "" doc/*.txt windows/README-Windows.txt
+txtcp pkg/doc "" windows/COPYING.MinGW-w64-runtime.txt
txtcp pkg/doc/manuals "" doc/man/txt/{xz,xzdec,lzmainfo}.txt
cp -v doc/man/pdf-*/{xz,xzdec,lzmainfo}-*.pdf pkg/doc/manuals
cp -v doc/api/* pkg/doc/api
txtcp pkg/doc/examples "" doc/examples/*
-if [ -f windows/COPYING-Windows.txt ]; then
- txtcp pkg/doc "" windows/COPYING-Windows.txt
-fi
+# Create the package. This requires 7z from 7-Zip.
+# If it isn't found, this step is skipped.
+for SEVENZ in "$(type -P 7z || true)" \
+ "$PROGRAMW6432/7-Zip/7z.exe" "$PROGRAMFILES/7-Zip/7z.exe" \
+ "/c/Program Files/7-Zip/7z.exe"
+do
+ [ -x "$SEVENZ" ] && break
+done
-# Create the package. This requires 7z.exe from 7-Zip. If it wasn't found,
-# this step is skipped and you have to zip it yourself.
-VER=$(sh build-aux/version.sh)
-cd pkg
-if [ -x "$SEVENZ_EXE" ]; then
- "$SEVENZ_EXE" a -tzip ../xz-$VER-windows.zip *
- "$SEVENZ_EXE" a ../xz-$VER-windows.7z *
+if [ -x "$SEVENZ" ]; then
+ VER=$(sh build-aux/version.sh)
+ cd pkg
+ "$SEVENZ" a -tzip ../xz-$VER-windows.zip *
+ "$SEVENZ" a ../xz-$VER-windows.7z *
else
echo
- echo "NOTE: 7z.exe was not found. xz-$VER-windows.zip"
+ echo "NOTE: 7z was not found. xz-$VER-windows.zip"
echo " and xz-$VER-windows.7z were not created."
echo " You can create them yourself from the pkg directory."
fi
-if [ ! -f ../windows/COPYING-Windows.txt ]; then
- echo
- echo "NOTE: windows/COPYING-Windows.txt doesn't exists."
- echo " MinGW(-w64) runtime copyright information"
- echo " is not included in the package."
-fi
-
echo
echo "Build completed successfully."
echo