Skip to content

Commit 9f38571

Browse files
committed
add VSCMD_DEBUG=1 logging to vcvars64.bat capture
1 parent 3b0727d commit 9f38571

File tree

1 file changed

+84
-55
lines changed

1 file changed

+84
-55
lines changed

modules/core/src/main/scala/scala/build/internals/NativeWrapper.scala

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -33,55 +33,56 @@ object MsvcEnvironment {
3333
case Some(vcvars) =>
3434
logger.debug(s"Using vcvars script $vcvars")
3535

36-
val msvcEnv = captureVcvarsEnv(vcvars, workingDir)
37-
val clDir = os.Path(msvcEnv("VCTOOLSINSTALLDIR")) / "bin" / "Hostx64" / "x64"
38-
logger.debug(s"clDir[$clDir]")
39-
if (!os.exists(clDir)) {
40-
logger.message(s"cl.exe directory missing: $clDir")
41-
-1
36+
val (debugEcho: Seq[String], msvcEnv: Map[String, String]) =
37+
captureVcvarsEnv(vcvars, workingDir)
38+
debugEcho.foreach { dbg =>
39+
logger.message(s"$dbg")
4240
}
43-
else {
44-
val msvcEnv: Map[String, String] = captureVcvarsEnv(vcvars, workingDir)
45-
val clExe: os.Path = clDir / "cl.exe"
46-
if !os.exists(clExe) then
47-
logger.message(s"warning: file not found: $clExe")
48-
49-
val msvcEntries: Seq[String] = {
50-
val entries = msvcEnv.getOrElse("PATH", "").split(";").toSeq
51-
if entries.headOption == Some(clDir.toString) then entries
52-
else clDir.toString +: entries
53-
}
41+
val msvcEntries: Seq[String] = msvcEnv.getOrElse("PATH", "").split(";").toSeq
42+
43+
// show aliased drive map
44+
val substMap: Map[Char, String] = aliasedDriveLetters
45+
substMap.foreach((k, v) => logger.message(s"substMap $k: -> $v"))
5446

55-
// show aliased drive map
56-
val substMap: Map[Char, String] = aliasedDriveLetters
57-
substMap.foreach((k, v) => logger.message(s"substMap $k: -> $v"))
47+
val finalPath = msvcEntries.mkString(";")
48+
val finalEnv =
49+
msvcEnv +
50+
("PATH" -> finalPath) +
51+
("GRAALVM_ARGUMENT_VECTOR_PROGRAM_NAME" -> "native-image")
5852

59-
val finalPath = msvcEntries.mkString(";")
60-
val finalEnv =
61-
msvcEnv +
62-
("PATH" -> finalPath) +
63-
("GRAALVM_ARGUMENT_VECTOR_PROGRAM_NAME" -> "native-image")
53+
logger.message(s"msvc PATH entries:")
54+
msvcEntries.foreach { entry =>
55+
logger.message(s"$entry;")
56+
}
6457

65-
logger.message(s"msvc PATH entries:")
66-
msvcEntries.foreach { entry =>
67-
logger.message(s"$entry;")
58+
// Replace native-image.cmd with native-image.exe, if applicable
59+
val updatedCommand: Seq[String] =
60+
command.headOption match {
61+
case Some(cmd) if cmd.toLowerCase.endsWith("native-image.cmd") =>
62+
val cmdPath = os.Path(cmd, os.pwd)
63+
val graalHome = cmdPath / os.up / os.up
64+
resolveNativeImage(graalHome) match {
65+
case Some(exe) =>
66+
exe.toString +: command.tail
67+
case None =>
68+
command // fall back to the .cmd wrapper
69+
}
70+
case _ =>
71+
command
6872
}
6973

70-
logger.message(s"native-image w/args: $command")
74+
logger.message(s"native-image w/args: $command")
7175

72-
// request extra info in case of exceptions
73-
val altCommand = insertAfterCp(command, "-H:+ReportExceptionStackTraces")
74-
val result =
75-
os.proc(altCommand)
76-
.call(
77-
cwd = workingDir,
78-
env = finalEnv,
79-
stdout = os.Inherit,
80-
stderr = os.Inherit
81-
)
76+
val result =
77+
os.proc(updatedCommand)
78+
.call(
79+
cwd = workingDir,
80+
env = finalEnv,
81+
stdout = os.Inherit,
82+
stderr = os.Inherit
83+
)
8284

83-
result.exitCode
84-
}
85+
result.exitCode
8586
}
8687
}
8788

@@ -177,19 +178,24 @@ object MsvcEnvironment {
177178
// =========================
178179
// Capture MSVC environment
179180
// =========================
180-
private def captureVcvarsEnv(vcvars: os.Path, workingDir: os.Path): Map[String, String] = {
181+
private def captureVcvarsEnv(
182+
vcvars: os.Path,
183+
workingDir: os.Path
184+
): (Seq[String], Map[String, String]) = {
185+
181186
val vcvarsCmd = vcvars.toIO.getAbsolutePath
182187

183-
val cmd = Seq(
188+
val sentinel = "::sentinel"
189+
val cmd = Seq(
184190
cmdExe,
185191
"/c",
186-
s"""(call \"$vcvarsCmd\") && set"""
192+
s"""set "VSCMD_DEBUG=1" & call "$vcvarsCmd" & echo $sentinel & set"""
187193
)
188194

189195
val out = new StringBuilder
190196

191197
val res = os.proc(cmd).call(
192-
cwd = workingDir, // run vcvars from the working directory
198+
cwd = workingDir,
193199
env = sys.env,
194200
stdout = os.ProcessOutput.Readlines(line => out.append(line).append("\n")),
195201
stderr = os.Inherit,
@@ -198,17 +204,40 @@ object MsvcEnvironment {
198204

199205
if res.exitCode != 0 then
200206
System.err.println(s"vcvars call failed with exit code ${res.exitCode}")
201-
Map.empty
207+
(Seq.empty, Map.empty)
202208
else
203-
out.result().linesIterator
204-
.map(_.trim)
205-
.filter(_.contains("="))
206-
.flatMap {
207-
_.split("=", 2) match
208-
case Array(k, v) => Some(k.toUpperCase(Locale.ROOT) -> v)
209-
case _ => None
210-
}
211-
.toMap
209+
val lines = out.result().linesIterator.map(_.trim).filter(_.nonEmpty).toVector
210+
211+
// Split at sentinel
212+
val (debugLines, afterSentinel) = lines.span(_ != sentinel)
213+
214+
// Drop the sentinel itself
215+
val envLines = afterSentinel.drop(1)
216+
217+
// Parse KEY=VALUE lines
218+
val envMap =
219+
envLines
220+
.flatMap { line =>
221+
if line.contains("=") then
222+
line.split("=", 2) match
223+
case Array(k, v) =>
224+
Some(k.toUpperCase(Locale.ROOT) -> v)
225+
case _ =>
226+
None
227+
else None
228+
}
229+
.toMap
230+
231+
(debugLines, envMap)
232+
}
233+
234+
private def resolveNativeImage(graalHome: os.Path): Option[os.Path] = {
235+
val candidates = Seq(
236+
graalHome / "lib" / "svm" / "bin" / "native-image.exe",
237+
graalHome / "bin" / "native-image.exe",
238+
graalHome / "native-image.exe"
239+
)
240+
candidates.find(os.exists)
212241
}
213242

214243
private def vcvarsOpt: Option[os.Path] = {

0 commit comments

Comments
 (0)