-
-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Windows launcher #791
Fix Windows launcher #791
Changes from all commits
d1a3fe7
15224aa
a833b11
304b1b6
f5e1175
40534e7
9635599
44beeea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -620,27 +620,13 @@ object dev extends MillModule{ | |
) | ||
).distinct | ||
|
||
|
||
// Pass dev.assembly VM options via file in Windows due to small max args limit | ||
def windowsVmOptions(taskName: String, batch: os.Path, args: Seq[String]) | ||
(implicit ctx: mill.util.Ctx) = { | ||
if (System.getProperty("java.specification.version").startsWith("1.")) { | ||
throw new Error(s"$taskName in Windows is only supported using Java 9 or above") | ||
} | ||
val vmOptionsFile = T.ctx.dest / "mill.vmoptions" | ||
T.ctx.log.info(s"Generated $vmOptionsFile; it should be kept in the same directory as $taskName's ${batch.last}") | ||
os.write(vmOptionsFile, args.mkString("\r\n")) | ||
} | ||
|
||
def launcher = T{ | ||
val isWin = scala.util.Properties.isWin | ||
val outputPath = T.ctx.dest / (if (isWin) "run.bat" else "run") | ||
|
||
os.write(outputPath, prependShellScript()) | ||
|
||
if (isWin) { | ||
windowsVmOptions("dev.launcher", outputPath, forkArgs()) | ||
} else { | ||
if (!isWin) { | ||
os.perms.set(outputPath, "rwxrwxrwx") | ||
} | ||
PathRef(outputPath) | ||
|
@@ -650,30 +636,43 @@ object dev extends MillModule{ | |
val isWin = scala.util.Properties.isWin | ||
val millPath = T.ctx.dest / (if (isWin) "mill.bat" else "mill") | ||
os.move(super.assembly().path, millPath) | ||
if (isWin) windowsVmOptions("dev.launcher", millPath, forkArgs()) | ||
PathRef(millPath) | ||
} | ||
|
||
def prependShellScript = T{ | ||
val (millArgs, otherArgs) = forkArgs().partition(arg => arg.startsWith("-DMILL") && !arg.startsWith("-DMILL_VERSION")) | ||
// Pass Mill options via file, due to small max args limit in Windows | ||
val vmOptionsFile = T.ctx.dest / "mill.properties" | ||
val millOptionsContent = millArgs.map(_.drop(2).replace("\\", "/")).mkString("\r\n") // drop -D prefix, replace \ with / | ||
os.write(vmOptionsFile, millOptionsContent) | ||
val jvmArgs = otherArgs ++ List(s"-DMILL_OPTIONS_PATH=$vmOptionsFile") | ||
val classpath = runClasspath().map(_.path.toString) | ||
val args = forkArgs() | ||
val (shellArgs, cmdArgs) = | ||
if (!scala.util.Properties.isWin) ( | ||
args, | ||
args | ||
) | ||
else ( | ||
Seq("""-XX:VMOptionsFile="$( dirname "$0" )"/mill.vmoptions"""), | ||
Seq("""-XX:VMOptionsFile=%~dp0\mill.vmoptions""") | ||
) | ||
launcherScript( | ||
shellArgs, | ||
cmdArgs, | ||
jvmArgs, | ||
jvmArgs, | ||
classpath, | ||
classpath | ||
Agg(pathingJar().path.toString) // TODO not working yet on Windows! see #791 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Windows, the classpath is only the "pathingJar", it contains all the dependencies. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lihaoyi this only relates to the |
||
) | ||
} | ||
|
||
def pathingJar = T{ | ||
// see http://todayguesswhat.blogspot.com/2011/03/jar-manifestmf-class-path-referencing.html | ||
// for more detailed explanation | ||
val isWin = scala.util.Properties.isWin | ||
val classpath = runClasspath().map{ pathRef => | ||
val path = if (isWin) "/" + pathRef.path.toString.replace("\\", "/") | ||
else pathRef.path.toString | ||
if (path.endsWith(".jar")) path | ||
else path + "/" | ||
}.mkString(" ") | ||
val manifestEntries = Map[String,String]( | ||
java.util.jar.Attributes.Name.MANIFEST_VERSION.toString -> "1.0", | ||
"Created-By" -> "Scala mill", | ||
"Class-Path" -> classpath | ||
) | ||
mill.modules.Jvm.createJar(Agg(), mill.modules.Jvm.JarManifest(manifestEntries)) | ||
} | ||
|
||
def run(args: String*) = T.command{ | ||
args match{ | ||
case Nil => mill.eval.Result.Failure("Need to pass in cwd as first argument to dev.run") | ||
|
@@ -691,7 +690,6 @@ object dev extends MillModule{ | |
} | ||
} | ||
|
||
|
||
def assembly = T{ | ||
|
||
val version = publishVersion()._2 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,32 +19,43 @@ public class MillClientMain { | |
public static final int ExitServerCodeWhenVersionMismatch() { return 101; } | ||
|
||
static void initServer(String lockBase, boolean setJnaNoSys) throws IOException,URISyntaxException{ | ||
String[] selfJars = System.getProperty("MILL_CLASSPATH").split(","); | ||
|
||
List<String> l = new ArrayList<>(); | ||
|
||
String selfJars = ""; | ||
List<String> vmOptions = new ArrayList<>(); | ||
l.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"); | ||
final Properties props = System.getProperties(); | ||
for(final String k: props.stringPropertyNames()){ | ||
String millOptionsPath = System.getProperty("MILL_OPTIONS_PATH"); | ||
if(millOptionsPath != null) { | ||
// read MILL_CLASSPATH from file MILL_OPTIONS_PATH | ||
Properties millProps = new Properties(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Windows we read the classpath from the |
||
millProps.load(new FileInputStream(millOptionsPath)); | ||
for(final String k: millProps.stringPropertyNames()){ | ||
String propValue = millProps.getProperty(k); | ||
if("MILL_CLASSPATH".equals(k)){ | ||
selfJars = propValue; | ||
} | ||
} | ||
} else { | ||
// read MILL_CLASSPATH from file sys props | ||
selfJars = System.getProperty("MILL_CLASSPATH"); | ||
} | ||
|
||
final Properties sysProps = System.getProperties(); | ||
for(final String k: sysProps.stringPropertyNames()){ | ||
if (k.startsWith("MILL_") && !"MILL_CLASSPATH".equals(k)) { | ||
vmOptions.add("-D" + k + "=" + props.getProperty(k)); | ||
vmOptions.add("-D" + k + "=" + sysProps.getProperty(k)); | ||
} | ||
} | ||
if(selfJars == null || selfJars.trim().isEmpty()) { | ||
throw new RuntimeException("MILL_CLASSPATH is empty!"); | ||
} | ||
if (setJnaNoSys) { | ||
vmOptions.add("-Djna.nosys=true"); | ||
} | ||
if(!Util.isWindows){ | ||
l.addAll(vmOptions); | ||
} else { | ||
final File vmOptionsFile = new File(lockBase, "vmoptions"); | ||
try (PrintWriter out = new PrintWriter(vmOptionsFile)) { | ||
for(String opt: vmOptions) | ||
out.println(opt); | ||
} | ||
l.add("-XX:VMOptionsFile=" + vmOptionsFile.getCanonicalPath()); | ||
} | ||
|
||
List<String> l = new ArrayList<>(); | ||
l.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"); | ||
l.addAll(vmOptions); | ||
l.add("-cp"); | ||
l.add(String.join(File.pathSeparator, selfJars)); | ||
l.add(String.join(File.pathSeparator, selfJars.split(","))); | ||
l.add("mill.main.MillServerMain"); | ||
l.add(lockBase); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We pass the
MILL_SOMETHING
properties via file, so that Windows doesn't complain!Everything except
MILL_VERSION
because it's used in lots of places.