win: update certifi
[gpodder.git] / tools / win_installer / _base.sh
blob81a1c1b26fee00af44a11690b336360808444ab9
1 #!/usr/bin/env bash
2 # Copyright 2016 Christoph Reiter
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 set -e
10 DIR="$( cd "$( dirname "$0" )" && pwd )"
11 cd "${DIR}"
13 # CONFIG START
15 ARCH="i686"
16 BUILD_VERSION="0"
18 # CONFIG END
20 MISC="${DIR}"/misc
21 if [ "${ARCH}" = "x86_64" ]; then
22 MINGW="mingw64"
23 else
24 MINGW="mingw32"
27 GPO_VERSION="0.0.0"
28 GPO_VERSION_DESC="UNKNOWN"
30 function set_build_root {
31 BUILD_ROOT="$1"
32 REPO_CLONE="${BUILD_ROOT}"/gpodder
33 MINGW_ROOT="${BUILD_ROOT}/${MINGW}"
36 if [ "$APPVEYOR" == "True" ]; then
37 set_build_root "$HOME/_gpodder_build_root"
38 elif [ -d "/home/IEUser" ]; then
39 set_build_root "/home/IEUser/_gpodder_build_root"
40 else
41 set_build_root "${DIR}/_build_root"
44 function build_pacman {
45 pacman --root "${BUILD_ROOT}" "$@"
48 function build_pip {
49 "${MINGW_ROOT}"/bin/python3.exe -m pip "$@"
52 function build_python {
53 "${MINGW_ROOT}"/bin/python3.exe "$@"
56 function build_compileall {
57 MSYSTEM= build_python -m compileall -b "$@"
60 function install_pre_deps {
61 # install python3 here to ensure same version
62 pacman -S --needed --noconfirm p7zip git dos2unix rsync \
63 mingw-w64-"${ARCH}"-nsis wget libidn2 libopenssl intltool mingw-w64-"${ARCH}"-toolchain \
64 mingw-w64-"${ARCH}"-python3
67 function create_root {
68 mkdir -p "${BUILD_ROOT}"
70 mkdir -p "${BUILD_ROOT}"/var/lib/pacman
71 mkdir -p "${BUILD_ROOT}"/var/log
72 mkdir -p "${BUILD_ROOT}"/tmp
74 build_pacman -Syu
75 build_pacman --noconfirm -S base
78 function extract_installer {
79 [ -z "$1" ] && (echo "Missing arg"; exit 1)
81 mkdir -p "$BUILD_ROOT"
82 7z x -o"$BUILD_ROOT"/"$MINGW" "$1"
83 rm -rf "$MINGW_ROOT"/'$PLUGINSDIR' "$MINGW_ROOT"/*.txt "$MINGW_ROOT"/*.nsi
86 PIP_REQUIREMENTS="\
87 podcastparser==0.6.4
88 mygpoclient==1.8
89 git+https://github.com/enthought/pywin32-ctypes.git@f27d6a0
90 html5lib==1.0.1
91 webencodings==0.5.1
92 six==1.12.0
93 certifi==2019.9.11
94 mutagen==1.42.0
95 youtube_dl==2019.9.12.1
98 function install_deps {
100 # We don't use the fontconfig backend, and this skips the lengthy
101 # cache update step during package installation
102 export MSYS2_FC_CACHE_SKIP=1
104 build_pacman --noconfirm -S git mingw-w64-"${ARCH}"-gdk-pixbuf2 \
105 mingw-w64-"${ARCH}"-librsvg \
106 mingw-w64-"${ARCH}"-gtk3 mingw-w64-"${ARCH}"-python3 \
107 mingw-w64-"${ARCH}"-python3-gobject \
108 mingw-w64-"${ARCH}"-python3-cairo \
109 mingw-w64-"${ARCH}"-python3-pip \
110 mingw-w64-"${ARCH}"-make
112 build_pacman -S --noconfirm mingw-w64-"${ARCH}"-python3-setuptools
114 build_pip install --no-deps --no-binary ":all:" --upgrade \
115 --force-reinstall $(echo "$PIP_REQUIREMENTS" | tr ["\\n"] [" "])
117 # replace ca-certificates with certifi's
118 build_pacman --noconfirm -Rdds mingw-w64-"${ARCH}"-ca-certificates || true
119 mkdir -p ${MINGW_ROOT}/ssl
120 site_packages=$(build_python -c 'import sys;print(next(c for c in sys.path if "site-packages" in c))')
121 cp -v ${site_packages}/certifi/cacert.pem ${MINGW_ROOT}/ssl/cert.pem
122 build_pip uninstall -y certifi
124 build_pacman --noconfirm -Rdds mingw-w64-"${ARCH}"-python3-pip || true
127 function install_gpodder {
128 [ -z "$1" ] && (echo "Missing arg"; exit 1)
130 rm -Rf "${REPO_CLONE}"
131 if [ "$2" == "rsync" ]; then
132 # development mode when not everything is committed
133 rsync -rvt "${DIR}"/../.. "${REPO_CLONE}"
134 else
135 git clone "${DIR}"/../.. "${REPO_CLONE}"
138 (cd "${REPO_CLONE}" && git checkout "$1") || exit 1
140 (cd "${REPO_CLONE}" && PYTHON="${MINGW_ROOT}"/bin/python3.exe mingw32-make install-win)
142 GPO_VERSION=$(MSYSTEM= build_python -c \
143 "import gpodder; import sys; sys.stdout.write(gpodder.__version__)")
144 GPO_VERSION_DESC="$GPO_VERSION"
145 if [ "$1" = "master" ]
146 then
147 local GIT_REV=$(git rev-list --count HEAD)
148 local GIT_HASH=$(git rev-parse --short HEAD)
149 GPO_VERSION_DESC="$GPO_VERSION-rev$GIT_REV-$GIT_HASH"
152 # Create launchers
153 echo "python3 is $(which python3) version is $(python3 --version)"
154 python3 "${MISC}"/create-launcher.py \
155 "${GPO_VERSION}" "${MINGW_ROOT}"/bin
157 # install fake dbus
158 site_packages=$(build_python -c 'import sys;print(next(c for c in sys.path if "site-packages" in c))')
159 site_packages_unix=$(echo "/$site_packages" | sed -e 's/\\/\//g' -e 's/://')
160 rsync -arv --delete "${REPO_CLONE}"/tools/fake-dbus-module/dbus "${site_packages_unix}/"
162 # install gtk3 settings for a proper font
163 mkdir -p "${MINGW_ROOT}"/etc/gtk-3.0
164 cp "${MISC}"/gtk3.0_settings.ini "${MINGW_ROOT}"/etc/gtk-3.0/settings.ini
166 # install bin/gpodder bin/gpo to a separate package, to be run before gpodder/__init__.py
167 gpodder_launch_dir="${site_packages_unix}"/gpodder_launch
168 mkdir -p "${gpodder_launch_dir}"
169 touch "${gpodder_launch_dir}"/__init__.py
170 cp ${REPO_CLONE}/bin/gpo "${gpodder_launch_dir}"/gpo.py
171 cp ${REPO_CLONE}/bin/gpodder "${gpodder_launch_dir}"/gpodder.py
173 build_compileall -d "" -f -q "$(cygpath -w "${MINGW_ROOT}")"
175 # copy gpodder.ico for notification-win32
176 cp ${REPO_CLONE}/tools/win_installer/misc/gpodder.ico "${MINGW_ROOT}"/bin
179 function cleanup_before {
180 # these all have svg variants
181 find "${MINGW_ROOT}"/share/icons -name "*.symbolic.png" -exec rm -f {} \;
183 # remove some larger ones
184 rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/512x512"
185 rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/256x256"
186 rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/96x96"
187 rm -Rf "${MINGW_ROOT}/share/icons/Adwaita/48x48"
188 "${MINGW_ROOT}"/bin/gtk-update-icon-cache-3.0.exe \
189 "${MINGW_ROOT}"/share/icons/Adwaita
191 # remove some gtk demo icons
192 find "${MINGW_ROOT}"/share/icons/hicolor -name "gtk3-*" -exec rm -f {} \;
193 "${MINGW_ROOT}"/bin/gtk-update-icon-cache-3.0.exe \
194 "${MINGW_ROOT}"/share/icons/hicolor
196 # python related, before installing gpodder
197 rm -Rf "${MINGW_ROOT}"/lib/python3.*/test
198 rm -f "${MINGW_ROOT}"/lib/python3.*/lib-dynload/_tkinter*
199 find "${MINGW_ROOT}"/lib/python3.* -type d -name "test*" \
200 -prune -exec rm -rf {} \;
201 find "${MINGW_ROOT}"/lib/python3.* -type d -name "*_test*" \
202 -prune -exec rm -rf {} \;
204 find "${MINGW_ROOT}"/bin -name "*.pyo" -exec rm -f {} \;
205 find "${MINGW_ROOT}"/bin -name "*.pyc" -exec rm -f {} \;
206 find "${MINGW_ROOT}" -type d -name "__pycache__" -prune -exec rm -rf {} \;
208 build_compileall -d "" -f -q "$(cygpath -w "${MINGW_ROOT}")"
209 find "${MINGW_ROOT}" -name "*.py" -exec rm -f {} \;
212 function cleanup_after {
213 # delete translations we don't support
214 for d in "${MINGW_ROOT}"/share/locale/*/LC_MESSAGES; do
215 if [ ! -f "${d}"/gpodder.mo ]; then
216 rm -Rf "${d}"
218 done
220 find "${MINGW_ROOT}" -regextype "posix-extended" -name "*.exe" -a ! \
221 -iregex ".*/(gpodder|gpo|python)[^/]*\\.exe" \
222 -exec rm -f {} \;
224 rm -Rf "${MINGW_ROOT}"/libexec
225 rm -Rf "${MINGW_ROOT}"/share/gtk-doc
226 rm -Rf "${MINGW_ROOT}"/include
227 rm -Rf "${MINGW_ROOT}"/var
228 rm -Rf "${MINGW_ROOT}"/etc/fonts
229 rm -Rf "${MINGW_ROOT}"/etc/pki
230 rm -Rf "${MINGW_ROOT}"/share/zsh
231 rm -Rf "${MINGW_ROOT}"/share/pixmaps
232 rm -Rf "${MINGW_ROOT}"/share/gnome-shell
233 rm -Rf "${MINGW_ROOT}"/share/dbus-1
234 rm -Rf "${MINGW_ROOT}"/share/gir-1.0
235 rm -Rf "${MINGW_ROOT}"/share/doc
236 rm -Rf "${MINGW_ROOT}"/share/man
237 rm -Rf "${MINGW_ROOT}"/share/info
238 rm -Rf "${MINGW_ROOT}"/share/mime
239 rm -Rf "${MINGW_ROOT}"/share/gettext
240 rm -Rf "${MINGW_ROOT}"/share/libtool
241 rm -Rf "${MINGW_ROOT}"/share/licenses
242 rm -Rf "${MINGW_ROOT}"/share/appdata
243 rm -Rf "${MINGW_ROOT}"/share/aclocal
244 rm -Rf "${MINGW_ROOT}"/share/ffmpeg
245 rm -Rf "${MINGW_ROOT}"/share/vala
246 rm -Rf "${MINGW_ROOT}"/share/readline
247 rm -Rf "${MINGW_ROOT}"/share/xml
248 rm -Rf "${MINGW_ROOT}"/share/bash-completion
249 rm -Rf "${MINGW_ROOT}"/share/common-lisp
250 rm -Rf "${MINGW_ROOT}"/share/emacs
251 rm -Rf "${MINGW_ROOT}"/share/gdb
252 rm -Rf "${MINGW_ROOT}"/share/libcaca
253 rm -Rf "${MINGW_ROOT}"/share/gettext
254 rm -Rf "${MINGW_ROOT}"/share/gst-plugins-base
255 rm -Rf "${MINGW_ROOT}"/share/gst-plugins-bad
256 rm -Rf "${MINGW_ROOT}"/share/libgpg-error
257 rm -Rf "${MINGW_ROOT}"/share/p11-kit
258 rm -Rf "${MINGW_ROOT}"/share/pki
259 rm -Rf "${MINGW_ROOT}"/share/thumbnailers
260 rm -Rf "${MINGW_ROOT}"/share/gtk-3.0
261 rm -Rf "${MINGW_ROOT}"/share/nghttp2
262 rm -Rf "${MINGW_ROOT}"/share/themes
263 rm -Rf "${MINGW_ROOT}"/share/fontconfig
264 rm -Rf "${MINGW_ROOT}"/share/gettext-*
265 rm -Rf "${MINGW_ROOT}"/share/gstreamer-1.0
266 rm -Rf "${MINGW_ROOT}"/share/installed-tests
268 find "${MINGW_ROOT}"/share/glib-2.0 -type f ! \
269 -name "*.compiled" -exec rm -f {} \;
271 # unused configuration example
272 rm -Rf "${MINGW_ROOT}"/ssl/openssl.cnf
274 rm -Rf "${MINGW_ROOT}"/lib/cmake
275 rm -Rf "${MINGW_ROOT}"/lib/gettext
276 rm -Rf "${MINGW_ROOT}"/lib/gtk-3.0
277 rm -Rf "${MINGW_ROOT}"/lib/mpg123
278 rm -Rf "${MINGW_ROOT}"/lib/p11-kit
279 rm -Rf "${MINGW_ROOT}"/lib/pkcs11
280 rm -Rf "${MINGW_ROOT}"/lib/ruby
281 rm -Rf "${MINGW_ROOT}"/lib/engines
283 # remove all tcl/tk libs
284 rm -Rf "${MINGW_ROOT}"/lib/dde*
285 rm -Rf "${MINGW_ROOT}"/lib/itcl*
286 rm -Rf "${MINGW_ROOT}"/lib/reg*
287 rm -Rf "${MINGW_ROOT}"/lib/tcl*
288 rm -Rf "${MINGW_ROOT}"/lib/tdbc*
289 rm -Rf "${MINGW_ROOT}"/lib/tk*
291 # remove terminfo database (not used, even by gpo)
292 rm -Rf "${MINGW_ROOT}"/lib/terminfo
293 rm -Rf "${MINGW_ROOT}"/share/terminfo
295 rm -f "${MINGW_ROOT}"/bin/libharfbuzz-icu-0.dll
296 rm -Rf "${MINGW_ROOT}"/lib/python2.*
298 find "${MINGW_ROOT}" -name "*.a" -exec rm -f {} \;
299 find "${MINGW_ROOT}" -name "*.whl" -exec rm -f {} \;
300 find "${MINGW_ROOT}" -name "*.h" -exec rm -f {} \;
301 find "${MINGW_ROOT}" -name "*.la" -exec rm -f {} \;
302 find "${MINGW_ROOT}" -name "*.sh" -exec rm -f {} \;
303 find "${MINGW_ROOT}" -name "*.jar" -exec rm -f {} \;
304 find "${MINGW_ROOT}" -name "*.def" -exec rm -f {} \;
305 find "${MINGW_ROOT}" -name "*.cmd" -exec rm -f {} \;
306 find "${MINGW_ROOT}" -name "*.cmake" -exec rm -f {} \;
307 find "${MINGW_ROOT}" -name "*.pc" -exec rm -f {} \;
308 find "${MINGW_ROOT}" -name "*.desktop" -exec rm -f {} \;
309 find "${MINGW_ROOT}" -name "*.manifest" -exec rm -f {} \;
310 find "${MINGW_ROOT}" -name "*.pyo" -exec rm -f {} \;
312 find "${MINGW_ROOT}"/bin -name "*-config" -exec rm -f {} \;
313 find "${MINGW_ROOT}"/bin -name "easy_install*" -exec rm -f {} \;
314 find "${MINGW_ROOT}" -regex ".*/bin/[^.]+" -exec rm -f {} \;
315 find "${MINGW_ROOT}" -regex ".*/bin/[^.]+\\.[0-9]+" -exec rm -f {} \;
317 find "${MINGW_ROOT}" -name "gtk30-properties.mo" -exec rm -rf {} \;
318 find "${MINGW_ROOT}" -name "gettext-tools.mo" -exec rm -rf {} \;
319 find "${MINGW_ROOT}" -name "libexif-12.mo" -exec rm -rf {} \;
320 find "${MINGW_ROOT}" -name "xz.mo" -exec rm -rf {} \;
321 find "${MINGW_ROOT}" -name "libgpg-error.mo" -exec rm -rf {} \;
323 find "${MINGW_ROOT}" -name "old_root.pem" -exec rm -rf {} \;
324 find "${MINGW_ROOT}" -name "weak.pem" -exec rm -rf {} \;
326 find "${MINGW_ROOT}"/bin -name "*.pyo" -exec rm -f {} \;
327 find "${MINGW_ROOT}"/bin -name "*.pyc" -exec rm -f {} \;
328 find "${MINGW_ROOT}" -type d -name "__pycache__" -prune -exec rm -rf {} \;
330 build_python "${MISC}/depcheck.py" --delete
332 find "${MINGW_ROOT}" -type d -empty -delete
335 function dump_packages {
336 DUMPFILE="${MINGW_ROOT}/contents.txt"
337 pkg=""
338 rm -f "$DUMPFILE"
340 unset PKGVERSIONS
341 declare -A PKGVERSIONS
342 while read pkg version; do
343 PKGVERSIONS[$pkg]="$version"
344 done < <(build_pacman -Q)
345 # REGFILES is a hash of file -> package name to check for unregistered files in the end
346 unset REGFILES
347 declare -A REGFILES
348 echo "msys2 packages:"
349 # first handle all files registered with pacman
350 while read _pkg file; do
351 realfile=""
352 if [[ "$file" == "${MINGW_ROOT}"* ]]; then
353 if [ -f "$file" ]; then
354 realfile="$file"
355 elif [[ "$file" == *".py" ]] && [ -f "${file}c" ]; then
356 realfile="${file}c"
359 if [ -n "$realfile" ]; then
360 if [ "$_pkg" != "$pkg" ]; then
361 pkg="$_pkg"
362 echo "$pkg ${PKGVERSIONS[$pkg]}"
364 echo " ${realfile#${MINGW_ROOT}}"
365 REGFILES["$realfile"]="$pkg"
367 done < <(build_pacman -Ql)
368 echo "==================="
369 # then handle all python packages (with an installed-files.txt)
370 echo "Python packages:"
371 for p in ${PIP_REQUIREMENTS}; do
372 pkg=${p%==*}
373 version=${p#*==}
374 echo "$pkg $version"
375 # pywin32-ctypes doesn't provide an egg-info/installed-files.txt
376 if [ "$pkg" == "pywin32-ctypes" ]; then
377 while read file; do
378 if [ ! ${REGFILES[$file]+_} ]; then
379 echo " $file"
380 REGFILES["$file"]="$pkg"
382 done < <(find "${MINGW_ROOT}" -type f -a \( -path '*/site-packages/pywin32_ctypes*' -o -path '*/site-packages/win32ctypes/*' \))
383 elif [ "$pkg" == "certifi" ]; then
384 while read file; do
385 if [ ! ${REGFILES[$file]+_} ]; then
386 echo " $file"
387 REGFILES["$file"]="$pkg"
389 done < <(find "${MINGW_ROOT}/ssl" -type f -path '*/ssl/cert.pem')
390 else
391 # other python deps provide an installed-files.txt, so simply go through them
392 egg="${MINGW_ROOT}/lib/python3.6/site-packages/${pkg}-${version}-py3.6.egg-info"
393 if [ -f "$egg/installed-files.txt" ]; then
394 while read file; do
395 realfile=""
396 tryfile="$egg/$file"
397 if [ -f "$tryfile" ]; then
398 realfile=$(realpath "$tryfile")
399 # we precompiled all python modules
400 elif [[ "$tryfile" == *.py ]] && [ -f "${tryfile}c" ]; then
401 realfile=$(realpath "${tryfile}c")
403 # this file (or compiled module) belongs to this python package
404 if [ -n "$realfile" ]; then
405 echo " $realfile"
406 REGFILES["$realfile"]="$pkg"
408 # installed-files.txt is not listed in itself, so add it manually
409 done < <(echo installed-files.txt; tr -d '\r' < "$egg/installed-files.txt")
412 done
413 echo "==================="
414 echo gPodder
415 # every file with gpodder in the path belongs to us!
416 while read relfile; do
417 file="${MINGW_ROOT}/${relfile#./}"
418 if [ ! ${REGFILES[$file]+_} ]; then
419 echo " $file"
420 REGFILES["$file"]="gpodder"
422 done < <(cd "${MINGW_ROOT}" && find . -type f -a \( -path '*gpodder*' -o -path '*/site-packages/dbus/*' -o -name gpo.exe \))
423 echo "==================="
424 echo "Unregistered files:"
425 # a few generated files
426 while read file; do
427 if [ ! ${REGFILES[$file]+_} ]; then
428 echo " $file"
430 done < <(find "${MINGW_ROOT}" -type f)
431 ) > "$DUMPFILE"
432 unix2dos "${DUMPFILE}"
433 cp "${DUMPFILE}" "$DIR/gpodder-$GPO_VERSION_DESC-contents.txt"
436 function build_installer {
437 BUILDPY=$(echo "${MINGW_ROOT}"/lib/python3.*/site-packages/gpodder)/build_info.py
438 cp "${REPO_CLONE}"/src/gpodder/build_info.py "$BUILDPY"
439 echo 'BUILD_TYPE = u"windows"' >> "$BUILDPY"
440 echo "BUILD_VERSION = $BUILD_VERSION" >> "$BUILDPY"
441 (cd "$REPO_CLONE" && echo "BUILD_INFO = u\"$(git rev-parse --short HEAD)\"" >> "$BUILDPY")
442 (cd $(dirname "$BUILDPY") && build_compileall -d "" -q -f -l .)
443 rm -f "$BUILDPY"
445 cp "${MISC}"/gpodder.ico "${BUILD_ROOT}"
446 (cd "$BUILD_ROOT" && makensis -V3 -NOCD -DVERSION="$GPO_VERSION_DESC" "${MISC}"/win_installer.nsi)
448 mv "$BUILD_ROOT/gpodder-LATEST.exe" "$DIR/gpodder-$GPO_VERSION_DESC-installer.exe"
451 function build_portable_installer {
452 BUILDPY=$(echo "${MINGW_ROOT}"/lib/python3.*/site-packages/gpodder)/build_info.py
453 cp "${REPO_CLONE}"/src/gpodder/build_info.py "$BUILDPY"
454 echo 'BUILD_TYPE = u"windows-portable"' >> "$BUILDPY"
455 echo "BUILD_VERSION = $BUILD_VERSION" >> "$BUILDPY"
456 (cd "$REPO_CLONE" && echo "BUILD_INFO = u\"$(git rev-parse --short HEAD)\"" >> "$BUILDPY")
457 (cd $(dirname "$BUILDPY") && build_compileall -d "" -q -f -l .)
458 rm -f "$BUILDPY"
460 local PORTABLE="$DIR/gpodder-${GPO_VERSION_DESC}-portable"
462 rm -rf "$PORTABLE"
463 mkdir "$PORTABLE"
464 cp "$MISC"/gpodder.lnk "$PORTABLE"
465 cp "$MISC"/gpo.lnk "$PORTABLE"
466 cp "$MISC"/README-PORTABLE.txt "$PORTABLE"/README.txt
467 unix2dos "$PORTABLE"/README.txt
468 mkdir "$PORTABLE"/config
469 cp -RT "${MINGW_ROOT}" "$PORTABLE"/data
471 rm -Rf 7zout 7z1604.exe
472 7z a payload.7z "$PORTABLE"
473 wget -P "$DIR" -c http://www.7-zip.org/a/7z1604.exe
474 7z x -o7zout 7z1604.exe
475 cat 7zout/7z.sfx payload.7z > "$PORTABLE".exe
476 rm -Rf 7zout 7z1604.exe payload.7z "$PORTABLE"