#!/bin/bash # SPDX-License-Identifier: 0BSD ############################################################################### # # This build a XZ Utils binary package using the GNU Autotools build system # # 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 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. # # NOTE: MinGW-w64 includes getopt_long(). The GNU getopt_long() (LGPLv2.1) # included in XZ Utils isn't used when building with MinGW-w64. # ############################################################################### # # Author: Lasse Collin # ############################################################################### # Abort immediately if something goes wrong. set -e # White spaces in directory names may break things so catch them immediately. case $(pwd) in ' ' | ' ' | ' ') echo "Error: White space in the directory name" >&2; exit 1 ;; esac # This script can be run either at the top-level directory of the package # or in the same directory containing this script. if [ ! -f windows/build.bash ]; then cd .. if [ ! -f windows/build.bash ]; then 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. # The rest of the arguments are passed to configure. buildit() { DESTDIR=$1 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 # Build the size-optimized binaries. Providing size-optimized liblzma # could be considered but I don't know if it should only use -Os or # should it also use --enable-small and if it should support # threading. So I don't include a size-optimized liblzma for now. ./configure \ --prefix= \ --enable-silent-rules \ --disable-dependency-tracking \ --disable-nls \ --disable-scripts \ --disable-threads \ --disable-shared \ --enable-small \ --host="$TRIPLET" \ CFLAGS="$CFLAGS -Os" 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" make distclean # Build the normal speed-optimized binaries. The type of threading # (win95 vs. vista) will be autodetect from the target architecture. ./configure \ --prefix= \ --enable-silent-rules \ --disable-dependency-tracking \ --disable-nls \ --disable-scripts \ --host="$TRIPLET" \ CFLAGS="$CFLAGS -O2" 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 "$DESTDIR" cp -v src/liblzma/.libs/liblzma-5.dll "$DESTDIR/liblzma.dll" "$STRIP" -v "$DESTDIR/"*.{exe,dll} PATH=$OLD_PATH } # Copy files and convert newlines from LF to CR+LF. Optionally add a suffix # to the destination filename. # # 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 the actual filenames. txtcp() { DESTDIR=$1 SUFFIX=$2 shift 2 for SRCFILE; do DESTFILE="$DESTDIR/${SRCFILE##*/}$SUFFIX" echo "Converting '$SRCFILE' -> '$DESTFILE'" sed s/\$/$'\r'/ < "$SRCFILE" > "$DESTFILE" done } 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 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 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. # They are the same for all architectures and builds. 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 COPYING.0BSD NEWS README THANKS txtcp pkg/doc "" doc/*.txt \ windows/README-Windows.txt \ windows/liblzma-crt-mixing.txt \ 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/* # 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 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 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 echo echo "Build completed successfully." echo