X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=tools%2Fmake-windows-release;h=72f7608b8daf33469b89d73ca65b4209e55913e4;hb=79b438138527401cc19e4746a4454210dd4b162b;hp=39e31ed00db7a7d66f1ed37564ee3aba1ed33064;hpb=6c04f143b1c136e475bf3945bda2d9d18edad0b6;p=wimlib diff --git a/tools/make-windows-release b/tools/make-windows-release index 39e31ed0..72f7608b 100755 --- a/tools/make-windows-release +++ b/tools/make-windows-release @@ -1,129 +1,338 @@ #!/bin/bash # -# This script prepares a Windows binary distribution of wimlib on Linux using -# MinGW-w64. The desired architecture must be passed as the first argument. +# This script prepares a Windows binary distribution of wimlib. -set -e +set -e -u -if [ ! -e src/wim.c ]; then - echo "This script must be run from the toplevel directory" 1>&2 - exit 1 -fi +SCRIPTNAME="$0" +TOPDIR=$(dirname "$(dirname "$(realpath "$0")")") +cd "$TOPDIR" # Top-level directory of the git repo -if [ $# -ne 1 ]; then - echo "Usage: $0 i686|x86_64" 1>&2 - exit 1 -fi +# Global variables, read-only after parse_options has run +ARCH= +DESTDIR= +EXTRA_CONFIGURE_ARGS= +INCLUDE_DOCS=false +INSTALL_PREREQUISITES=false +MAKE="make -j$(getconf _NPROCESSORS_ONLN)" +MSYSTEM=${MSYSTEM:-} +SKIP_CONFIGURE=false +VERSION=$(tools/get-version-number) +ZIP=false +ZIPFILE= -ARCH="$1" -shift - -case "$ARCH" in -i686|x86_64) - ;; -*) - echo "ERROR: ARCH must be i686 or x86_64" 1>&2 - exit 1 - ;; -esac - -VERSION=$(grep 'AC_INIT' configure.ac | \ - grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+[^]]*') -DESTDIR=wimlib-${VERSION}-windows-${ARCH}-bin -ZIPFILE=wimlib-${VERSION}-windows-${ARCH}-bin.zip -MAKE="make -j $(grep -c processor /proc/cpuinfo)" -WINDEPDIR=./tools/windeps -SYSROOT=$WINDEPDIR/sysroot_${ARCH} - -# Prepare third party libraries - -if [ ! -e $SYSROOT ]; then - $MAKE -C $WINDEPDIR sysroot_${ARCH} -fi +PREBUILT_LLVM_MINGW_ENABLED=false +PREBUILT_LLVM_MINGW_URL=https://github.com/mstorsjo/llvm-mingw/releases/download/20230320/llvm-mingw-20230320-msvcrt-x86_64.zip +PREBUILT_LLVM_MINGW_ZIP=$(basename "$PREBUILT_LLVM_MINGW_URL") +PREBUILT_LLVM_MINGW=${PREBUILT_LLVM_MINGW_ZIP%.zip} +PREBUILT_LLVM_MINGW_BIN="/$PREBUILT_LLVM_MINGW/bin" -# Compile wimlib +usage() +{ + cat << EOF +Usage: $SCRIPTNAME [OPTION]... [EXTRA_CONFIGURE_ARG]... +Options: + --arch=ARCH Specify the CPU architecture. This is unnecessary + when using MSYS2. -if ! grep -q "./configure --host=${ARCH}-w64-mingw32" config.log || \ - ! grep -q "configure: exit 0" config.log -then - extra_args= - if [ $ARCH = x86_64 ]; then - extra_args="--enable-ssse3-sha1" - fi - # Note: putting -static-libgcc in CC is a workaround for libtool - # stripping it: - # http://www.gnu.org/software/libtool/manual/libtool.html#Stripped-link-flags - ./configure --host=${ARCH}-w64-mingw32 --disable-static \ - CC="${ARCH}-w64-mingw32-gcc -static-libgcc" \ - CFLAGS="-O2 -Wall" \ - CPPFLAGS="-I$SYSROOT/include" \ - LDFLAGS="-L$SYSROOT/lib" \ - PKG_CONFIG_PATH="$SYSROOT/lib/pkgconfig" \ - $extra_args - $MAKE clean -fi -$MAKE + --include-docs Build and install the PDF manual pages. -# Create empty destination directory + --install-prerequisites Install the prerequisite packages needed to build + wimlib. This is only supported in MSYS2. You can + omit this if you have already done this for the same + MSYS2 environment. This option normally only + installs MSYS2 packages, but for ARM64 cross-builds + it also installs a separate prebuilt toolchain. -rm -rf $DESTDIR -mkdir $DESTDIR + --skip-configure Skip running the configure script again. You can + use this to save time in incremental builds if you + are sure you didn't change any options. -# Install binaries + --zip Zip the output files up into a zip file. +EOF +} -cp .libs/*.{dll,exe} $DESTDIR -${ARCH}-w64-mingw32-strip $DESTDIR/*.{dll,exe} +parse_options() +{ + if [ -z "$MSYSTEM" ]; then + ARCH=x86_64 + else + case "$MSYSTEM" in + MINGW32) + ARCH=i686 + CC_PKG=mingw-w64-i686-gcc + ;; + MINGW64) + ARCH=x86_64 + CC_PKG=mingw-w64-x86_64-gcc + ;; + CLANG32) + ARCH=i686 + CC_PKG=mingw-w64-clang-i686-clang + ;; + CLANG64) + ARCH=x86_64 + CC_PKG=mingw-w64-clang-x86_64-clang + ;; + CLANGARM64) + ARCH=aarch64 + # MSYS2 doesn't yet support cross-compiling for ARM64, + # so use a separate prebuilt toolchain for that case. + if [ "$(uname -m)" = x86_64 ]; then + PREBUILT_LLVM_MINGW_ENABLED=true + export PATH="$PREBUILT_LLVM_MINGW_BIN:$PATH" + else + CC_PKG=mingw-w64-clang-aarch64-clang + fi + ;; + *) + echo 1>&2 "Unsupported MSYS2 environment: $MSYSTEM. This script supports" + echo 1>&2 "MINGW32, MINGW64, CLANG32, CLANG64, and CLANGARM64." + echo 1>&2 "See https://www.msys2.org/docs/environments/" + exit 1 + esac + fi -# Install text files + local longopts="help" + longopts+=",arch:" + longopts+=",include-docs" + longopts+=",install-prerequisites" + longopts+=",skip-configure" + longopts+=",zip" -cp NEWS README* COPYING* $DESTDIR -cp $WINDEPDIR/COPYING* $DESTDIR -( - cd $DESTDIR - for fil in NEWS README* COPYING*; do - sed < $fil > ${fil}.txt -e 's/$/\r/g' - rm $fil + local options + if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then + usage 1>&2 + exit 1 + fi + eval set -- "$options" + while true; do + case "$1" in + --help) + usage + exit 0 + ;; + --arch) + ARCH=$2 + shift + ;; + --include-docs) + INCLUDE_DOCS=true + ;; + --install-prerequisites) + if [ -z "$MSYSTEM" ]; then + echo 1>&2 "--install-prerequisites is only supported in MSYS2." + exit 1 + fi + INSTALL_PREREQUISITES=true + ;; + --skip-configure) + SKIP_CONFIGURE=true + ;; + --zip) + ZIP=true + ;; + --) + shift + break + ;; + *) + echo 1>&2 "Invalid option '$1'" + usage 1>&2 + exit 1 + ;; + esac + shift done -) + case "$ARCH" in + i686|x86_64|aarch64) + ;; + *) + echo 1>&2 "Unknown ARCH: $ARCH. Please specify a supported architecture with --arch" + exit 1 + ;; + esac + DESTDIR=wimlib-${VERSION}-windows-${ARCH}-bin + ZIPFILE=$DESTDIR.zip + EXTRA_CONFIGURE_ARGS=("$@") +} +install_prebuilt_llvm_mingw() +{ + if [ -e "$PREBUILT_LLVM_MINGW_BIN" ]; then + echo "Prebuilt $PREBUILT_LLVM_MINGW is already installed" + return + fi + echo "Downloading $PREBUILT_LLVM_MINGW_ZIP..." + wget "$PREBUILT_LLVM_MINGW_URL" -O "/$PREBUILT_LLVM_MINGW_ZIP" + echo "Unzipping $PREBUILT_LLVM_MINGW_ZIP..." + unzip "/$PREBUILT_LLVM_MINGW_ZIP" -d / + if [ ! -e "$PREBUILT_LLVM_MINGW_BIN" ]; then + echo 1>&2 "$PREBUILT_LLVM_MINGW_BIN not found after unzip" + exit 1 + fi + echo "Done installing prebuilt toolchain $PREBUILT_LLVM_MINGW" +} -# Install man pages +install_prerequisites() +{ + echo "Installing the MSYS2 $MSYSTEM packages needed to build wimlib..." + local packages=(autoconf automake git libtool make pkgconf) + if "$PREBUILT_LLVM_MINGW_ENABLED"; then + echo "Will use prebuilt toolchain instead of MSYS2 one" + packages+=(wget unzip) + else + packages+=("$CC_PKG") + fi + pacman -Syu --noconfirm --needed "${packages[@]}" + echo "Done installing the MSYS2 $MSYSTEM packages needed to build wimlib." -mkdir $DESTDIR/doc + if $PREBUILT_LLVM_MINGW_ENABLED; then + install_prebuilt_llvm_mingw + fi +} -function gen_pdf_from_man_page() { - local manbase=$1 - local pdf=${DESTDIR}/doc/${manbase}.pdf +bootstrap_repository() +{ + echo "Bootstrapping the wimlib repository..." + ./bootstrap +} - echo "Generating $pdf" +configure_wimlib() +{ + echo "Configuring wimlib..." + local configure_args=("--host=${ARCH}-w64-mingw32") + configure_args+=("--disable-static") + # -static-libgcc is needed with gcc. It should go in the CFLAGS, but + # libtool strips it, so it must go directly in CC instead. See + # http://www.gnu.org/software/libtool/manual/libtool.html#Stripped-link-flags + local cc="${ARCH}-w64-mingw32-cc" + if ! type -P "$cc" &>/dev/null; then + cc="${ARCH}-w64-mingw32-gcc" + fi + if "$cc" --version | grep -q '(GCC)'; then + configure_args+=("CC=$cc -static-libgcc") + fi + configure_args+=("${EXTRA_CONFIGURE_ARGS[@]}") + ./configure "${configure_args[@]}" + $MAKE clean +} + +build_wimlib() +{ + echo "Building wimlib..." + $MAKE +} + +list_imagex_commands() +{ + for cmd in ./doc/man1/wim*.1; do + local cmd=${cmd##*/} + cmd=${cmd%.1} + case "$cmd" in + wimlib-imagex|wimmount|wimmountrw|wimunmount) + ;; + *) + echo "$cmd" + ;; + esac + done +} - MANPATH="./doc" man -t $manbase | ps2pdf - $pdf +install_binaries() +{ + echo "Installing binaries..." + cp .libs/*.{dll,exe} "$DESTDIR" + strip "$DESTDIR"/*.{dll,exe} } -for fil in ./doc/man1/wimlib-imagex-*.1; do - manbase=`basename $fil` - manbase=${manbase%%.1} - cmd=$(echo $manbase | sed s/wimlib-imagex-//) - if [ $cmd == mount -o $cmd == mountrw -o $cmd == unmount ]; then - continue +install_text_files() +{ + echo "Installing NEWS, README, and licenses..." + cp NEWS README* COPYING* "$DESTDIR" + sed -n '/^#/q; s/^[\/\* ]*//; p' src/divsufsort.c > "$DESTDIR"/COPYING.libdivsufsort-lite + if ! grep -q 'Copyright' "$DESTDIR"/COPYING.libdivsufsort-lite; then + echo 1>&2 "ERROR: failed to extract libdivsufsort-lite license text" + exit 1 fi + cd "$DESTDIR" + for fil in NEWS README* COPYING*; do + sed < "$fil" > "${fil}".txt -e 's/$/\r/g' + rm "$fil" + done + cd .. +} + +gen_pdf_from_man_page() +{ + local cmd=$1 + local pdf=${DESTDIR}/doc/${cmd}.pdf + + echo "Generating $pdf" + MANPATH="./doc" man -t "$cmd" | ps2pdf - "$pdf" +} - gen_pdf_from_man_page $manbase +install_pdf_docs() +{ + echo "Installing PDF manual pages..." + mkdir "$DESTDIR"/doc + for cmd in $(list_imagex_commands); do + gen_pdf_from_man_page "$cmd" + done + gen_pdf_from_man_page wimlib-imagex +} - sed 's/$/\r/g' > ${DESTDIR}/wim${cmd}.cmd <<- EOF - @echo off - %~dp0\\wimlib-imagex $cmd %* - EOF - chmod +x ${DESTDIR}/wim${cmd}.cmd -done +install_cmd_aliases() +{ + echo "Installing wim*.cmd files..." + for cmd in $(list_imagex_commands); do + sed 's/$/\r/g' > "${DESTDIR}/${cmd}.cmd" <<- EOF + @echo off + "%~dp0\\wimlib-imagex" ${cmd#wim} %* + EOF + chmod +x "${DESTDIR}/${cmd}.cmd" + done +} -gen_pdf_from_man_page wimlib-imagex +install_development_files() +{ + echo "Installing development files..." + mkdir "$DESTDIR"/devel + cp .libs/libwim.dll.a "$DESTDIR"/devel/libwim.lib + cp include/wimlib.h "$DESTDIR"/devel/ +} -# Generate ZIP file +create_zip_file() +{ + echo "Creating zip file..." + cd "$DESTDIR" + 7z -mx9 a ../"$ZIPFILE" . > /dev/null + cd .. +} -rm -f $ZIPFILE -( - dir=$PWD - cd $DESTDIR - 7z -mx9 a "$dir/$ZIPFILE" . -) +parse_options "$@" +rm -rf -- "$DESTDIR" "$ZIPFILE" +mkdir -- "$DESTDIR" +if $INSTALL_PREREQUISITES; then + install_prerequisites +fi +if [ ! -e configure ]; then + bootstrap_repository +fi +if [ ! -e config.log ] || ! $SKIP_CONFIGURE; then + configure_wimlib +fi +build_wimlib +install_binaries +install_text_files +if $INCLUDE_DOCS; then + install_pdf_docs +fi +install_cmd_aliases +install_development_files +if $ZIP; then + create_zip_file + echo "Success! Output is in $ZIPFILE" +else + echo "Success! Output is in $DESTDIR" +fi