-
-
Notifications
You must be signed in to change notification settings - Fork 408
Copy GraalVM under shorter path on Windows CI #4917
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
Copy GraalVM under shorter path on Windows CI #4917
Conversation
They might disappear across runs, given they're externally managed
These are run like the '/** Usage' ones, but are not put on the website
This also copies the changes in |
About #4907 (comment), this could be added in coursier. Maybe with something like ArchiveCache().withShortPathDir(Some(new File("C:/jvms"))) That way, we'd only have to keep |
Looking at this PR it feels like it's exposing too much complexity in the API: asking the user to configure an explicit path, and then asking the user to call a separate command to copy things to that explicit path, both seem like incidental complexity that we should try and avoid. Are there any other options? e.g. Can we always copy the Graal binary to a shorter path in |
i reverted all changes, and made it use coursier/coursier#3373 (this needs coursier |
main/util/src/mill/util/Jvm.scala
Outdated
if (isWin) os.Path(System.getenv("UserProfile")) / ".mill/cache/jvm" | ||
else os.home / ".cache/mill/jvm" |
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.
This snippet here looks a bit unusual. I thought we just use os.home
for most things? Or are we using UserProfile
in other parts of the code as well?
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.
Yes, mill.bat
uses it here. I also used it in JLineNativeLoader
, added in #4882.
Ideally, that directory should be obtained by a native Windows call rather than via the environment. Coursier does it via directories-jvm, but it's quite cumbersome (requires JNI or newer JVM foreign API stuff, or running a powershell script…). Given mill.bat
relies on the env for that, it's better just to do the same in Mill IMO.
@@ -51,6 +53,11 @@ trait JvmWorkerModule extends OfflineSupportModule with CoursierModule { | |||
|
|||
def zincLogDebug: T[Boolean] = Task.Input(Task.ctx().log.debugEnabled) | |||
|
|||
def useShortJvmPath(jvmId: String): Boolean = | |||
Properties.isWin && ( | |||
jvmId.startsWith("graalvm") || jvmId.startsWith("liberica-nik") |
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.
What's liberica-nik
?
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.
It's an alternative GraalVM distribution. Coursier uses it, as it has support for more platforms (like Alpine Linux on arm64, but not Windows on arm64 though)
Conflicts: build.mill core/util/src/mill/util/Jvm.scala scalalib/src/mill/scalalib/JvmWorkerModule.scala
Recently run into this issue on my fork here and here, with a somewhat cryptic error message looking like
|
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.
looks good to me
core/util/src/mill/util/Jvm.scala
Outdated
os.Path(System.getenv("UserProfile")) / ".mill/cache/jvm" | ||
else { | ||
val cacheBase = sys.env.get("XDG_CACHE_HOME").map(os.Path(_)).getOrElse(os.home / ".cache") |
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.
Two things.
- When
ctx
is defined,ctx.get.env
is probably the better source for environment variables. - We should either use
System.getenv
orsys.env.get
but not both.
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.
val env = ctx.map(_.env).getOrElse(sys.env)
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 can check ctx.env
for XDG_CACHE_HOME
, but I'm more wary of it for UserProfile
. On Windows, env var names are case-insensitive, so that the path can be set as Path
for example. In that case, System.getenv("PATH")
respects the case-insensitiveness on Windows, and finds the variable. sys.env.get("PATH")
doesn't. And IIUC, ctx.env.get("PATH")
wouldn't either.
So I'd stick to System.getenv
for UserProfile
, as this is used on Windows only, and unlikely to be customized by users. But ctx.env
and both System.getenv
and sys.env
are fine outside of Windows, for XDG_CACHE_HOME
.
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.
On Windows, the environment isn't really a Map[String, String]
, more a Map[CaseInsensitiveString, String]
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.
Can you please add a comment, since this isn't obvious.
Also, I'd assume Mill already suffers form this nifty details. Ideally, we have a map with case-insensitive keys semantics in TaskCtx.env
. Also, sys.env
seems to be a bad abstraction when it doesn't work correctly under Windows, so we should always use System.getenv
. Nothing we can solve here, but I think we should review Mill regarding this issue.
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.
Looks like the case-insensitive lookup is already implemented in sys.env
.
https://www.scala-lang.org/api/current/scala/sys.html#env-0
An immutable Map representing the current system environment.
If lookup fails, use System.getenv(_) for case-insensitive lookup on a certain platform. If that also fails, throw NoSuchElementException.
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.
Just realized that TaskCtx.env
suffers from that too, yes.
And indeed, sys.env
is a bad abstraction. I tend to always use System.getenv
in my projects.
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.
@alexarchambault seems like this has caused some tests to break in |
These were broken before merging this PR. The broken task is |
…)" This reverts commit d2552c4.
@alexarchambault the revert #5009 fixes the tests that have been broken consistently since this PR landed. Rebootstrapping is currently broken due to the same error (https://github.com/com-lihaoyi/mill/actions/runs/14699556292). I couldn't figure out how this PR causes that breakage either, but will merge the revert first just so we can fix |
This reverts commit d2552c4. Just to see if this can fix the main build CC @alexarchambault
Publishing seems to be making more progress now since the revert https://github.com/com-lihaoyi/mill/actions/runs/14700178878/job/41248197683 |
Apparently, the coursier version bump seems to be the problem, rather than the use of shorter paths in But enabling the use of short GraalVM paths alongside bumping coursier (making sure the Mill build itself relies on shorter paths this time) seems to work, see #5018. |
Comes from #4917, but shouldn't be a problem
…utions (new attempt) (#5018) New attempt at #4917 It seems the too long paths are being an issue as soon as we bump the coursier version ([this job](https://github.com/alexarchambault/mill/actions/runs/14705154651/attempts/1) only bumps the coursier version, and results in issues with too long GraalVM paths). Unlike #4917, this not only uses short paths in examples and integration tests, but also in the Mill build itself. It seems this makes `dist.native.nativeImage` happy.
This adds a
nativeImageMaybeCopyGraal
command onNativeImageModule
. This command only has an effect ifNativeImageModule#nativeImageGraalVmCopyBase: Option[os.Path]
is non-empty. By default, it's non-empty only in Windows CI environments, where it'sSome(os.Path("C:/jvms"))
.nativeImageMaybeCopyGraal
copies the GraalVM distribution under a sub-directory of it, likeC:\jvms\5aa5d09c
.5aa5d09c
is a hash of the original GraalVM distribution path.If this directory exists,
NativeImageModule#nativeImageTool
uses it rather than the original GraalVM distribution, to get the path ofnative-image
. This offers a workaround for too long paths of GraalVM header files, that we run into sometimes on the CI (more on fork CIs than in the main repo, in my experience).This allows to get rid of the coursier archive cache customizations on the CI, that were meant to work around that problem too. The resulting paths were sometimes still too long, given they contain the URL of the GraalVM distribution, like
C:\coursier-arc\https\github.com\graalvm\graalvm-ce-builds\releases\download\jdk-23.0.1\graalvm-community-jdk-23.0.1_windows-x64_bin.zip\
. In constrast, with this PR, we get GraalVM distribution paths likeC:\jvms\5aa5d09c
.