]> wimlib.net Git - wimlib/blob - tools/make-windows-release
make-windows-release: split into functions for readability
[wimlib] / tools / make-windows-release
1 #!/bin/bash
2 #
3 # This script prepares a Windows binary distribution of wimlib.
4
5 set -e -u
6
7 SCRIPTNAME="$0"
8 TOPDIR=$(dirname "$(dirname "$(realpath "$0")")")
9 cd "$TOPDIR" # Top-level directory of the git repo
10
11 # Global variables, read-only after parse_options has run
12 ARCH=
13 DESTDIR=
14 EXTRA_CONFIGURE_ARGS=
15 INCLUDE_DOCS=false
16 INSTALL_MSYS2_PACKAGES=false
17 MAKE="make -j$(getconf _NPROCESSORS_ONLN)"
18 MSYSTEM=${MSYSTEM:-}
19 SKIP_CONFIGURE=false
20 VERSION=$(tools/get-version-number)
21 ZIP=false
22 ZIPFILE=
23
24 usage()
25 {
26         cat << EOF
27 Usage: $SCRIPTNAME [OPTION]... [EXTRA_CONFIGURE_ARG]...
28 Options:
29   --arch=ARCH               Specify the CPU architecture.  This is unnecessary
30                             when using MSYS2.
31
32   --include-docs            Build and install the PDF manual pages.
33
34   --install-msys2-packages  Install the MSYS2 packages needed to build wimlib.
35                             You can omit this if you have already done this for
36                             the same MSYS2 environment.
37
38   --skip-configure          Skip running the configure script again.  You can
39                             use this to save time in incremental builds if you
40                             are sure you didn't change any options.
41
42   --zip                     Zip the output files up into a zip file.
43 EOF
44 }
45
46 parse_options()
47 {
48         if [ -z "$MSYSTEM" ]; then
49                 ARCH=x86_64
50         else
51                 case "$MSYSTEM" in
52                 MINGW32)
53                         ARCH=i686
54                         CC_PKG=mingw-w64-i686-gcc
55                         ;;
56                 MINGW64)
57                         ARCH=x86_64
58                         CC_PKG=mingw-w64-x86_64-gcc
59                         ;;
60                 CLANG32)
61                         ARCH=i686
62                         CC_PKG=mingw-w64-clang-i686-clang
63                         ;;
64                 CLANG64)
65                         ARCH=x86_64
66                         CC_PKG=mingw-w64-clang-x86_64-clang
67                         ;;
68                 CLANGARM64)
69                         ARCH=aarch64
70                         CC_PKG=mingw-w64-clang-aarch64-clang
71                         ;;
72                 *)
73                         echo 1>&2 "Unsupported MSYS2 environment: $MSYSTEM.  This script supports"
74                         echo 1>&2 "MINGW32, MINGW64, CLANG32, CLANG64, and CLANGARM64."
75                         echo 1>&2 "See https://www.msys2.org/docs/environments/"
76                         exit 1
77                 esac
78         fi
79
80         local longopts="help"
81         longopts+=",arch:"
82         longopts+=",include-docs"
83         longopts+=",install-msys2-packages"
84         longopts+=",skip-configure"
85         longopts+=",zip"
86
87         local options
88         if ! options=$(getopt -o "" -l "$longopts" -- "$@"); then
89                 usage 1>&2
90                 exit 1
91         fi
92         eval set -- "$options"
93         while true; do
94                 case "$1" in
95                 --help)
96                         usage
97                         exit 0
98                         ;;
99                 --arch)
100                         ARCH=$2
101                         shift
102                         ;;
103                 --include-docs)
104                         INCLUDE_DOCS=true
105                         ;;
106                 --install-msys2-packages)
107                         if [ -z "$MSYSTEM" ]; then
108                                 echo 1>&2 "--install-msys2-packages is not allowed outside MSYS2."
109                                 exit 1
110                         fi
111                         INSTALL_MSYS2_PACKAGES=true
112                         ;;
113                 --skip-configure)
114                         SKIP_CONFIGURE=true
115                         ;;
116                 --zip)
117                         ZIP=true
118                         ;;
119                 --)
120                         shift
121                         break
122                         ;;
123                 *)
124                         echo 1>&2 "Invalid option '$1'"
125                         usage 1>&2
126                         exit 1
127                         ;;
128                 esac
129                 shift
130         done
131         case "$ARCH" in
132         i686|x86_64|aarch64)
133                 ;;
134         *)
135                 echo 1>&2 "Unknown ARCH: $ARCH.  Please specify a supported architecture with --arch"
136                 exit 1
137                 ;;
138         esac
139         DESTDIR=wimlib-${VERSION}-windows-${ARCH}-bin
140         ZIPFILE=$DESTDIR.zip
141         EXTRA_CONFIGURE_ARGS=("$@")
142 }
143
144 install_msys2_packages()
145 {
146         echo "Installing the MSYS2 $MSYSTEM packages needed to build wimlib..."
147         pacman -Syu --noconfirm --needed \
148                 autoconf \
149                 automake \
150                 git \
151                 libtool \
152                 make \
153                 "$CC_PKG" \
154                 pkgconf
155         echo "Done installing the MSYS2 $MSYSTEM packages needed to build wimlib."
156 }
157
158 bootstrap_repository()
159 {
160         echo "Bootstrapping the wimlib repository..."
161         ./bootstrap
162 }
163
164 configure_wimlib()
165 {
166         echo "Configuring wimlib..."
167         local configure_args=("--host=${ARCH}-w64-mingw32")
168         configure_args+=("--disable-static")
169         # -static-libgcc is needed with gcc.  It should go in the CFLAGS, but
170         # libtool strips it, so it must go directly in CC instead.  See
171         # http://www.gnu.org/software/libtool/manual/libtool.html#Stripped-link-flags
172         if "${ARCH}-w64-mingw32-cc" --version | grep -q '(GCC)'; then
173                 configure_args+=("CC=${ARCH}-w64-mingw32-cc -static-libgcc")
174         fi
175         configure_args+=("${EXTRA_CONFIGURE_ARGS[@]}")
176         ./configure "${configure_args[@]}"
177         $MAKE clean
178 }
179
180 build_wimlib()
181 {
182         echo "Building wimlib..."
183         $MAKE
184 }
185
186 list_imagex_commands()
187 {
188         for cmd in ./doc/man1/wim*.1; do
189                 local cmd=${cmd##*/}
190                 cmd=${cmd%.1}
191                 case "$cmd" in
192                 wimlib-imagex|wimmount|wimmountrw|wimunmount)
193                         ;;
194                 *)
195                         echo "$cmd"
196                         ;;
197                 esac
198         done
199 }
200
201 install_binaries()
202 {
203         echo "Installing binaries..."
204         cp .libs/*.{dll,exe} "$DESTDIR"
205         strip "$DESTDIR"/*.{dll,exe}
206 }
207
208 install_text_files()
209 {
210         echo "Installing NEWS, README, and licenses..."
211         cp NEWS README* COPYING* "$DESTDIR"
212         sed -n '/^#/q; s/^[\/\* ]*//; p' src/divsufsort.c > "$DESTDIR"/COPYING.libdivsufsort-lite
213         if ! grep -q 'Copyright' "$DESTDIR"/COPYING.libdivsufsort-lite; then
214                 echo 1>&2 "ERROR: failed to extract libdivsufsort-lite license text"
215                 exit 1
216         fi
217         cd "$DESTDIR"
218         for fil in NEWS README* COPYING*; do
219                 sed < "$fil" > "${fil}".txt -e 's/$/\r/g'
220                 rm "$fil"
221         done
222         cd ..
223 }
224
225 gen_pdf_from_man_page()
226 {
227         local cmd=$1
228         local pdf=${DESTDIR}/doc/${cmd}.pdf
229
230         echo "Generating $pdf"
231         MANPATH="./doc" man -t "$cmd" | ps2pdf - "$pdf"
232 }
233
234 install_pdf_docs()
235 {
236         echo "Installing PDF manual pages..."
237         mkdir "$DESTDIR"/doc
238         for cmd in $(list_imagex_commands); do
239                 gen_pdf_from_man_page "$cmd"
240         done
241         gen_pdf_from_man_page wimlib-imagex
242 }
243
244 install_cmd_aliases()
245 {
246         echo "Installing wim*.cmd files..."
247         for cmd in $(list_imagex_commands); do
248                 sed 's/$/\r/g' > "${DESTDIR}/${cmd}.cmd" <<- EOF
249                         @echo off
250                         "%~dp0\\wimlib-imagex" ${cmd#wim} %*
251                 EOF
252                 chmod +x "${DESTDIR}/${cmd}.cmd"
253         done
254 }
255
256 install_development_files()
257 {
258         echo "Installing development files..."
259         mkdir "$DESTDIR"/devel
260         cp .libs/libwim.dll.a "$DESTDIR"/devel/libwim.lib
261         cp include/wimlib.h "$DESTDIR"/devel/
262 }
263
264 create_zip_file()
265 {
266         echo "Creating zip file..."
267         cd "$DESTDIR"
268         7z -mx9 a ../"$ZIPFILE" . > /dev/null
269         cd ..
270 }
271
272 parse_options "$@"
273 rm -rf -- "$DESTDIR" "$ZIPFILE"
274 mkdir -- "$DESTDIR"
275 if $INSTALL_MSYS2_PACKAGES; then
276         install_msys2_packages
277 fi
278 if [ ! -e configure ]; then
279         bootstrap_repository
280 fi
281 if [ ! -e config.log ] || ! $SKIP_CONFIGURE; then
282         configure_wimlib
283 fi
284 build_wimlib
285 install_binaries
286 install_text_files
287 if $INCLUDE_DOCS; then
288         install_pdf_docs
289 fi
290 install_cmd_aliases
291 install_development_files
292 if $ZIP; then
293         create_zip_file
294         echo "Success!  Output is in $ZIPFILE"
295 else
296         echo "Success!  Output is in $DESTDIR"
297 fi