-
Notifications
You must be signed in to change notification settings - Fork 5
/
winedeploy.sh
272 lines (218 loc) · 10.5 KB
/
winedeploy.sh
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
#!/bin/bash
# sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) universe"
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt install p7zip-full icoutils # For Notepad++
# Get Wine
wget -c https://www.playonlinux.com/wine/binaries/linux-x86/PlayOnLinux-wine-3.20-linux-x86.pol
# Get old Wine (for icons and such)
# apt download libc6:i386
# ./W dpkg -x wine*.deb .
# Download ALL the i386 dependencies of Wine down to glibc/libc6, but not Wine itself
# (we have a newer one)
URLS=$(apt-get --allow-unauthenticated -o Apt::Get::AllowUnauthenticated=true \
-o Debug::NoLocking=1 -o APT::Cache-Limit=125829120 -o Dir::Etc::sourceparts=- \
-o APT::Get::List-Cleanup=0 -o APT::Get::AllowUnauthenticated=1 \
-o Debug::pkgProblemResolver=true -o Debug::pkgDepCache::AutoInstall=true \
-o APT::Install-Recommends=0 -o APT::Install-Suggests=0 -y \
install --print-uris wine:i386 | grep "_i386" | grep -v "wine" | cut -d "'" -f 2 )
wget -c $URLS
# Get unionfs-fuse to make shared read-only wineprefix usable for every user
apt download fuse unionfs-fuse libfuse2 # 32-bit versions seemingly do not work properly on 64-bit machines
# Get suitable old ld-linux.so and the stuff that comes with it
# apt download libc6:i386 # It is already included above
mkdir -p ./Wine.AppDir
tar xfvj PlayOnLinux-wine-*-linux-x86.pol -C ./Wine.AppDir --strip-components=2 wineversion/
cd Wine.AppDir/
# Add winetricks and cabextract
wget "https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks" -P ./bin && chmod +x ./bin/winetricks
wget "https://mex.mirror.pkgbuild.com/community/os/x86_64/cabextract-1.9.1-1-x86_64.pkg.tar.xz" -P ../ && tar xvf ../cabextract-*-x86_64.pkg.tar.xz --strip-components=1
# Extract debs
find ../.. -name '*.deb' -exec dpkg -x {} . \;
# Make absolutely sure it will not load stuff from /lib or /usr
sed -i -e 's|/usr|/xxx|g' lib/ld-linux.so.2
sed -i -e 's|/usr/lib|/ooo/ooo|g' lib/ld-linux.so.2
# Remove duplicate (why is it there?)
rm -f lib/i386-linux-gnu/ld-*.so
# Workaround for:
# p11-kit: couldn't load module
rm usr/lib/i386-linux-gnu/libp11-* || true
find . -path '*libp11*' -delete || true
# Only use Windows fonts. Do not attempt to use fonts from the host
# This should greatly speed up first-time launch times
# and get rid of fontconfig messages
sed -i -e 's|fontconfig|xxxxconfig|g' lib/wine/gdi32.dll.so
find . -path '*fontconfig*' -delete
# Get libhookexecv.so
cp ../libhookexecv.so lib/libhookexecv.so
# Get wine-preloader_hook
cp ../wine-preloader_hook bin/
chmod +x bin/wine-preloader_hook
# Write custom AppRun
cat > AppRun <<\EOF
#!/bin/bash
HERE="$(dirname "$(readlink -f "${0}")")"
export LD_LIBRARY_PATH="$HERE/usr/lib":$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$HERE/usr/lib/i386-linux-gnu":$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$HERE/lib":$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$HERE/lib/i386-linux-gnu":$LD_LIBRARY_PATH
# Sound Library
export LD_LIBRARY_PATH="$HERE/usr/lib/i386-linux-gnu/pulseaudio":$LD_LIBRARY_PATH
export LD_LIBRARY_PATH="$HERE/usr/lib/i386-linux-gnu/alsa-lib":$LD_LIBRARY_PATH
# LD
export WINELDLIBRARY="$HERE/lib/ld-linux.so.2"
export WINEDLLOVERRIDES="mscoree,mshtml=" # Do not ask to install Mono or Gecko
export WINEDEBUG=-all # Do not print Wine debug messages
# Workaround for: wine: loadlocale.c:129: _nl_intern_locale_data:
# Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
export LC_ALL=C LANGUAGE=C LANG=C
# Load Explorer if no arguments given
APPLICATION=""
if [ -z "$*" ] ; then
APPLICATION="winecfg"
fi
# Since the AppImage gets mounted at different locations, relying on "$HERE"
# does not good to determine a unique string per application when inside an AppImage
if [ -z "$APPIMAGE" ] ; then
AppName=wine_$(echo "$HERE" | sha1sum | cut -d " " -f 1)
else
AppName=wine_$(echo "$APPIMAGE" | sha1sum | cut -d " " -f 1)
fi
MNT_WINEPREFIX="/tmp/$AppName.unionfs" # TODO: Use the name of the app
# remove C:\users symlink to /home for older wineprefix.tar.gz files
if [ -n "$WINEPREFIX" ] ; then
MIME1=$(file --mime-type $WINEPREFIX/drive_c/users)
if [ "$MIME1" = "$WINEPREFIX/drive_c/users: inode/symlink" ]; then
rm -rf "$WINEPREFIX/drive_c/users"
fi
fi
# Load bundled WINEPREFIX if existing and if $WINEPREFIX is not set
if [ -d "$HERE/wineprefix" ] && [ -z "$WINEPREFIX" ] ; then
RO_WINEPREFIX="$HERE/wineprefix" # WINEPREFIX in the AppDir
RW_WINEPREFIX_OVERLAY="/tmp/$AppName.rw" # TODO: Use the name of the app
mkdir -p "$MNT_WINEPREFIX" "$RW_WINEPREFIX_OVERLAY"
if [ ! -e "$MNT_WINEPREFIX/drive_c" ] ; then
echo "Mounting $MNT_WINEPREFIX"
"$HERE/usr/bin/unionfs-fuse" -o use_ino,uid=$UID -ocow "$RW_WINEPREFIX_OVERLAY"=RW:"$RO_WINEPREFIX"=RO "$MNT_WINEPREFIX" || exit 1
trap atexit EXIT
fi
export WINEPREFIX="$MNT_WINEPREFIX"
echo "Using $HERE/wineprefix mounted to $WINEPREFIX"
fi
atexit()
{
while pgrep -f "$HERE/bin/wineserver" ; do sleep 1 ; done
pkill -f "$HERE/usr/bin/unionfs-fuse"
sleep 1
rm -r "$MNT_WINEPREFIX" # "$RW_WINEPREFIX_OVERLAY"
}
# Allow the AppImage to be symlinked to e.g., /usr/bin/wineserver
if [ ! -z $APPIMAGE ] ; then
BINARY_NAME=$(basename "$ARGV0")
else
BINARY_NAME=$(basename "$0")
fi
if [ ! -z "$1" ] && [ -e "$HERE/bin/$1" ] ; then
APPLICATION="$1"
MAIN="$HERE/bin/$1" ; shift
elif [ ! -z "$1" ] && [ -e "$HERE/usr/bin/$1" ] ; then
MAIN="$HERE/usr/bin/$1" ; shift
elif [ -e "$HERE/bin/$BINARY_NAME" ] ; then
MAIN="$HERE/bin/$BINARY_NAME"
elif [ -e "$HERE/usr/bin/$BINARY_NAME" ] ; then
MAIN="$HERE/usr/bin/$BINARY_NAME"
else
MAIN="$HERE/bin/wine"
fi
# create missing registry files to ensure wine runs correctly
if [ ! -e "$WINEPREFIX/system.reg" ] ; then
LD_PRELOAD="$HERE/lib/libhookexecv.so" "$WINELDLIBRARY" "$HERE/bin/wine" "wineboot" "-u" | cat
fi
MIME=$(file --mime-type "$MAIN")
if [ "$MIME" = "$MAIN: text/x-shellscript" ] ; then
if [ "$APPLICATION" = "winetricks" ] ; then
# https://wiki.winehq.org/Winetricks
"$MAIN" "$@" | cat
elif [ ! -z "$APPLICATION" ] ; then
# shell scripts in /bin/ that need to be run as 'wine wineprogram'
# msiexec, notepad, regedit, regsvr32, wineboot, winecfg, wineconsole, winedbg, winefile, winemine, winepath
LD_PRELOAD="$HERE/lib/libhookexecv.so" "$WINELDLIBRARY" "$HERE/bin/wine" "$APPLICATION" "$@" | cat
fi
elif [ -z "$APPLICATION" ] ; then
LD_PRELOAD="$HERE/lib/libhookexecv.so" "$WINELDLIBRARY" "$MAIN" "$@" | cat
else
LD_PRELOAD="$HERE/lib/libhookexecv.so" "$WINELDLIBRARY" "$MAIN" "$APPLICATION" | cat
fi
EOF
chmod +x AppRun
# Why is this needed? Probably because our Wine was compiled on a different distribution
( cd ./lib/i386-linux-gnu/ ; ln -s libudev.so.1 libudev.so.0 )
( cd ./usr/lib/i386-linux-gnu/ ; rm -f libpng12.so.0 ; ln -s ../../../lib/libpng12.so.0 . )
rm -rf lib64/
# Cannot move around share since Wine has the relative path to it; hence symlinking
# so that the desktop file etc. are in the correct place for desktop integration
cp -r usr/share share/ && rm -rf usr/share
( cd usr/ ; ln -s ../share . )
grep "Categories=" usr/share/applications/wine.desktop || echo 'Categories=System;Emulator;' >> usr/share/applications/wine.desktop
cp usr/share/applications/wine.desktop .
touch wine.svg # FIXME
export VERSION=$(strings ./lib/libwine.so.1 | grep wine-[\.0-9] | cut -d "-" -f 2)
cd ..
export WINEDLLOVERRIDES="mscoree,mshtml="
mkdir -p ./Wine.AppDir/wineprefixnew
export WINEPREFIX=$(readlink -f ./Wine.AppDir/wineprefixnew)
./Wine.AppDir/AppRun wineboot.exe
./Wine.AppDir/AppRun wineboot.exe
sleep 5
# Need to ensure that we have system.reg userdef.reg user.reg, otherwise explorer.exe will not launch
ls -lh "$WINEPREFIX"
# echo "disable" > "$WINEPREFIX/.update-timestamp" # Stop Wine from updating $WINEPREFIX automatically from time to time # This leads to non-working WINEPREFIX!
( cd "$WINEPREFIX/drive_c/" ; rm -rf users ) || true # Do not hardcode username in wineprefix
ls -lh "$WINEPREFIX/"
mv ./Wine.AppDir/wineprefixnew ./Wine.AppDir/wineprefix && export WINEPREFIX=$(readlink -f ./Wine.AppDir/wineprefix)
wget -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x ./appimagetool-x86_64.AppImage
ARCH=x86_64 ./appimagetool-x86_64.AppImage -g ./Wine.AppDir
#
# Wine AppImage DONE. Now making a wineprefix for Notepad++
#
export VERSION=$(wget -q "https://notepad-plus-plus.org/repository/7.x/?C=M;O=D" -O - | grep href | grep '/"' | grep -v "unstable" | grep -v "repository" | cut -d ">" -f 6 | cut -d '"' -f 2| sed -e 's|/||g' | sort -r -V | uniq | head -n 1)
SHORTVERSION=$(echo $VERSION | cut -d "." -f 1).x
wget -c "https://notepad-plus-plus.org/repository/$SHORTVERSION/$VERSION/npp.$VERSION.bin.minimalist.7z"
7z x -o"$WINEPREFIX/drive_c/windows/system32/" npp*.7z # system32 is on Windows $PATH equivalent
# Perhaps we can make this generic so as to convert all from portableapps.com in the same way
# wget -c "http://download3.portableapps.com/portableapps/Notepad++Portable/NotepadPlusPlusPortable_7.6.paf.exe"
# 7z x -y -otmp NotepadPlusPlusPortable_7.6.paf.exe
# mv tmp/* "$WINEPREFIX/drive_c/windows/system32/"
# Icon
rm ./Wine.AppDir/*.{svg,svgz,png,xpm} ./Wine.AppDir/.DirIcon || true
wrestool -x -t 14 ./Wine.AppDir/wineprefix/drive_c/windows/system32/notepad++.exe > icon.ico
convert icon.ico icon.png
mkdir -p ./Wine.AppDir/usr/share/icons/hicolor/{256x256,48x48,16x16}/apps/
cp icon-3.png ./Wine.AppDir/usr/share/icons/hicolor/256x256/apps/notepadpp.png
cp icon-6.png ./Wine.AppDir/usr/share/icons/hicolor/48x48/apps/notepadpp.png
cp icon-8.png ./Wine.AppDir/usr/share/icons/hicolor/16x16/apps/notepadpp.png
cp icon-3.png ./Wine.AppDir/notepadpp.png
sed -i -e 's|^Icon=.*|Icon=notepadpp|g' ./Wine.AppDir/*.desktop
sed -i -e 's|^Name=.*|Name=NotepadPlusPlus|g' ./Wine.AppDir/*.desktop
sed -i -e 's|^Name\[.*||g' ./Wine.AppDir/*.desktop
sed -i -e 's|winecfg|notepad++.exe|g' ./Wine.AppDir/AppRun
ls -lh "$WINEPREFIX"
# Delete unneeded files
SQ=$(readlink -f .)/Wine.AppDir/
find Wine.AppDir/ -type f -or -type l > tmp.avail
while read p; do
readlink -f "$p" >> tmp.normalized.have
done <tmp.avail
sed -i -e 's|'$SQ'||g' tmp.normalized.have
while read p; do
if [[ $p =~ .*AppRun ]] || [[ $p =~ .*fuse.* ]] || [[ $p =~ .*copyright ]] || [[ $p =~ .*.desktop ]] || [[ $p =~ .*png ]] || [[ $p =~ .*svg ]] || [ ! -z "$(grep "$p" NotepadPlusPlus.manifest)" ] ; then
echo "KEEP $p"
else
echo rm "Wine.AppDir/$p"
rm "Wine.AppDir/$p" || true
fi
done <tmp.normalized.have
find Wine.AppDir/ -type d -empty -delete # Remove empty directories
ARCH=x86_64 ./appimagetool-x86_64.AppImage -g ./Wine.AppDir
( cd ./Wine.AppDir ; tar cfvz ../wineprefix.tar.gz wineprefix/ )