@@ -244,6 +244,8 @@ struct GlobalSettings
244244
245245 // settings parser
246246 void setTarget (string option, string target) {
247+ stderr.writefln(" Start os: %s arch: %s" , targetOs, targetArch);
248+
247249 foreach (component; target.asLowerCase.text.splitter(' -' )) {
248250 auto aliasIndex = countUntil(targetAliases[].map! (a => a.from), component);
249251 if (aliasIndex >= 0 ) {
@@ -268,6 +270,7 @@ struct GlobalSettings
268270 stderr.writeln;
269271 needsHelp = true ;
270272 }
273+ stderr.writefln(" End os: %s arch: %s" , targetOs, targetArch);
271274 }
272275}
273276
@@ -345,6 +348,9 @@ GlobalSettings parseSettings(string[] args, const(Config)[] configs) {
345348
346349 arraySep = " ," ;
347350
351+ stderr.writefln(" Start os: %s arch: %s" , settings.targetOs, settings.targetArch);
352+ scope (exit) stderr.writefln(" End os: %s arch: %s" , settings.targetOs, settings.targetArch);
353+
348354 retry_parse_opts:
349355 try
350356 {
@@ -455,6 +461,7 @@ struct CompileParams {
455461struct Job {
456462 CompileParams params;
457463 string [] args;
464+ string [string ] envVars;
458465 string workDir;
459466 // When executable is produced it will be a first artifact
460467 string [] artifacts;
@@ -467,6 +474,71 @@ struct Job {
467474 bool printOutput;
468475}
469476
477+ bool isSomeWindowsTarget (in GlobalSettings gs) {
478+ if (gs.targetOs != TargetOs.windows) return false ;
479+ if (gs.targetArch == TargetArch.arm64) return true ;
480+ if (gs.targetArch == TargetArch.x64) return true ;
481+ return false ;
482+ }
483+
484+ void addWindowsLibs (in GlobalSettings gs, ref string [string ] envVars) {
485+ import std.file ;
486+
487+ if (hostOs != TargetOs.windows) return ;
488+ if (! isSomeWindowsTarget(gs)) return ;
489+
490+ import std.process : execute, Config;
491+ auto result = execute([" vswhere" , " -latest" , " -property" , " resolvedInstallationPath" ], null , Config.none, size_t .max);
492+
493+ if (result.status != 0 ) {
494+ stderr.writeln(" vswhere exited with " , result.status);
495+ stderr.writeln(" Cannot find Windows SDK and Visual Studio" );
496+ return ;
497+ }
498+
499+ // LDC will skip environment setup if it detects VSINSTALLDIR and VSCMD_ARG_TGT_ARCH
500+ auto vsPath = result.output.strip;
501+ envVars[" VSINSTALLDIR" ] = vsPath;
502+ envVars[" VSCMD_ARG_TGT_ARCH" ] = archName[gs.targetArch];
503+
504+ auto sdkPath = ` C:\Program Files (x86)\Windows Kits\10\Lib` ;
505+ if (! exists(sdkPath)) {
506+ stderr.writeln(" Cannot find Windows SDK at %s" , sdkPath);
507+ return ;
508+ }
509+
510+ string maxSdkPath;
511+ foreach (DirEntry e; dirEntries(sdkPath, SpanMode.shallow)) {
512+ if (maxSdkPath is null || e.name > maxSdkPath) {
513+ maxSdkPath = e.name;
514+ }
515+ }
516+
517+ auto vsToolsPath = buildPath(vsPath, ` VC\Tools\MSVC` );
518+ string maxVSPath;
519+ foreach (DirEntry e; dirEntries(vsToolsPath, SpanMode.shallow)) {
520+ if (maxVSPath is null || e.name > maxVSPath) {
521+ maxVSPath = e.name;
522+ }
523+ }
524+
525+ auto umLibsPath = buildPath(maxSdkPath, " um" , archName[gs.targetArch]);
526+ auto ucrtLibsPath = buildPath(maxSdkPath, " ucrt" , archName[gs.targetArch]);
527+ auto vsLibsPath = buildPath(maxVSPath, " lib" , archName[gs.targetArch]);
528+
529+ auto umTestPath = buildPath(umLibsPath, " kernel32.lib" );
530+ auto ucrtTestPath = buildPath(ucrtLibsPath, " libucrt.lib" );
531+ auto vsTestPath = buildPath(vsLibsPath, " libcmt.lib" );
532+
533+ if (maxSdkPath is null || maxVSPath is null || ! exists(umTestPath) || ! exists(ucrtTestPath) || ! exists(vsTestPath)) {
534+ stderr.writeln(" Cannot find Visual Studio at %s" , vsPath);
535+ return ;
536+ }
537+
538+ import std.array : join;
539+ envVars[" LIB" ] = join([umLibsPath, ucrtLibsPath, vsLibsPath], " ;" );
540+ }
541+
470542Job makeCompileJob (in GlobalSettings gs, in CompileParams params) {
471543 import std.path : buildPath;
472544
@@ -526,12 +598,16 @@ Job makeCompileJob(in GlobalSettings gs, in CompileParams params) {
526598 args ~= buildPath(params.srcDir, " custom_object.d" );
527599 }
528600
601+ string [string ] envVars;
602+ addWindowsLibs(gs, envVars);
603+
529604 Job job = {
530605 params : params,
531606 args : args,
532607 artifacts : artifacts,
533608 extraArtifacts : extraArtifacts,
534609 printOutput : gs.printCallees,
610+ envVars : envVars,
535611 };
536612 return job;
537613}
@@ -619,10 +695,16 @@ JobResult runJob(in GlobalSettings gs, in Job job) {
619695 }
620696
621697 void printCommand () {
622- if (gs.prettyPrint)
698+ if (gs.prettyPrint) {
623699 stderr.writefln(" > %-(%s\n | %)" , job.args);
624- else
625- stderr.writefln(" > %-(%s %)" , job.args);
700+ foreach (key, val; job.envVars)
701+ stderr.writefln(" | $% = %s" , key, val);
702+ } else {
703+ stderr.writef(" > %-(%s %)" , job.args);
704+ foreach (key, val; job.envVars)
705+ stderr.writef(" $%s=%s" , key, val);
706+ stderr.writeln;
707+ }
626708 }
627709
628710 if (gs.printCommands) printCommand;
@@ -632,7 +714,7 @@ JobResult runJob(in GlobalSettings gs, in Job job) {
632714 MonoTime startTime = currTime;
633715 import std.process : execute, Config;
634716 try {
635- auto result = execute(job.args, null , Config.none, size_t .max, job.workDir);
717+ auto result = execute(job.args, job.envVars , Config.none, size_t .max, job.workDir);
636718 MonoTime endTime = currTime;
637719
638720 void printCalleeOutput () {
0 commit comments