3 # This script builds wimlib for Windows. It supports both MSYS2 and Linux.
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 ! type -P "$cc" &>/dev/null; then
214 echo 1>&2 "ERROR: $cc not found!"
215 if [ -n "$MSYSTEM" ]; then
216 echo 1>&2 "Consider using --install-prerequisites"
220 if "$cc" --version | grep -q '(GCC)'; then
221 configure_args+=("CC=$cc -static-libgcc")
223 configure_args+=("${EXTRA_CONFIGURE_ARGS[@]}")
224 ./configure "${configure_args[@]}"
230 echo "Building wimlib..."
234 list_imagex_commands()
236 for cmd in ./doc/man1/wim*.1; do
240 wimlib-imagex|wimmount|wimmountrw|wimunmount)
251 echo "Installing binaries..."
252 cp .libs/*.{dll,exe} "$DESTDIR"
253 strip "$DESTDIR"/*.{dll,exe}
258 echo "Installing NEWS, README, and licenses..."
259 cp NEWS README* COPYING* "$DESTDIR"
260 sed -n '/^#/q; s/^[\/\* ]*//; p' src/divsufsort.c > "$DESTDIR"/COPYING.libdivsufsort-lite
261 if ! grep -q 'Copyright' "$DESTDIR"/COPYING.libdivsufsort-lite; then
262 echo 1>&2 "ERROR: failed to extract libdivsufsort-lite license text"
266 for fil in NEWS README* COPYING*; do
267 sed < "$fil" > "${fil}".txt -e 's/$/\r/g'
273 gen_pdf_from_man_page()
276 local pdf=${DESTDIR}/doc/${cmd}.pdf
278 echo "Generating $pdf"
279 MANPATH="./doc" man -t "$cmd" | ps2pdf - "$pdf"
284 echo "Installing PDF manual pages..."
286 for cmd in $(list_imagex_commands); do
287 gen_pdf_from_man_page "$cmd"
289 gen_pdf_from_man_page wimlib-imagex
292 install_cmd_aliases()
294 echo "Installing wim*.cmd files..."
295 for cmd in $(list_imagex_commands); do
296 sed 's/$/\r/g' > "${DESTDIR}/${cmd}.cmd" <<- EOF
298 "%~dp0\\wimlib-imagex" ${cmd#wim} %*
300 chmod +x "${DESTDIR}/${cmd}.cmd"
304 install_development_files()
306 echo "Installing development files..."
307 mkdir "$DESTDIR"/devel
308 cp .libs/libwim.dll.a "$DESTDIR"/devel/libwim.lib
309 cp include/wimlib.h "$DESTDIR"/devel/
314 echo "Creating zip file..."
316 7z -mx9 a ../"$ZIPFILE" . > /dev/null
321 rm -rf -- "$DESTDIR" "$ZIPFILE"
323 if $INSTALL_PREREQUISITES; then
324 install_prerequisites
326 if [ ! -e configure ]; then
329 if [ ! -e config.log ] || ! $SKIP_CONFIGURE; then
335 if $INCLUDE_DOCS; then
339 install_development_files
342 echo "Success! Output is in $ZIPFILE"
344 echo "Success! Output is in $DESTDIR"