aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg_Environment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolsrc/src/vcpkg_Environment.cpp')
-rw-r--r--toolsrc/src/vcpkg_Environment.cpp219
1 files changed, 160 insertions, 59 deletions
diff --git a/toolsrc/src/vcpkg_Environment.cpp b/toolsrc/src/vcpkg_Environment.cpp
index ed70e6881..8aaaba8a8 100644
--- a/toolsrc/src/vcpkg_Environment.cpp
+++ b/toolsrc/src/vcpkg_Environment.cpp
@@ -1,86 +1,187 @@
-#include <regex>
-#include <array>
+#include "pch.h"
#include "vcpkg_Environment.h"
#include "vcpkg_Commands.h"
-#include "metrics.h"
#include "vcpkg_System.h"
+#include "vcpkg_Strings.h"
+#include "vcpkg_Files.h"
-namespace vcpkg {namespace Environment
+namespace vcpkg::Environment
{
- static const fs::path default_cmake_installation_dir = "C:/Program Files/CMake/bin";
- static const fs::path default_cmake_installation_dir_x86 = "C:/Program Files (x86)/CMake/bin";
- static const fs::path default_git_installation_dir = "C:/Program Files/git/cmd";
- static const fs::path default_git_installation_dir_x86 = "C:/Program Files (x86)/git/cmd";
+ static std::vector<std::string> get_VS2017_installation_instances(const vcpkg_paths& paths)
+ {
+ const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
+ const std::wstring cmd = System::create_powershell_script_cmd(script);
+ System::exit_code_and_output ec_data = System::cmd_execute_and_capture_output(cmd);
+ Checks::check_exit(ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances");
+ return Strings::split(ec_data.output, "\n");
+ }
+
+ static optional<fs::path> find_vs2015_installation_instance()
+ {
+ const optional<std::wstring> vs2015_cmntools_optional = System::get_environmental_variable(L"VS140COMNTOOLS");
+ if (!vs2015_cmntools_optional)
+ {
+ return nullptr;
+ }
+
+ static const fs::path vs2015_cmntools = fs::path(*vs2015_cmntools_optional).parent_path(); // The call to parent_path() is needed because the env variable has a trailing backslash
+ static const fs::path vs2015_path = vs2015_cmntools.parent_path().parent_path();
+ return std::make_unique<fs::path>(vs2015_path);
+ }
+
+ static const optional<fs::path>& get_VS2015_installation_instance()
+ {
+ static const optional<fs::path> vs2015_path = find_vs2015_installation_instance();
+ return vs2015_path;
+ }
- static void ensure_on_path(const std::array<int, 3>& version, const wchar_t* version_check_cmd, const wchar_t* install_cmd)
+ static fs::path find_dumpbin_exe(const vcpkg_paths& paths)
{
- System::exit_code_and_output ec_data = System::cmd_execute_and_capture_output(version_check_cmd);
- if (ec_data.exit_code == 0)
+ const std::vector<std::string> vs2017_installation_instances = get_VS2017_installation_instances(paths);
+ std::vector<fs::path> paths_examined;
+
+ // VS2017
+ for (const std::string& instance : vs2017_installation_instances)
{
- // version check
- std::regex re(R"###((\d+)\.(\d+)\.(\d+))###");
- std::match_results<std::string::const_iterator> match;
- auto found = std::regex_search(ec_data.output, match, re);
- if (found)
+ const fs::path msvc_path = Strings::format(R"(%s\VC\Tools\MSVC)", instance);
+ std::vector<fs::path> msvc_subdirectories;
+ Files::non_recursive_find_matching_paths_in_dir(msvc_path, [&](const fs::path& current)
+ {
+ return fs::is_directory(current);
+ }, &msvc_subdirectories);
+
+ // Sort them so that latest comes first
+ std::sort(msvc_subdirectories.begin(), msvc_subdirectories.end(), [&](const fs::path& left, const fs::path& right)
+ {
+ return left.filename() > right.filename();
+ });
+
+ for (const fs::path& subdir : msvc_subdirectories)
{
- int d1 = atoi(match[1].str().c_str());
- int d2 = atoi(match[2].str().c_str());
- int d3 = atoi(match[3].str().c_str());
- if (d1 > version[0] || (d1 == version[0] && d2 > version[1]) || (d1 == version[0] && d2 == version[1] && d3 >= version[2]))
+ const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
+ paths_examined.push_back(dumpbin_path);
+ if (fs::exists(dumpbin_path))
{
- // satisfactory version found
- return;
+ return dumpbin_path;
}
}
}
- auto rc = System::cmd_execute(install_cmd);
- if (rc)
+ // VS2015
+ const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance();
+ if (vs_2015_installation_instance)
+ {
+ const fs::path vs2015_dumpbin_exe = *vs_2015_installation_instance / "VC" / "bin" / "dumpbin.exe";
+ paths_examined.push_back(vs2015_dumpbin_exe);
+ if (fs::exists(vs2015_dumpbin_exe))
+ {
+ return vs2015_dumpbin_exe;
+ }
+ }
+
+ System::println(System::color::error, "Could not detect dumpbin.exe.");
+ System::println("The following paths were examined:");
+ for (const fs::path& path : paths_examined)
+ {
+ System::println(" %s", path.generic_string());
+ }
+ exit(EXIT_FAILURE);
+ }
+
+ const fs::path& get_dumpbin_exe(const vcpkg_paths& paths)
+ {
+ static const fs::path dumpbin_exe = find_dumpbin_exe(paths);
+ return dumpbin_exe;
+ }
+
+ static vcvarsall_and_platform_toolset find_vcvarsall_bat(const vcpkg_paths& paths)
+ {
+ const std::vector<std::string> vs2017_installation_instances = get_VS2017_installation_instances(paths);
+ std::vector<fs::path> paths_examined;
+
+ // VS2017
+ for (const fs::path& instance : vs2017_installation_instances)
+ {
+ const fs::path vcvarsall_bat = instance / "VC" / "Auxiliary" / "Build" / "vcvarsall.bat";
+ paths_examined.push_back(vcvarsall_bat);
+ if (fs::exists(vcvarsall_bat))
+ {
+ return { vcvarsall_bat , L"v141" };
+ }
+ }
+
+ // VS2015
+ const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance();
+ if (vs_2015_installation_instance)
+ {
+ const fs::path vs2015_vcvarsall_bat = *vs_2015_installation_instance / "VC" / "vcvarsall.bat";
+
+ paths_examined.push_back(vs2015_vcvarsall_bat);
+ if (fs::exists(vs2015_vcvarsall_bat))
+ {
+ return { vs2015_vcvarsall_bat, L"v140" };
+ }
+ }
+
+ System::println(System::color::error, "Could not detect vcvarsall.bat.");
+ System::println("The following paths were examined:");
+ for (const fs::path& path : paths_examined)
{
- System::println(System::color::error, "Launching powershell failed or was denied");
- TrackProperty("error", "powershell install failed");
- TrackProperty("installcmd", install_cmd);
- exit(rc);
+ System::println(" %s", path.generic_string());
}
+ exit(EXIT_FAILURE);
+ }
+
+ const vcvarsall_and_platform_toolset& get_vcvarsall_bat(const vcpkg_paths& paths)
+ {
+ static const vcvarsall_and_platform_toolset vcvarsall_bat = find_vcvarsall_bat(paths);
+ return vcvarsall_bat;
}
- void ensure_git_on_path(const vcpkg_paths& paths)
+ static fs::path find_ProgramFiles()
{
- const fs::path downloaded_git = paths.downloads / "PortableGit" / "cmd";
- const std::wstring path_buf = Strings::wformat(L"%s;%s;%s;%s",
- downloaded_git.native(),
- System::wdupenv_str(L"PATH"),
- default_git_installation_dir.native(),
- default_git_installation_dir_x86.native());
- _wputenv_s(L"PATH", path_buf.c_str());
-
- static constexpr std::array<int, 3> git_version = {2,0,0};
- // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
- ensure_on_path(git_version, L"git --version 2>&1", L"powershell -ExecutionPolicy Bypass scripts\\fetchDependency.ps1 -Dependency git");
+ const optional<std::wstring> program_files = System::get_environmental_variable(L"PROGRAMFILES");
+ Checks::check_exit(program_files.get() != nullptr, "Could not detect the PROGRAMFILES environmental variable");
+ return *program_files;
}
- void ensure_cmake_on_path(const vcpkg_paths& paths)
+ static const fs::path& get_ProgramFiles()
{
- const fs::path downloaded_cmake = paths.downloads / "cmake-3.5.2-win32-x86" / "bin";
- const std::wstring path_buf = Strings::wformat(L"%s;%s;%s;%s",
- downloaded_cmake.native(),
- System::wdupenv_str(L"PATH"),
- default_cmake_installation_dir.native(),
- default_cmake_installation_dir_x86.native());
- _wputenv_s(L"PATH", path_buf.c_str());
-
- static constexpr std::array<int, 3> cmake_version = {3,5,0};
- // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
- ensure_on_path(cmake_version, L"cmake --version 2>&1", L"powershell -ExecutionPolicy Bypass scripts\\fetchDependency.ps1 -Dependency cmake");
+ static const fs::path p = find_ProgramFiles();
+ return p;
}
- void ensure_nuget_on_path(const vcpkg_paths& paths)
+ static fs::path find_ProgramFiles_32_bit()
{
- const std::wstring path_buf = Strings::wformat(L"%s;%s", paths.downloads.native(), System::wdupenv_str(L"PATH"));
- _wputenv_s(L"PATH", path_buf.c_str());
+ const optional<std::wstring> program_files_X86 = System::get_environmental_variable(L"ProgramFiles(x86)");
+ if (program_files_X86)
+ {
+ return *program_files_X86;
+ }
+
+ return get_ProgramFiles();
+ }
+
+ const fs::path& get_ProgramFiles_32_bit()
+ {
+ static const fs::path p = find_ProgramFiles_32_bit();
+ return p;
+ }
- static constexpr std::array<int, 3> nuget_version = {1,0,0};
- // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
- ensure_on_path(nuget_version, L"nuget 2>&1", L"powershell -ExecutionPolicy Bypass scripts\\fetchDependency.ps1 -Dependency nuget");
+ static fs::path find_ProgramFiles_platform_bitness()
+ {
+ const optional<std::wstring> program_files_W6432 = System::get_environmental_variable(L"ProgramW6432");
+ if (program_files_W6432)
+ {
+ return *program_files_W6432;
+ }
+
+ return get_ProgramFiles();
+ }
+
+ const fs::path& get_ProgramFiles_platform_bitness()
+ {
+ static const fs::path p = find_ProgramFiles_platform_bitness();
+ return p;
}
-}}
+}