1 #!/usr/bin/env bash |
|
2 # |
|
3 # DESCRIPTION: re-package Isabelle distribution with add-on components |
|
4 |
|
5 ## diagnostics |
|
6 |
|
7 PRG=$(basename "$0") |
|
8 |
|
9 function usage() |
|
10 { |
|
11 echo |
|
12 echo "Usage: isabelle $PRG ARCHIVE PLATFORM_FAMILY [REMOTE_MAC]" |
|
13 echo |
|
14 echo " Re-package Isabelle source distribution with add-on components and" |
|
15 echo " post-hoc patches for platform family linux, windows, macos." |
|
16 echo |
|
17 echo " The optional remote Mac OS X system is used for dmg build." |
|
18 echo |
|
19 echo " Add-on components are that of the running Isabelle version!" |
|
20 echo |
|
21 exit 1 |
|
22 } |
|
23 |
|
24 function fail() |
|
25 { |
|
26 echo "$1" >&2 |
|
27 exit 2 |
|
28 } |
|
29 |
|
30 |
|
31 ## arguments |
|
32 |
|
33 [ "$#" -ne 2 -a "$#" -ne 3 ] && usage |
|
34 |
|
35 ARCHIVE="$1"; shift |
|
36 PLATFORM_FAMILY="$1"; shift |
|
37 REMOTE_MAC="$1"; shift |
|
38 |
|
39 [ -f "$ARCHIVE" ] || fail "Bad source archive: $ARCHIVE" |
|
40 |
|
41 ARCHIVE_DIR="$(cd $(dirname "$ARCHIVE"); echo "$PWD")" |
|
42 ISABELLE_NAME="$(basename "$ARCHIVE" .tar.gz)" |
|
43 |
|
44 |
|
45 ## main |
|
46 |
|
47 #GNU tar (notably on Mac OS X) |
|
48 type -p gnutar >/dev/null && function tar() { gnutar "$@"; } |
|
49 |
|
50 TMP="/var/tmp/isabelle-makedist$$" |
|
51 mkdir "$TMP" || fail "Cannot create directory $TMP" |
|
52 |
|
53 ISABELLE_TARGET="$TMP/$ISABELLE_NAME" |
|
54 |
|
55 tar -C "$TMP" -x -z -f "$ARCHIVE" || exit 2 |
|
56 |
|
57 |
|
58 # distribution classpath (based on educated guesses) |
|
59 |
|
60 splitarray ":" "$ISABELLE_CLASSPATH"; CLASSPATH_ENTRIES=("${SPLITARRAY[@]}") |
|
61 declare -a DISTRIBUTION_CLASSPATH=() |
|
62 |
|
63 for ENTRY in "${CLASSPATH_ENTRIES[@]}" |
|
64 do |
|
65 ENTRY=$(echo "$ENTRY" | perl -n -e " |
|
66 if (m,$ISABELLE_HOME/(.*)\$,) { print qq{\$1}; } |
|
67 elsif (m,$USER_HOME/.isabelle/contrib/(.*)\$,) { print qq{contrib/\$1}; } |
|
68 elsif (m,/home/isabelle/contrib/(.*)\$,) { print qq{contrib/\$1}; } |
|
69 else { print; }; |
|
70 print qq{\n};") |
|
71 DISTRIBUTION_CLASSPATH["${#DISTRIBUTION_CLASSPATH[@]}"]="$ENTRY" |
|
72 done |
|
73 |
|
74 DISTRIBUTION_CLASSPATH["${#DISTRIBUTION_CLASSPATH[@]}"]="src/Tools/jEdit/dist/jedit.jar" |
|
75 |
|
76 echo "classpath" |
|
77 for ENTRY in "${DISTRIBUTION_CLASSPATH[@]}" |
|
78 do |
|
79 echo " $ENTRY" |
|
80 done |
|
81 |
|
82 |
|
83 # bundled components |
|
84 |
|
85 if [ ! -e "$ARCHIVE_DIR/contrib" ]; then |
|
86 if [ ! -e "$ARCHIVE_DIR/../contrib" ]; then |
|
87 mkdir -p "$ARCHIVE_DIR/contrib" |
|
88 else |
|
89 ln -s "../contrib" "$ARCHIVE_DIR/contrib" |
|
90 fi |
|
91 fi |
|
92 |
|
93 echo "#bundled components" >> "$ISABELLE_TARGET/etc/components" |
|
94 |
|
95 for CATALOG in main "$PLATFORM_FAMILY" bundled "bundled-$PLATFORM_FAMILY" |
|
96 do |
|
97 CATALOG_FILE="$ISABELLE_HOME/Admin/components/$CATALOG" |
|
98 if [ -f "$CATALOG_FILE" ] |
|
99 then |
|
100 echo "catalog ${CATALOG}" |
|
101 { |
|
102 while { unset REPLY; read -r; test "$?" = 0 -o -n "$REPLY"; } |
|
103 do |
|
104 case "$REPLY" in |
|
105 \#* | "") ;; |
|
106 *) |
|
107 COMPONENT="$REPLY" |
|
108 COMPONENT_DIR="$ISABELLE_TARGET/contrib/$COMPONENT" |
|
109 case "$COMPONENT" in |
|
110 jedit_build*) ;; |
|
111 *) |
|
112 echo " component $COMPONENT" |
|
113 CONTRIB="$ARCHIVE_DIR/contrib/${COMPONENT}.tar.gz" |
|
114 if [ ! -f "$CONTRIB" ]; then |
|
115 type -p curl > /dev/null || fail "Cannot download files: missing curl" |
|
116 REMOTE="$ISABELLE_COMPONENT_REPOSITORY/${COMPONENT}.tar.gz" |
|
117 echo " downloading $REMOTE" |
|
118 curl --fail --silent "$REMOTE" > "$CONTRIB" || \ |
|
119 fail "Failed to download \"$REMOTE\"" |
|
120 perl -e "exit((stat('${CONTRIB}'))[7] == 0 ? 0 : 1);" && exit 2 |
|
121 fi |
|
122 |
|
123 tar -C "$ISABELLE_TARGET/contrib" -x -z -f "$CONTRIB" || exit 2 |
|
124 if [ -f "$COMPONENT_DIR/etc/settings" -o -f "$COMPONENT_DIR/etc/components" ] |
|
125 then |
|
126 case "$COMPONENT" in |
|
127 jdk-*) |
|
128 mv "$ISABELLE_TARGET/contrib/$COMPONENT" "$ISABELLE_TARGET/contrib/jdk" |
|
129 echo "contrib/jdk" >> "$ISABELLE_TARGET/etc/components" |
|
130 ;; |
|
131 *) |
|
132 echo "contrib/$COMPONENT" >> "$ISABELLE_TARGET/etc/components" |
|
133 ;; |
|
134 esac |
|
135 fi |
|
136 ;; |
|
137 esac |
|
138 ;; |
|
139 esac |
|
140 done |
|
141 } < "$CATALOG_FILE" |
|
142 fi |
|
143 done |
|
144 |
|
145 |
|
146 # purge other platforms |
|
147 |
|
148 function purge_target |
|
149 { |
|
150 ( |
|
151 cd "$ISABELLE_TARGET" |
|
152 for DIR in $(eval find "$@" | sort) |
|
153 do |
|
154 echo "removing $DIR" |
|
155 rm -rf "$DIR" |
|
156 done |
|
157 ) |
|
158 } |
|
159 |
|
160 |
|
161 # platform-specific setup (inside archive) |
|
162 |
|
163 case "$PLATFORM_FAMILY" in |
|
164 linux) |
|
165 purge_target 'contrib -name "x86*-darwin" -o -name "x86*-cygwin" -o -name "x86*-windows"' |
|
166 |
|
167 ( |
|
168 init_component "$JEDIT_HOME" |
|
169 |
|
170 echo "# Java runtime options" |
|
171 eval "declare -a JAVA_ARGS=($ISABELLE_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_OPTIONS)" |
|
172 for ARG in "${JAVA_ARGS[@]}" |
|
173 do |
|
174 echo "$ARG" |
|
175 done |
|
176 echo "-Disabelle.jedit_server=${ISABELLE_NAME}" |
|
177 ) > "$ISABELLE_TARGET/${ISABELLE_NAME}.options" |
|
178 |
|
179 LINUX_CLASSPATH="" |
|
180 for ENTRY in "${DISTRIBUTION_CLASSPATH[@]}" |
|
181 do |
|
182 if [ -z "$LINUX_CLASSPATH" ]; then |
|
183 LINUX_CLASSPATH="\\\$ISABELLE_HOME/$ENTRY" |
|
184 else |
|
185 LINUX_CLASSPATH="$LINUX_CLASSPATH:\\\$ISABELLE_HOME/$ENTRY" |
|
186 fi |
|
187 done |
|
188 |
|
189 cat "$ISABELLE_HOME/Admin/Linux/Isabelle.run" | \ |
|
190 perl -p > "$ISABELLE_TARGET/${ISABELLE_NAME}.run" -e "s,{CLASSPATH},$LINUX_CLASSPATH,;" |
|
191 chmod +x "$ISABELLE_TARGET/${ISABELLE_NAME}.run" |
|
192 |
|
193 mv "$ISABELLE_TARGET/contrib/linux_app" "$TMP/." |
|
194 cp "$TMP/linux_app/Isabelle" "$ISABELLE_TARGET/$ISABELLE_NAME" |
|
195 ;; |
|
196 macos) |
|
197 purge_target 'contrib -name "x86*-linux" -o -name "x86*-cygwin" -o -name "x86*-windows"' |
|
198 mv "$ISABELLE_TARGET/contrib/macos_app" "$TMP/." |
|
199 |
|
200 perl -pi \ |
|
201 -e "s,lookAndFeel=.*,lookAndFeel=com.apple.laf.AquaLookAndFeel,g;" \ |
|
202 -e "s,delete-line.shortcut=.*,delete-line.shortcut=C+d,g;" \ |
|
203 -e "s,delete.shortcut2=.*,delete.shortcut2=A+d,g;" \ |
|
204 -e "s,plugin-blacklist.MacOSX.jar=true,plugin-blacklist.MacOSX.jar=,g;" \ |
|
205 "$ISABELLE_TARGET/src/Tools/jEdit/dist/properties/jEdit.props" |
|
206 ;; |
|
207 windows) |
|
208 purge_target 'contrib -name "x86*-linux" -o -name "x86*-darwin" -o -name "x86-cygwin"' |
|
209 |
|
210 mv "$ISABELLE_TARGET/contrib/windows_app" "$TMP/." |
|
211 |
|
212 perl -pi \ |
|
213 -e "s,lookAndFeel=.*,lookAndFeel=com.sun.java.swing.plaf.windows.WindowsLookAndFeel,g;" \ |
|
214 -e "s,foldPainter=.*,foldPainter=Square,g;" \ |
|
215 "$ISABELLE_TARGET/src/Tools/jEdit/dist/properties/jEdit.props" |
|
216 |
|
217 ( |
|
218 init_component "$JEDIT_HOME" |
|
219 |
|
220 echo -e "# Java runtime options\r" |
|
221 eval "declare -a JAVA_ARGS=($ISABELLE_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_OPTIONS)" |
|
222 for ARG in "${JAVA_ARGS[@]}" |
|
223 do |
|
224 echo -e "$ARG\r" |
|
225 done |
|
226 echo -e "-Disabelle.jedit_server=${ISABELLE_NAME}\r" |
|
227 ) > "$ISABELLE_TARGET/${ISABELLE_NAME}.l4j.ini" |
|
228 |
|
229 ( |
|
230 cd "$TMP" |
|
231 |
|
232 APP_TEMPLATE="$ISABELLE_HOME/Admin/Windows/launch4j" |
|
233 |
|
234 ( |
|
235 for ENTRY in "${DISTRIBUTION_CLASSPATH[@]}" |
|
236 do |
|
237 ENTRY=$(echo "$ENTRY" | perl -p -e 's,/,\\\\,g;') |
|
238 echo " <cp>%EXEDIR%\\\\$ENTRY</cp>" |
|
239 done |
|
240 ) > exe_classpath |
|
241 EXE_CLASSPATH="$(cat exe_classpath)" |
|
242 |
|
243 perl -p \ |
|
244 -e "s,{OUTFILE},$ISABELLE_TARGET/${ISABELLE_NAME}.exe,g;" \ |
|
245 -e "s,{ICON},$APP_TEMPLATE/isabelle_transparent.ico,g;" \ |
|
246 -e "s,{SPLASH},$APP_TEMPLATE/isabelle.bmp,g;" \ |
|
247 -e "s,{CLASSPATH},$EXE_CLASSPATH,g;" \ |
|
248 -e "s,{ISABELLE_NAME},$ISABELLE_NAME,g;" \ |
|
249 "$APP_TEMPLATE/isabelle.xml" > isabelle.xml |
|
250 |
|
251 "windows_app/launch4j-${ISABELLE_PLATFORM_FAMILY}/launch4j" isabelle.xml |
|
252 |
|
253 cp "$APP_TEMPLATE/manifest.xml" "$ISABELLE_TARGET/${ISABELLE_NAME}.exe.manifest" |
|
254 ) |
|
255 |
|
256 ( |
|
257 cd "$ISABELLE_TARGET" |
|
258 |
|
259 cp "$ISABELLE_HOME/Admin/Windows/Cygwin/Cygwin-Terminal.bat" . |
|
260 |
|
261 CYGWIN_MIRROR="$(cat contrib/cygwin/isabelle/cygwin_mirror)" |
|
262 cat "$ISABELLE_HOME/Admin/Windows/Cygwin/Cygwin-Setup.bat" | \ |
|
263 perl -p > "Cygwin-Setup.bat" -e "s,{MIRROR},$CYGWIN_MIRROR,;" |
|
264 chmod +x "Cygwin-Setup.bat" |
|
265 |
|
266 for NAME in postinstall rebaseall |
|
267 do |
|
268 cp -a "$ISABELLE_HOME/Admin/Windows/Cygwin/isabelle/$NAME" \ |
|
269 "contrib/cygwin/isabelle/." |
|
270 done |
|
271 |
|
272 if [ "$ISABELLE_PLATFORM_FAMILY" = macos ]; then |
|
273 find . -type f -not -name '*.exe' -not -name '*.dll' -perm +100 \ |
|
274 -print0 > "contrib/cygwin/isabelle/executables" |
|
275 else |
|
276 find . -type f -not -name '*.exe' -not -name '*.dll' -executable \ |
|
277 -print0 > "contrib/cygwin/isabelle/executables" |
|
278 fi |
|
279 |
|
280 find . -type l -exec echo "{}" ";" -exec readlink "{}" ";" \ |
|
281 > "contrib/cygwin/isabelle/symlinks" |
|
282 find . -type l -exec rm "{}" ";" |
|
283 |
|
284 touch "contrib/cygwin/isabelle/uninitialized" |
|
285 ) |
|
286 ;; |
|
287 *) |
|
288 ;; |
|
289 esac |
|
290 |
|
291 |
|
292 # archive |
|
293 |
|
294 BUNDLE_ARCHIVE="${ARCHIVE_DIR}/${ISABELLE_NAME}_${PLATFORM_FAMILY}.tar.gz" |
|
295 |
|
296 echo "packaging $(basename "$BUNDLE_ARCHIVE")" |
|
297 tar -C "$TMP" -c -z -f "$BUNDLE_ARCHIVE" "$ISABELLE_NAME" || exit 2 |
|
298 |
|
299 |
|
300 # platform-specific setup (outside archive) |
|
301 |
|
302 case "$PLATFORM_FAMILY" in |
|
303 linux) |
|
304 echo "application for $PLATFORM_FAMILY" |
|
305 ln -s "${ISABELLE_NAME}_linux.tar.gz" "${ARCHIVE_DIR}/${ISABELLE_NAME}_app.tar.gz" |
|
306 ;; |
|
307 macos) |
|
308 echo "application for $PLATFORM_FAMILY" |
|
309 ( |
|
310 cd "$TMP" |
|
311 |
|
312 APP_TEMPLATE="$ISABELLE_HOME/Admin/MacOS" |
|
313 APP="dmg/${ISABELLE_NAME}.app" |
|
314 |
|
315 mkdir -p "dmg/.background" |
|
316 cp "$APP_TEMPLATE/dmg/background.png" "dmg/.background/" |
|
317 cp "$APP_TEMPLATE/dmg/DS_Store" "dmg/.DS_Store" |
|
318 ln -s /Applications "dmg/." |
|
319 |
|
320 for NAME in Java MacOS PlugIns Resources |
|
321 do |
|
322 mkdir -p "$APP/Contents/$NAME" |
|
323 done |
|
324 |
|
325 ( |
|
326 init_component "$JEDIT_HOME" |
|
327 |
|
328 cat "$APP_TEMPLATE/Info.plist-part1" |
|
329 |
|
330 declare -a OPTIONS=() |
|
331 eval "OPTIONS=($ISABELLE_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_SYSTEM_OPTIONS $JEDIT_JAVA_OPTIONS)" |
|
332 for OPT in "${OPTIONS[@]}" |
|
333 do |
|
334 echo "<string>$OPT</string>" |
|
335 done |
|
336 echo "<string>-Disabelle.jedit_server={ISABELLE_NAME}</string>" |
|
337 echo "<string>-Dapple.awt.application.name={ISABELLE_NAME}</string>" |
|
338 |
|
339 cat "$APP_TEMPLATE/Info.plist-part2" |
|
340 ) | perl -p -e "s,{ISABELLE_NAME},${ISABELLE_NAME},g;" > "$APP/Contents/Info.plist" |
|
341 |
|
342 for ENTRY in "${DISTRIBUTION_CLASSPATH[@]}" |
|
343 do |
|
344 ln -sf "../Resources/${ISABELLE_NAME}/$ENTRY" "$APP/Contents/Java" |
|
345 done |
|
346 |
|
347 cp -R "$APP_TEMPLATE/Resources/." "$APP/Contents/Resources/." |
|
348 |
|
349 ln -sf "../Resources/${ISABELLE_NAME}/contrib/jdk/x86_64-darwin" \ |
|
350 "$APP/Contents/PlugIns/bundled.jdk" |
|
351 |
|
352 cp macos_app/JavaAppLauncher "$APP/Contents/MacOS/." && \ |
|
353 chmod +x "$APP/Contents/MacOS/JavaAppLauncher" |
|
354 |
|
355 mv "$ISABELLE_NAME" "$APP/Contents/Resources/." |
|
356 ln -sf "../../Info.plist" "$APP/Contents/Resources/$ISABELLE_NAME/${ISABELLE_NAME}.plist" |
|
357 ln -sf "Contents/Resources/$ISABELLE_NAME" "$APP/Isabelle" |
|
358 |
|
359 rm -f "${ARCHIVE_DIR}/${ISABELLE_NAME}.dmg" |
|
360 tar -C dmg -czf "${ARCHIVE_DIR}/${ISABELLE_NAME}_dmg.tar.gz" . |
|
361 |
|
362 if [ -n "$REMOTE_MAC" ] |
|
363 then |
|
364 echo -n "$REMOTE_MAC: building dmg ..." |
|
365 isabelle remote_dmg -V Isabelle "$REMOTE_MAC" \ |
|
366 "${ARCHIVE_DIR}/${ISABELLE_NAME}_dmg.tar.gz" "${ARCHIVE_DIR}/${ISABELLE_NAME}.dmg" && |
|
367 echo " done" |
|
368 fi |
|
369 ) |
|
370 ;; |
|
371 windows) |
|
372 ( |
|
373 cd "$TMP" |
|
374 rm -f "$TMP/${ISABELLE_NAME}.7z" |
|
375 7z -y -bd a "$TMP/${ISABELLE_NAME}.7z" "$ISABELLE_NAME" |
|
376 [ -f "$TMP/${ISABELLE_NAME}.7z" ] || exit 2 |
|
377 |
|
378 echo "application for $PLATFORM_FAMILY" |
|
379 ( |
|
380 cat "windows_app/7zsd_All_x64.sfx" |
|
381 cat "$ISABELLE_HOME/Admin/Windows/Installer/sfx.txt" | \ |
|
382 perl -p -e "s,{ISABELLE_NAME},${ISABELLE_NAME},g;" |
|
383 cat "$TMP/${ISABELLE_NAME}.7z" |
|
384 ) > "${ARCHIVE_DIR}/${ISABELLE_NAME}.exe" |
|
385 chmod +x "${ARCHIVE_DIR}/${ISABELLE_NAME}.exe" |
|
386 ) |
|
387 ;; |
|
388 *) |
|
389 ;; |
|
390 esac |
|
391 |
|
392 |
|
393 # clean up |
|
394 rm -rf "$TMP" |
|