From eef48f36b2dd447bee9f653a860f7ba021f80154 Mon Sep 17 00:00:00 2001 From: Mike Franklin Date: Wed, 22 Aug 2018 21:55:26 +0900 Subject: [PATCH 1/3] build.d: Get path to vswhere --- src/build.d | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/build.d b/src/build.d index ce2d32a881d8..696006cd2c54 100755 --- a/src/build.d +++ b/src/build.d @@ -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); @@ -913,6 +916,61 @@ 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 + auto standardPath = ["cmd", "/C", "echo", `%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe`].execute.output; + standardPath = standardPath.replace(`"`, ""); // Remove quotes surrounding the path + standardPath = standardPath.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 + immutable url = "https://github.com/Microsoft/vswhere/releases/download/2.5.2/vswhere.exe"; + enum tries = 3; + foreach(i; 0..tries) + { + import std.net.curl : download, HTTPStatusException; + try + { + log("Downloading %s ...", url); + download(url, outputPath); + return outputPath; + } + catch(HTTPStatusException e) + { + if (e.status == 404) throw e; + else + { + log("Failed to download %s (Attempt %s of %s)", url, i + 1, tries); + continue; + } + } + } + + 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) { From d980ae0c2c0e396ba0129623e91997218dfb9bcc Mon Sep 17 00:00:00 2001 From: Mike Franklin Date: Sat, 25 Aug 2018 10:57:05 +0900 Subject: [PATCH 2/3] build.d: consolidate download procedure into a function --- src/build.d | 59 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/build.d b/src/build.d index 696006cd2c54..7a0aabf9ffbf 100755 --- a/src/build.d +++ b/src/build.d @@ -808,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. @@ -945,28 +980,10 @@ version(Windows) return outputPath; // try to download it - immutable url = "https://github.com/Microsoft/vswhere/releases/download/2.5.2/vswhere.exe"; - enum tries = 3; - foreach(i; 0..tries) - { - import std.net.curl : download, HTTPStatusException; - try - { - log("Downloading %s ...", url); - download(url, outputPath); - return outputPath; - } - catch(HTTPStatusException e) - { - if (e.status == 404) throw e; - else - { - log("Failed to download %s (Attempt %s of %s)", url, i + 1, tries); - continue; - } - } - } + 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"); } } From f76f531e8d427e82677889b71b1db57ea68d21d4 Mon Sep 17 00:00:00 2001 From: Mike Franklin Date: Sun, 26 Aug 2018 01:41:13 +0900 Subject: [PATCH 3/3] build.d: chain functions used to create standard path for vswhere --- src/build.d | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/build.d b/src/build.d index 7a0aabf9ffbf..7414c34f39be 100755 --- a/src/build.d +++ b/src/build.d @@ -968,9 +968,10 @@ version(Windows) return where.output; // Check if vswhere.exe is in the standard location - auto standardPath = ["cmd", "/C", "echo", `%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe`].execute.output; - standardPath = standardPath.replace(`"`, ""); // Remove quotes surrounding the path - standardPath = standardPath.replace("\r\n", ""); // Remove trailing newline characters + 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; @@ -984,7 +985,7 @@ version(Windows) 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"); + throw new Exception("Could not obtain vswhere.exe. Consider downloading it from https://github.com/Microsoft/vswhere and placing it in your PATH"); } }