Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ void parseEnvironment()
exit(1);
}

version(Windows)
env.getDefault("HOST_VSWHERE", getHostVSWhere(env["G"]));

env.getDefault("HOST_CXX", getHostCXX);
env.getDefault("CXX_KIND", getHostCXXKind);

Expand Down Expand Up @@ -805,6 +808,41 @@ auto sourceFiles()
return sources;
}

/*
Downloads a file from a given URL

Params:
to = Location to store the file downloaded
from = The URL to the file to download
tries = The number of times to try if an attempt to download fails
Returns: `true` if download succeeded
*/
bool download(string to, string from, uint tries = 3)
{
import std.net.curl : download, HTTPStatusException;

foreach(i; 0..tries)
{
try
{
log("Downloading %s ...", from);
download(from, to);
return true;
}
catch(HTTPStatusException e)
{
if (e.status == 404) throw e;
else
{
log("Failed to download %s (Attempt %s of %s)", from, i + 1, tries);
continue;
}
}
}

return false;
}

/*
Detects the host OS.

Expand Down Expand Up @@ -913,6 +951,44 @@ auto getHostDMDPath(string hostDmd)
static assert(false, "Unrecognized or unsupported OS.");
}

version(Windows)
{
/*
Gets the absolute path to the host's vshwere executable

Params:
outputFolder = this build's output folder
Returns: a string that is the absolute path of the host's vswhere executable
*/
auto getHostVSWhere(string outputFolder)
{
// Check if vswhere.exe can be found in the host's PATH
const where = ["where", "vswhere"].execute;
if (where.status == 0)
return where.output;

// Check if vswhere.exe is in the standard location
const standardPath = ["cmd", "/C", "echo", `%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe`]
.execute.output // Execute command and return standard output
.replace(`"`, "") // Remove quotes surrounding the path
.replace("\r\n", ""); // Remove trailing newline characters
if (standardPath.exists)
return standardPath;

// Check if it has already been dowloaded to this build's output folder
const outputPath = outputFolder.buildPath("vswhere").exeName;
if (outputPath.exists)
return outputPath;

// try to download it
if (download(outputPath, "https://github.com/Microsoft/vswhere/releases/download/2.5.2/vswhere.exe"))
return outputPath;

// Could not find or obtain vswhere.exe
throw new Exception("Could not obtain vswhere.exe. Consider downloading it from https://github.com/Microsoft/vswhere and placing it in your PATH");
}
}

// Add the executable filename extension to the given `name` for the current OS.
auto exeName(T)(T name)
{
Expand Down