summaryrefslogtreecommitdiffstats
path: root/tools/package.sh
blob: ce18f6372410eae34c069d159c3d4ca9111325bf (plain)
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
#!/bin/bash

set -e
cd "$(dirname "$0")/.."
. tools/_util.sh

bash tools/build.sh

DIST=build/dist
rm -rf "$DIST"
mkdir -p "$DIST"

echo "=== Staging runtime libs beside the jars ==="
for d in $RUNTIME_LIB_DIRS; do
  mkdir -p "$DIST/lib/$d"
  n=0
  for j in lib/"$d"/*.jar; do
    is_shippable_jar "$j" || continue # never ship -sources / -javadoc
    cp "$j" "$DIST/lib/$d/"
    n=$((n + 1))
  done
  for dll in lib/"$d"/*.dll; do
    [ -f "$dll" ] || continue # e.g. openjfx's native Prism/Glass libraries
    cp "$dll" "$DIST/lib/$d/"
  done
  echo "  lib/$d/ ($n jars)"
done

echo "=== Generating executable manifests ==="
# Generated from what is actually staged, never hand-maintained. Four silent
# failure modes: wildcards match nothing; a missing trailing newline makes jar
# drop the line; paths are relative to this jar; and java -jar ignores -cp, so
# this line is the entire classpath at runtime.
for e in $EXECUTABLES; do
  CPLINE=""
  for m in $MODULES; do
    [ "$m" = "$e" ] && continue
    CPLINE="$CPLINE${CPLINE:+ }$m.jar"
  done
  for d in $RUNTIME_LIB_DIRS; do
    for j in "$DIST"/lib/"$d"/*.jar; do
      [ -f "$j" ] || continue
      CPLINE="$CPLINE lib/$d/$(basename "$j")"
    done
  done
  write_manifest_attr "$TMP/$e-manifest.txt" "Class-Path" "$CPLINE"
  echo "  $e: $CPLINE"
done

echo "=== Packaging ==="
for m in $MODULES; do
  case " $EXECUTABLES " in
  *" $m "*)
    "$JAR" --create --file "$DIST/$m.jar" --main-class "$(mainclass_of "$m")" \
      --manifest "$TMP/$m-manifest.txt" -C "build/classes/$m" .
    ;;
  *)
    "$JAR" --create --file "$DIST/$m.jar" -C "build/classes/$m" .
    ;;
  esac
  echo "  $DIST/$m.jar"
done

for e in $EXECUTABLES; do
  cat >"$DIST/run-${e#ui-}.bat" <<EOF
@echo off
cd /d "%~dp0"
java -Djava.library.path="%~dp0lib\openjfx" -jar "%~dp0$e.jar"
if errorlevel 1 pause
EOF
done

[ -f README.pdf ] && cp README.pdf "$DIST/"

echo "=== Manifest as it actually landed in the jar ==="
# Cheapest check that prevents a Level-0: if Main-Class or Class-Path didn't
# survive, it surfaces here instead of on the grader's machine.
for e in $EXECUTABLES; do
  rm -rf "$TMP/mf" && mkdir -p "$TMP/mf"
  (cd "$TMP/mf" && "$JAR" -xf "$OLDPWD/$DIST/$e.jar" META-INF/MANIFEST.MF)
  echo "-- $e.jar --"
  sed 's/^/  /' "$TMP/mf/META-INF/MANIFEST.MF"

  grep -q '^Main-Class:' "$TMP/mf/META-INF/MANIFEST.MF" || {
    echo "*** Main-Class missing in $e.jar ***"
    exit 1
  }
  grep -q 'Class-Path:' "$TMP/mf/META-INF/MANIFEST.MF" || {
    echo "*** Class-Path missing in $e.jar ***"
    exit 1
  }
done

echo "======================================"
echo "Self-contained output in $DIST"
for e in $EXECUTABLES; do
  echo "  cd $DIST && java -jar $e.jar"
done
echo "======================================"