3 # This script prepares a Windows binary distribution of wimlib.
8 TOPDIR=$(dirname "$(dirname "$(realpath "$0")")")
9 cd "$TOPDIR" # Top-level directory of the git repo
11 # Global variables, read-only after parse_options has run
16 INSTALL_PREREQUISITES=false
17 MAKE="make -j$(getconf _NPROCESSORS_ONLN)"
20 VERSION=$(tools/get-version-number)
24 PREBUILT_LLVM_MINGW_ENABLED=false
25 PREBUILT_LLVM_MINGW_URL=https://github.com/mstorsjo/llvm-mingw/releases/download/20230320/llvm-mingw-20230320-msvcrt-x86_64.zip
26 PREBUILT_LLVM_MINGW_ZIP=$(basename "$PREBUILT_LLVM_MINGW_URL")
27 PREBUILT_LLVM_MINGW=${PREBUILT_LLVM_MINGW_ZIP%.zip}
28 PREBUILT_LLVM_MINGW_BIN="/$PREBUILT_LLVM_MINGW/bin"
33 Usage: $SCRIPTNAME [OPTION]... [EXTRA_CONFIGURE_ARG]...
35 --arch=ARCH Specify the CPU architecture. This is unnecessary
38 --include-docs Build and install the PDF manual pages.
40 --install-prerequisites Install the prerequisite packages needed to build
41 wimlib. This is only supported in MSYS2. You can
42 omit this if you have already done this for the same
43 MSYS2 environment. This option normally only
44 installs MSYS2 packages, but for ARM64 cross-builds
45 it also installs a separate prebuilt toolchain.
47 --skip-configure Skip running the configure script again. You can
48 use this to save time in incremental builds if you
49 are sure you didn't change any options.
51 --zip Zip the output files up into a zip file.
57 if [ -z "$MSYSTEM" ]; then
63 CC_PKG=mingw-w64-i686-gcc
67 CC_PKG=mingw-w64-x86_64-gcc
71 CC_PKG=mingw-w64-clang-i686-clang
75 CC_PKG=mingw-w64-clang-x86_64-clang
79 # MSYS2 doesn't yet support cross-compiling for ARM64,
80 # so use a separate prebuilt toolchain for that case.
81 if [ "$(uname -m)" = x86_64 ]; then
82 PREBUILT_LLVM_MINGW_ENABLED=true
83 export PATH="$PREBUILT_LLVM_MINGW_BIN:$PATH"
85 CC_PKG=mingw-w64-clang-aarch64-clang
89 echo 1>&2 "Unsupported MSYS2 environment: $MSYSTEM. This script supports"
90 echo 1>&2 "MINGW32, MINGW64, CLANG32, CLANG64, and CLANGARM64."
91 echo 1>&2 "See https://www.msys2.org/docs/environments/"
98 longopts+=",include-docs"
99 longopts+=",install-prerequisites"
100 longopts+=",skip-configure"
104 if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then
108 eval set -- "$options"
122 --install-prerequisites)
123 if [ -z "$MSYSTEM" ]; then
124 echo 1>&2 "--install-prerequisites is only supported in MSYS2."
127 INSTALL_PREREQUISITES=true
140 echo 1>&2 "Invalid option '$1'"
151 echo 1>&2 "Unknown ARCH: $ARCH. Please specify a supported architecture with --arch"
155 DESTDIR=wimlib-${VERSION}-windows-${ARCH}-bin
157 EXTRA_CONFIGURE_ARGS=("$@")
160 install_prebuilt_llvm_mingw()
162 if [ -e "$PREBUILT_LLVM_MINGW_BIN" ]; then
163 echo "Prebuilt $PREBUILT_LLVM_MINGW is already installed"
166 echo "Downloading $PREBUILT_LLVM_MINGW_ZIP..."
167 wget "$PREBUILT_LLVM_MINGW_URL" -O "/$PREBUILT_LLVM_MINGW_ZIP"
168 echo "Unzipping $PREBUILT_LLVM_MINGW_ZIP..."
169 unzip "/$PREBUILT_LLVM_MINGW_ZIP" -d /
170 if [ ! -e "$PREBUILT_LLVM_MINGW_BIN" ]; then
171 echo 1>&2 "$PREBUILT_LLVM_MINGW_BIN not found after unzip"
174 echo "Done installing prebuilt toolchain $PREBUILT_LLVM_MINGW"
177 install_prerequisites()
179 echo "Installing the MSYS2 $MSYSTEM packages needed to build wimlib..."
180 local packages=(autoconf automake git libtool make pkgconf)
181 if "$PREBUILT_LLVM_MINGW_ENABLED"; then
182 echo "Will use prebuilt toolchain instead of MSYS2 one"
183 packages+=(wget unzip)
185 packages+=("$CC_PKG")
187 pacman -Syu --noconfirm --needed "${packages[@]}"
188 echo "Done installing the MSYS2 $MSYSTEM packages needed to build wimlib."
190 if $PREBUILT_LLVM_MINGW_ENABLED; then
191 install_prebuilt_llvm_mingw
195 bootstrap_repository()
197 echo "Bootstrapping the wimlib repository..."
203 echo "Configuring wimlib..."
204 local configure_args=("--host=${ARCH}-w64-mingw32")
205 configure_args+=("--disable-static")
206 # -static-libgcc is needed with gcc. It should go in the CFLAGS, but
207 # libtool strips it, so it must go directly in CC instead. See
208 # http://www.gnu.org/software/libtool/manual/libtool.html#Stripped-link-flags
209 local cc="${ARCH}-w64-mingw32-cc"
210 if ! type -P "$cc" &>/dev/null; then
211 cc="${ARCH}-w64-mingw32-gcc"
213 if "$cc" --version | grep -q '(GCC)'; then
214 configure_args+=("CC=$cc -static-libgcc")
216 configure_args+=("${EXTRA_CONFIGURE_ARGS[@]}")
217 ./configure "${configure_args[@]}"
223 echo "Building wimlib..."
227 list_imagex_commands()
229 for cmd in ./doc/man1/wim*.1; do
233 wimlib-imagex|wimmount|wimmountrw|wimunmount)
244 echo "Installing binaries..."
245 cp .libs/*.{dll,exe} "$DESTDIR"
246 strip "$DESTDIR"/*.{dll,exe}
251 echo "Installing NEWS, README, and licenses..."
252 cp NEWS README* COPYING* "$DESTDIR"
253 sed -n '/^#/q; s/^[\/\* ]*//; p' src/divsufsort.c > "$DESTDIR"/COPYING.libdivsufsort-lite
254 if ! grep -q 'Copyright' "$DESTDIR"/COPYING.libdivsufsort-lite; then
255 echo 1>&2 "ERROR: failed to extract libdivsufsort-lite license text"
259 for fil in NEWS README* COPYING*; do
260 sed < "$fil" > "${fil}".txt -e 's/$/\r/g'
266 gen_pdf_from_man_page()
269 local pdf=${DESTDIR}/doc/${cmd}.pdf
271 echo "Generating $pdf"
272 MANPATH="./doc" man -t "$cmd" | ps2pdf - "$pdf"
277 echo "Installing PDF manual pages..."
279 for cmd in $(list_imagex_commands); do
280 gen_pdf_from_man_page "$cmd"
282 gen_pdf_from_man_page wimlib-imagex
285 install_cmd_aliases()
287 echo "Installing wim*.cmd files..."
288 for cmd in $(list_imagex_commands); do
289 sed 's/$/\r/g' > "${DESTDIR}/${cmd}.cmd" <<- EOF
291 "%~dp0\\wimlib-imagex" ${cmd#wim} %*
293 chmod +x "${DESTDIR}/${cmd}.cmd"
297 install_development_files()
299 echo "Installing development files..."
300 mkdir "$DESTDIR"/devel
301 cp .libs/libwim.dll.a "$DESTDIR"/devel/libwim.lib
302 cp include/wimlib.h "$DESTDIR"/devel/
307 echo "Creating zip file..."
309 7z -mx9 a ../"$ZIPFILE" . > /dev/null
314 rm -rf -- "$DESTDIR" "$ZIPFILE"
316 if $INSTALL_PREREQUISITES; then
317 install_prerequisites
319 if [ ! -e configure ]; then
322 if [ ! -e config.log ] || ! $SKIP_CONFIGURE; then
328 if $INCLUDE_DOCS; then
332 install_development_files
335 echo "Success! Output is in $ZIPFILE"
337 echo "Success! Output is in $DESTDIR"