| author | Fabian Huch <huch@in.tum.de> | 
| Fri, 23 Aug 2024 15:30:09 +0200 | |
| changeset 80949 | 97924a26a5c3 | 
| parent 80224 | db92e0b6a11a | 
| child 82480 | 489f4a79d215 | 
| permissions | -rw-r--r-- | 
| 72448 | 1 | /* Title: Pure/System/executable.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Support for platform-specific executables. | |
| 5 | */ | |
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 75393 | 10 | object Executable {
 | 
| 72460 | 11 | def libraries_closure(path: Path, | 
| 72454 | 12 | mingw: MinGW = MinGW.none, | 
| 79499 
d117821a5e82
always use patchelf on Linux: base-line is Ubuntu 18.04 where that works properly (see also e79294c4230c);
 wenzelm parents: 
78773diff
changeset | 13 | filter: String => Boolean = _ => true | 
| 75393 | 14 |   ): List[String] = {
 | 
| 72460 | 15 | val exe_path = path.expand | 
| 72454 | 16 | val exe_dir = exe_path.dir | 
| 17 | val exe = exe_path.base | |
| 72448 | 18 | |
| 75393 | 19 |     val ldd_lines = {
 | 
| 72454 | 20 | val ldd = if (Platform.is_macos) "otool -L" else "ldd" | 
| 21 | val script = mingw.bash_script(ldd + " " + File.bash_path(exe)) | |
| 80224 
db92e0b6a11a
clarified signature: prefer symbolic isabelle.Path over physical java.io.File;
 wenzelm parents: 
79499diff
changeset | 22 | split_lines(Isabelle_System.bash(script, cwd = exe_dir).check.out) | 
| 72448 | 23 | } | 
| 24 | ||
| 72454 | 25 | def lib_name(lib: String): String = | 
| 72468 | 26 | Library.take_prefix[Char](c => c != '.' && c != '-', | 
| 72454 | 27 | Library.take_suffix[Char](_ != '/', lib.toList)._2)._1.mkString | 
| 28 | ||
| 29 | val libs = | |
| 30 |       if (Platform.is_macos) {
 | |
| 31 | val Pattern = """^\s*(/.+)\s+\(.*\)$""".r | |
| 32 |         for {
 | |
| 78592 | 33 | case Pattern(lib) <- ldd_lines | 
| 72454 | 34 |           if !lib.startsWith("@executable_path/") && filter(lib_name(lib))
 | 
| 35 | } yield lib | |
| 36 | } | |
| 37 |       else {
 | |
| 38 | val Pattern = """^.*=>\s*(/.+)\s+\(.*\)$""".r | |
| 39 | val prefix = | |
| 40 |           mingw.root match {
 | |
| 41 | case None => "" | |
| 42 | case Some(path) => path.absolute.implode | |
| 43 | } | |
| 78592 | 44 |         for { case Pattern(lib) <- ldd_lines if filter(lib_name(lib)) }
 | 
| 72454 | 45 | yield prefix + lib | 
| 46 | } | |
| 47 | ||
| 48 |     if (libs.nonEmpty) {
 | |
| 73317 | 49 | libs.foreach(lib => Isabelle_System.copy_file(Path.explode(lib), exe_dir)) | 
| 72454 | 50 | |
| 51 |       if (Platform.is_linux) {
 | |
| 79499 
d117821a5e82
always use patchelf on Linux: base-line is Ubuntu 18.04 where that works properly (see also e79294c4230c);
 wenzelm parents: 
78773diff
changeset | 52 |         Isabelle_System.require_command("patchelf")
 | 
| 
d117821a5e82
always use patchelf on Linux: base-line is Ubuntu 18.04 where that works properly (see also e79294c4230c);
 wenzelm parents: 
78773diff
changeset | 53 |         Isabelle_System.bash("patchelf --force-rpath --set-rpath '$ORIGIN' " + File.bash_path(exe_path)).check
 | 
| 72454 | 54 | } | 
| 55 |       else if (Platform.is_macos) {
 | |
| 56 | val script = | |
| 57 |           ("install_name_tool" ::
 | |
| 58 | libs.map(file => "-change " + Bash.string(file) + " " + | |
| 59 |               Bash.string("@executable_path/" + Path.explode(file).file_name) + " " +
 | |
| 60 |               File.bash_path(exe))).mkString(" ")
 | |
| 80224 
db92e0b6a11a
clarified signature: prefer symbolic isabelle.Path over physical java.io.File;
 wenzelm parents: 
79499diff
changeset | 61 | Isabelle_System.bash(script, cwd = exe_dir).check | 
| 72448 | 62 | } | 
| 63 | } | |
| 72454 | 64 | |
| 65 | libs | |
| 72448 | 66 | } | 
| 67 | } |