@@ -690,65 +690,80 @@ private static Path ensureLauncher(Launcher launcherArgs, BuildToolLog log) thro
690690 }
691691 }
692692
693- private static void generateLaunchers (Launcher launcherArgs , BuildToolLog log ) throws IOException {
694- if (!Files .exists (launcherArgs .launcherPath )) {
695- info (log , "Generating GraalPy launchers" );
696- createParentDirectories (launcherArgs .launcherPath );
697- Path java = Paths .get (System .getProperty ("java.home" ), "bin" , "java" );
698- String classpath = String .join (File .pathSeparator , launcherArgs .computeClassPath ());
699- if (!IS_WINDOWS ) {
700- var script = String .format ("""
701- #!/usr/bin/env bash
702- %s --enable-native-access=ALL-UNNAMED -classpath %s %s --python.Executable="$0" "$@"
703- """ ,
704- java ,
705- String .join (File .pathSeparator , classpath ),
706- GRAALPY_MAIN_CLASS );
707- try {
708- Files .writeString (launcherArgs .launcherPath , script );
709- var perms = Files .getPosixFilePermissions (launcherArgs .launcherPath );
710- perms .addAll (List .of (PosixFilePermission .OWNER_EXECUTE , PosixFilePermission .GROUP_EXECUTE , PosixFilePermission .OTHERS_EXECUTE ));
711- Files .setPosixFilePermissions (launcherArgs .launcherPath , perms );
712- } catch (IOException e ) {
713- throw new IOException (String .format ("failed to create launcher %s" , launcherArgs .launcherPath ), e );
714- }
715- } else {
716- // on windows, generate a venv launcher that executes our mvn target
717- var script = String .format ("""
718- import os, shutil, struct, venv
719- from pathlib import Path
720- vl = os.path.join(venv.__path__[0], 'scripts', 'nt', 'graalpy.exe')
721- tl = os.path.join(r'%s')
722- os.makedirs(Path(tl).parent.absolute(), exist_ok=True)
723- shutil.copy(vl, tl)
724- cmd = r'%s --enable-native-access=ALL-UNNAMED -classpath "%s" %s'
725- pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg")
726- with open(pyvenvcfg, 'w', encoding='utf-8') as f:
727- f.write('venvlauncher_command = ')
728- f.write(cmd)
729- """ ,
730- launcherArgs .launcherPath ,
731- java ,
732- classpath ,
733- GRAALPY_MAIN_CLASS );
734- File tmp ;
735- try {
736- tmp = File .createTempFile ("create_launcher" , ".py" );
737- } catch (IOException e ) {
738- throw new IOException ("failed to create tmp launcher" , e );
739- }
740- tmp .deleteOnExit ();
741- try (var wr = new FileWriter (tmp )) {
742- wr .write (script );
743- } catch (IOException e ) {
744- throw new IOException (String .format ("failed to write tmp launcher %s" , tmp ), e );
693+ private static boolean checkWinLauncherJavaPath (Path venvCfg , Path java ) {
694+ try {
695+ for (String line : Files .readAllLines (venvCfg )) {
696+ if (line .trim ().startsWith ("venvlauncher_command = " + java )) {
697+ return true ;
745698 }
699+ }
700+ } catch (IOException ignore ) {
701+ }
702+ return false ;
703+ }
746704
747- try {
748- GraalPyRunner .run (classpath , log , tmp .getAbsolutePath ());
749- } catch (InterruptedException e ) {
750- throw new IOException (String .format ("failed to run Graalpy launcher" ), e );
751- }
705+ private static void generateLaunchers (Launcher launcherArgs , BuildToolLog log ) throws IOException {
706+ debug (log , "Generating GraalPy launchers" );
707+ createParentDirectories (launcherArgs .launcherPath );
708+ Path java = Paths .get (System .getProperty ("java.home" ), "bin" , "java" );
709+ String classpath = String .join (File .pathSeparator , launcherArgs .computeClassPath ());
710+ String extraJavaOptions = String .join (" " , GraalPyRunner .getExtraJavaOptions ());
711+ if (!IS_WINDOWS ) {
712+ // we do not bother checking if it exists and has correct java home, since it is simple
713+ // to regenerate the launcher
714+ var script = String .format ("""
715+ #!/usr/bin/env bash
716+ %s --enable-native-access=ALL-UNNAMED %s -classpath %s %s --python.Executable="$0" "$@"
717+ """ ,
718+ java ,
719+ extraJavaOptions ,
720+ String .join (File .pathSeparator , classpath ),
721+ GRAALPY_MAIN_CLASS );
722+ try {
723+ Files .writeString (launcherArgs .launcherPath , script );
724+ var perms = Files .getPosixFilePermissions (launcherArgs .launcherPath );
725+ perms .addAll (List .of (PosixFilePermission .OWNER_EXECUTE , PosixFilePermission .GROUP_EXECUTE , PosixFilePermission .OTHERS_EXECUTE ));
726+ Files .setPosixFilePermissions (launcherArgs .launcherPath , perms );
727+ } catch (IOException e ) {
728+ throw new IOException (String .format ("failed to create launcher %s" , launcherArgs .launcherPath ), e );
729+ }
730+ } else if (!Files .exists (launcherArgs .launcherPath ) || !checkWinLauncherJavaPath (launcherArgs .launcherPath .getParent ().resolve ("pyenv.cfg" ), java )) {
731+ // on windows, generate a venv launcher that executes the java command
732+ var script = String .format ("""
733+ import os, shutil, struct, venv
734+ from pathlib import Path
735+ vl = os.path.join(venv.__path__[0], 'scripts', 'nt', 'graalpy.exe')
736+ tl = os.path.join(r'%s')
737+ os.makedirs(Path(tl).parent.absolute(), exist_ok=True)
738+ shutil.copy(vl, tl)
739+ cmd = r'%s --enable-native-access=ALL-UNNAMED %s -classpath "%s" %s'
740+ pyvenvcfg = os.path.join(os.path.dirname(tl), "pyvenv.cfg")
741+ with open(pyvenvcfg, 'w', encoding='utf-8') as f:
742+ f.write('venvlauncher_command = ')
743+ f.write(cmd)
744+ """ ,
745+ launcherArgs .launcherPath ,
746+ java ,
747+ extraJavaOptions ,
748+ classpath ,
749+ GRAALPY_MAIN_CLASS );
750+ File tmp ;
751+ try {
752+ tmp = File .createTempFile ("create_launcher" , ".py" );
753+ } catch (IOException e ) {
754+ throw new IOException ("failed to create tmp launcher" , e );
755+ }
756+ tmp .deleteOnExit ();
757+ try (var wr = new FileWriter (tmp )) {
758+ wr .write (script );
759+ } catch (IOException e ) {
760+ throw new IOException (String .format ("failed to write tmp launcher %s" , tmp ), e );
761+ }
762+
763+ try {
764+ GraalPyRunner .run (classpath , log , tmp .getAbsolutePath ());
765+ } catch (InterruptedException e ) {
766+ throw new IOException ("failed to run Graalpy launcher" , e );
752767 }
753768 }
754769 }
0 commit comments