File: windows-build.sh

package info (click to toggle)
wimlib 1.14.4-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,044 kB
  • sloc: ansic: 49,927; sh: 7,148; makefile: 293
file content (345 lines) | stat: -rwxr-xr-x 8,071 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
#!/bin/bash
#
# This script builds wimlib for Windows.  It supports both MSYS2 and Linux.

set -e -u

SCRIPTNAME="$0"
TOPDIR=$(dirname "$(dirname "$(realpath "$0")")")
cd "$TOPDIR" # Top-level directory of the git repo

# Global variables, read-only after parse_options has run
ARCH=
CC_PKG=
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.sh)
ZIP=false
ZIPFILE=

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"

usage()
{
	cat << EOF
Usage: $SCRIPTNAME [OPTION]... [EXTRA_CONFIGURE_ARG]...
Options:
  --arch=ARCH               Specify the CPU architecture.  This is unnecessary
                            when using MSYS2.

  --include-docs            Build and install the PDF manual pages.

  --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.

  --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.

  --zip                     Zip the output files up into a zip file.
EOF
}

parse_options()
{
	case "$MSYSTEM" in
	"")
		ARCH=x86_64
		;;
	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

	local longopts="help"
	longopts+=",arch:"
	longopts+=",include-docs"
	longopts+=",install-prerequisites"
	longopts+=",skip-configure"
	longopts+=",zip"

	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_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."

	if $PREBUILT_LLVM_MINGW_ENABLED; then
		install_prebuilt_llvm_mingw
	fi
}

bootstrap_repository()
{
	echo "Bootstrapping the wimlib repository..."
	./bootstrap
}

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
	# https://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 ! type -P "$cc" &>/dev/null; then
		echo 1>&2 "ERROR: $cc not found!"
		if [ -n "$MSYSTEM" ]; then
			echo 1>&2 "Consider using --install-prerequisites"
		fi
		exit 1
	fi
	if ! "$cc" --version | grep -q -i 'clang'; 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
}

install_binaries()
{
	echo "Installing binaries..."
	cp .libs/*.{dll,exe} "$DESTDIR"
	strip "$DESTDIR"/*.{dll,exe}
}

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%.md}".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"
}

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
}

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
}

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/
}

create_zip_file()
{
	echo "Creating zip file..."
	cd "$DESTDIR"
	7z -mx9 a ../"$ZIPFILE" . > /dev/null
	cd ..
}

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