| author | wenzelm |
| Wed, 31 Aug 2022 20:54:23 +0200 | |
| changeset 76026 | 614a8feea80c |
| parent 75659 | 9bd92ac9328f |
| child 76098 | bcca0fbb8a34 |
| permissions | -rw-r--r-- |
| 64929 | 1 |
/* Title: Pure/Admin/build_jdk.scala |
2 |
Author: Makarius |
|
3 |
||
4 |
Build Isabelle jdk component from original platform installations. |
|
5 |
*/ |
|
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
|
73086
178c9d04e08c
more robust sharing, despite minimal impact on archive size;
wenzelm
parents:
73084
diff
changeset
|
10 |
import java.io.{File => JFile}
|
| 64933 | 11 |
import java.nio.file.Files |
| 64934 | 12 |
import java.nio.file.attribute.PosixFilePermission |
| 64933 | 13 |
|
| 64929 | 14 |
import scala.util.matching.Regex |
15 |
||
16 |
||
| 75393 | 17 |
object Build_JDK {
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
18 |
/* platform and version information */ |
| 64929 | 19 |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
20 |
sealed case class JDK_Platform( |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
21 |
platform_name: String, |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
22 |
platform_regex: Regex, |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
23 |
exe: String = "java", |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
24 |
macos_home: Boolean = false, |
| 75393 | 25 |
jdk_version: String = "" |
26 |
) {
|
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
27 |
override def toString: String = platform_name |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
28 |
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
29 |
def platform_path: Path = Path.explode(platform_name) |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
30 |
|
| 75393 | 31 |
def detect(jdk_dir: Path): Option[JDK_Platform] = {
|
32 |
val major_version = {
|
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
33 |
val Major_Version = """.*jdk(\d+).*$""".r |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
34 |
val jdk_name = jdk_dir.file.getName |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
35 |
jdk_name match {
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
36 |
case Major_Version(s) => s |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
37 |
case _ => error("Cannot determine major version from " + quote(jdk_name))
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
38 |
} |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
39 |
} |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
40 |
|
|
73082
e67d659d7a41
more direct ISABELLE_JDK_HOME, thanks to zulu-jdk directory layout;
wenzelm
parents:
73081
diff
changeset
|
41 |
val path = jdk_dir + Path.explode("bin") + Path.explode(exe)
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
42 |
if (path.is_file) {
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
43 |
val file_descr = Isabelle_System.bash("file -b " + File.bash_path(path)).check.out
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
44 |
if (platform_regex.pattern.matcher(file_descr).matches) {
|
| 74356 | 45 |
val Version = ("^(" + major_version + """[0-9.+]+)(?:-LTS)?$""").r
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
46 |
val version_lines = |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
47 |
Isabelle_System.bash("strings " + File.bash_path(path)).check
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
48 |
.out_lines.flatMap({ case Version(s) => Some(s) case _ => None })
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
49 |
version_lines match {
|
|
73082
e67d659d7a41
more direct ISABELLE_JDK_HOME, thanks to zulu-jdk directory layout;
wenzelm
parents:
73081
diff
changeset
|
50 |
case List(jdk_version) => Some(copy(jdk_version = jdk_version)) |
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
51 |
case _ => error("Expected unique version within executable " + path)
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
52 |
} |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
53 |
} |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
54 |
else None |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
55 |
} |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
56 |
else None |
| 64929 | 57 |
} |
58 |
} |
|
59 |
||
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
60 |
val templates: List[JDK_Platform] = |
| 66906 | 61 |
List( |
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
62 |
JDK_Platform("arm64-darwin", """.*Mach-O 64-bit.*arm64.*""".r, macos_home = true),
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
63 |
JDK_Platform("arm64-linux", """.*ELF 64-bit.*ARM aarch64.*""".r),
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
64 |
JDK_Platform("x86_64-darwin", """.*Mach-O 64-bit.*x86[-_]64.*""".r, macos_home = true),
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
65 |
JDK_Platform("x86_64-linux", """.*ELF 64-bit.*x86[-_]64.*""".r),
|
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
66 |
JDK_Platform("x86_64-windows", """.*PE32\+ executable.*x86[-_]64.*""".r, exe = "java.exe"))
|
| 64929 | 67 |
|
68 |
||
69 |
/* README */ |
|
70 |
||
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
71 |
def readme(jdk_version: String): String = |
|
75659
9bd92ac9328f
more robust Scala 3 indentation, for the sake of IntelliJ IDEA;
wenzelm
parents:
75394
diff
changeset
|
72 |
"""This is OpenJDK """ + jdk_version + """ based on downloads by Azul, see also |
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
73 |
https://www.azul.com/downloads/zulu-community/?package=jdk |
| 64929 | 74 |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
75 |
The main license is GPL2, but some modules are covered by other (more liberal) |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
76 |
licenses, see legal/* for details. |
| 64929 | 77 |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
78 |
Linux, Windows, macOS all work uniformly, depending on platform-specific |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
79 |
subdirectories. |
| 64929 | 80 |
""" |
81 |
||
82 |
||
83 |
/* settings */ |
|
84 |
||
|
73082
e67d659d7a41
more direct ISABELLE_JDK_HOME, thanks to zulu-jdk directory layout;
wenzelm
parents:
73081
diff
changeset
|
85 |
val settings: String = |
|
75659
9bd92ac9328f
more robust Scala 3 indentation, for the sake of IntelliJ IDEA;
wenzelm
parents:
75394
diff
changeset
|
86 |
"""# -*- shell-script -*- :mode=shellscript: |
| 64929 | 87 |
|
88 |
case "$ISABELLE_PLATFORM_FAMILY" in |
|
89 |
linux) |
|
| 66906 | 90 |
ISABELLE_JAVA_PLATFORM="$ISABELLE_PLATFORM64" |
| 64929 | 91 |
ISABELLE_JDK_HOME="$COMPONENT/$ISABELLE_JAVA_PLATFORM" |
92 |
;; |
|
93 |
windows) |
|
| 66906 | 94 |
ISABELLE_JAVA_PLATFORM="$ISABELLE_WINDOWS_PLATFORM64" |
| 64929 | 95 |
ISABELLE_JDK_HOME="$COMPONENT/$ISABELLE_JAVA_PLATFORM" |
96 |
;; |
|
97 |
macos) |
|
|
73082
e67d659d7a41
more direct ISABELLE_JDK_HOME, thanks to zulu-jdk directory layout;
wenzelm
parents:
73081
diff
changeset
|
98 |
if [ -n "$ISABELLE_APPLE_PLATFORM64" -a -d "$COMPONENT/$ISABELLE_APPLE_PLATFORM64" ] |
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
99 |
then |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
100 |
ISABELLE_JAVA_PLATFORM="$ISABELLE_APPLE_PLATFORM64" |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
101 |
else |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
102 |
ISABELLE_JAVA_PLATFORM="$ISABELLE_PLATFORM64" |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
103 |
fi |
|
73082
e67d659d7a41
more direct ISABELLE_JDK_HOME, thanks to zulu-jdk directory layout;
wenzelm
parents:
73081
diff
changeset
|
104 |
ISABELLE_JDK_HOME="$COMPONENT/$ISABELLE_JAVA_PLATFORM" |
| 64929 | 105 |
;; |
106 |
esac |
|
107 |
""" |
|
108 |
||
109 |
||
110 |
/* extract archive */ |
|
111 |
||
| 75393 | 112 |
def extract_archive(dir: Path, archive: Path): JDK_Platform = {
|
| 64929 | 113 |
try {
|
| 72376 | 114 |
val tmp_dir = Isabelle_System.make_directory(dir + Path.explode("tmp"))
|
| 69128 | 115 |
|
| 69367 | 116 |
if (archive.get_ext == "zip") {
|
| 69128 | 117 |
Isabelle_System.bash( |
118 |
"unzip -x " + File.bash_path(archive.absolute), cwd = tmp_dir.file).check |
|
119 |
} |
|
120 |
else {
|
|
| 69425 | 121 |
Isabelle_System.gnutar("-xzf " + File.bash_path(archive), dir = tmp_dir).check
|
| 69128 | 122 |
} |
123 |
||
| 64929 | 124 |
val dir_entry = |
| 73084 | 125 |
File.read_dir(tmp_dir) match {
|
| 64929 | 126 |
case List(s) => s |
127 |
case _ => error("Archive contains multiple directories")
|
|
128 |
} |
|
129 |
||
130 |
val jdk_dir = tmp_dir + Path.explode(dir_entry) |
|
131 |
val platform = |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
132 |
templates.view.flatMap(_.detect(jdk_dir)) |
|
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
133 |
.headOption.getOrElse(error("Failed to detect JDK platform"))
|
| 64929 | 134 |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
135 |
val platform_dir = dir + platform.platform_path |
| 64929 | 136 |
if (platform_dir.is_dir) error("Directory already exists: " + platform_dir)
|
| 69128 | 137 |
|
| 73317 | 138 |
Isabelle_System.move_file(jdk_dir, platform_dir) |
| 64929 | 139 |
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
140 |
platform |
| 64929 | 141 |
} |
142 |
catch { case ERROR(msg) => cat_error(msg, "The error(s) above occurred for " + archive) }
|
|
143 |
} |
|
144 |
||
145 |
||
146 |
/* build jdk */ |
|
147 |
||
148 |
def build_jdk( |
|
149 |
archives: List[Path], |
|
|
71726
a5fda30edae2
clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents:
71602
diff
changeset
|
150 |
progress: Progress = new Progress, |
| 75393 | 151 |
target_dir: Path = Path.current |
152 |
): Unit = {
|
|
| 64929 | 153 |
if (Platform.is_windows) error("Cannot build jdk on Windows")
|
154 |
||
| 75394 | 155 |
Isabelle_System.with_tmp_dir("jdk") { dir =>
|
156 |
progress.echo("Extracting ...")
|
|
157 |
val platforms = archives.map(extract_archive(dir, _)) |
|
| 64929 | 158 |
|
| 75394 | 159 |
val jdk_version = |
160 |
platforms.map(_.jdk_version).distinct match {
|
|
161 |
case List(version) => version |
|
162 |
case Nil => error("No archives")
|
|
163 |
case versions => |
|
164 |
error("Archives contain multiple JDK versions: " + commas_quote(versions))
|
|
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
165 |
} |
| 64929 | 166 |
|
| 75394 | 167 |
templates.filterNot(p1 => platforms.exists(p2 => p1.platform_name == p2.platform_name)) |
168 |
match {
|
|
169 |
case Nil => |
|
170 |
case missing => error("Missing platforms: " + commas_quote(missing.map(_.platform_name)))
|
|
171 |
} |
|
| 64929 | 172 |
|
| 75394 | 173 |
val jdk_name = "jdk-" + jdk_version |
174 |
val jdk_path = Path.explode(jdk_name) |
|
175 |
val component_dir = dir + jdk_path |
|
| 64929 | 176 |
|
| 75394 | 177 |
Isabelle_System.make_directory(component_dir + Path.explode("etc"))
|
178 |
File.write(Components.settings(component_dir), settings) |
|
179 |
File.write(component_dir + Path.explode("README"), readme(jdk_version))
|
|
180 |
||
181 |
for (platform <- platforms) {
|
|
182 |
Isabelle_System.move_file(dir + platform.platform_path, component_dir) |
|
183 |
} |
|
| 64929 | 184 |
|
| 75394 | 185 |
for (file <- File.find_files(component_dir.file, include_dirs = true)) {
|
186 |
val path = file.toPath |
|
187 |
val perms = Files.getPosixFilePermissions(path) |
|
188 |
perms.add(PosixFilePermission.OWNER_READ) |
|
189 |
perms.add(PosixFilePermission.GROUP_READ) |
|
190 |
perms.add(PosixFilePermission.OTHERS_READ) |
|
191 |
perms.add(PosixFilePermission.OWNER_WRITE) |
|
192 |
if (file.isDirectory) {
|
|
| 64934 | 193 |
perms.add(PosixFilePermission.OWNER_WRITE) |
| 75394 | 194 |
perms.add(PosixFilePermission.OWNER_EXECUTE) |
195 |
perms.add(PosixFilePermission.GROUP_EXECUTE) |
|
196 |
perms.add(PosixFilePermission.OTHERS_EXECUTE) |
|
| 64933 | 197 |
} |
| 75394 | 198 |
Files.setPosixFilePermissions(path, perms) |
199 |
} |
|
| 64931 | 200 |
|
| 75394 | 201 |
progress.echo("Archiving ...")
|
202 |
Isabelle_System.gnutar( |
|
203 |
"-czf " + File.bash_path(target_dir + jdk_path.tar.gz) + " " + jdk_name, dir = dir).check |
|
204 |
} |
|
| 64929 | 205 |
} |
206 |
||
207 |
||
208 |
/* Isabelle tool wrapper */ |
|
209 |
||
210 |
val isabelle_tool = |
|
| 69128 | 211 |
Isabelle_Tool("build_jdk", "build Isabelle jdk component from original archives",
|
| 75394 | 212 |
Scala_Project.here, |
213 |
{ args =>
|
|
214 |
var target_dir = Path.current |
|
| 64929 | 215 |
|
| 75394 | 216 |
val getopts = Getopts("""
|
| 65873 | 217 |
Usage: isabelle build_jdk [OPTIONS] ARCHIVES... |
| 64929 | 218 |
|
219 |
Options are: |
|
220 |
-D DIR target directory (default ".") |
|
221 |
||
| 69128 | 222 |
Build jdk component from tar.gz archives, with original jdk archives |
|
73081
120ffea2c244
prefer OpenJDK from Azul: supports more versions and platforms;
wenzelm
parents:
72894
diff
changeset
|
223 |
for Linux, Windows, and macOS. |
| 64929 | 224 |
""", |
| 75394 | 225 |
"D:" -> (arg => target_dir = Path.explode(arg))) |
| 64929 | 226 |
|
| 75394 | 227 |
val more_args = getopts(args) |
228 |
if (more_args.isEmpty) getopts.usage() |
|
| 64929 | 229 |
|
| 75394 | 230 |
val archives = more_args.map(Path.explode) |
231 |
val progress = new Console_Progress() |
|
| 64929 | 232 |
|
| 75394 | 233 |
build_jdk(archives = archives, progress = progress, target_dir = target_dir) |
234 |
}) |
|
| 64929 | 235 |
} |