aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/VcpkgPaths.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolsrc/src/VcpkgPaths.cpp')
-rw-r--r--toolsrc/src/VcpkgPaths.cpp392
1 files changed, 248 insertions, 144 deletions
diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp
index 17a11b1a9..dac9e40e7 100644
--- a/toolsrc/src/VcpkgPaths.cpp
+++ b/toolsrc/src/VcpkgPaths.cpp
@@ -10,27 +10,31 @@
namespace vcpkg
{
+ static constexpr CWStringView V_120 = L"v120";
+ static constexpr CWStringView V_140 = L"v140";
+ static constexpr CWStringView V_141 = L"v141";
+
static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd,
const std::array<int, 3>& expected_version)
{
- static const std::regex re(R"###((\d+)\.(\d+)\.(\d+))###");
+ static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###");
- auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd));
+ const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd));
if (rc.exit_code != 0)
{
return false;
}
std::match_results<std::string::const_iterator> match;
- auto found = std::regex_search(rc.output, match, re);
+ const auto found = std::regex_search(rc.output, match, RE);
if (!found)
{
return false;
}
- int d1 = atoi(match[1].str().c_str());
- int d2 = atoi(match[2].str().c_str());
- int d3 = atoi(match[3].str().c_str());
+ const int d1 = atoi(match[1].str().c_str());
+ const int d2 = atoi(match[2].str().c_str());
+ const int d3 = atoi(match[3].str().c_str());
if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) ||
(d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2]))
{
@@ -58,46 +62,40 @@ namespace vcpkg
return nullopt;
}
- static std::vector<fs::path> find_from_PATH(const std::wstring& name)
- {
- const std::wstring cmd = Strings::wformat(L"where.exe %s", name);
- auto out = System::cmd_execute_and_capture_output(cmd);
- if (out.exit_code != 0)
- {
- return {};
- }
-
- return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); });
- }
-
static fs::path fetch_dependency(const fs::path& scripts_folder,
const std::wstring& tool_name,
const fs::path& expected_downloaded_path,
const std::array<int, 3>& version)
{
+ const std::string tool_name_utf8 = Strings::to_utf8(tool_name);
+ const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
+ System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...",
+ tool_name_utf8,
+ version_as_string,
+ tool_name_utf8,
+ version_as_string);
const fs::path script = scripts_folder / "fetchDependency.ps1";
- auto install_cmd = System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name));
- System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd);
+ const auto install_cmd =
+ System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name));
+ const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd);
if (rc.exit_code)
{
- const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
-
System::println(System::Color::error,
"Launching powershell failed or was denied when trying to fetch %s version %s.\n"
"(No sufficient installed version was found)",
- Strings::to_utf8(tool_name),
+ tool_name_utf8,
version_as_string);
{
auto locked_metrics = Metrics::g_metrics.lock();
locked_metrics->track_property("error", "powershell install failed");
- locked_metrics->track_property("installcmd", install_cmd);
+ locked_metrics->track_property("dependency", tool_name);
}
Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code);
}
const fs::path actual_downloaded_path = Strings::trimmed(rc.output);
std::error_code ec;
- auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec);
+ const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec);
Checks::check_exit(VCPKG_LINE_INFO,
eq && !ec,
"Expected dependency downloaded path to be %s, but was %s",
@@ -108,71 +106,99 @@ namespace vcpkg
static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
{
- static constexpr std::array<int, 3> expected_version = {3, 9, 1};
- static const std::wstring version_check_arguments = L"--version";
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {3, 9, 3};
+ static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version";
- const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe";
- const std::vector<fs::path> from_path = find_from_PATH(L"cmake");
+ const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe";
+ const std::vector<fs::path> from_path = Files::find_from_PATH(L"cmake");
std::vector<fs::path> candidate_paths;
candidate_paths.push_back(downloaded_copy);
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "CMake" / "bin" / "cmake.exe");
- candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "CMake" / "bin");
+ candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe");
+ candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin");
const Optional<fs::path> path =
- find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
{
return *p;
}
- return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, expected_version);
+ return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION);
}
fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
{
- static constexpr std::array<int, 3> expected_version = {4, 1, 0};
- static const std::wstring version_check_arguments = L"";
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {4, 3, 0};
+ static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY;
- const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe";
- const std::vector<fs::path> from_path = find_from_PATH(L"nuget");
+ const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe";
+ const std::vector<fs::path> from_path = Files::find_from_PATH(L"nuget");
std::vector<fs::path> candidate_paths;
candidate_paths.push_back(downloaded_copy);
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- auto path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
+ auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
{
return *p;
}
- return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, expected_version);
+ return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION);
}
fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
{
- static constexpr std::array<int, 3> expected_version = {2, 14, 1};
- static const std::wstring version_check_arguments = L"--version";
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {2, 14, 1};
+ static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version";
const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe";
- const std::vector<fs::path> from_path = find_from_PATH(L"git");
+ const std::vector<fs::path> from_path = Files::find_from_PATH(L"git");
std::vector<fs::path> candidate_paths;
candidate_paths.push_back(downloaded_copy);
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "git" / "cmd" / "git.exe");
- candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "git" / "cmd" / "git.exe");
+ candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe");
+ candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe");
const Optional<fs::path> path =
- find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
{
return *p;
}
- return fetch_dependency(scripts_folder, L"git", downloaded_copy, expected_version);
+ return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION);
+ }
+
+ static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
+ {
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {3, 1, 81};
+ static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version";
+
+ const fs::path downloaded_copy =
+ downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe";
+
+ std::vector<fs::path> candidate_paths;
+ candidate_paths.push_back(downloaded_copy);
+ // TODO: Uncomment later
+ // const std::vector<fs::path> from_path = Files::find_from_PATH(L"installerbase");
+ // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
+ // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" /
+ // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe");
+ // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" /
+ // "QtIFW-3.1.0" / "bin" / "installerbase.exe");
+
+ const Optional<fs::path> path =
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
+ {
+ return *p;
+ }
+
+ return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION);
}
Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir)
@@ -233,7 +259,7 @@ namespace vcpkg
{
for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets))
{
- std::string triplet_file_name = path.stem().generic_u8string();
+ const std::string triplet_file_name = path.stem().generic_u8string();
if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare
{
// t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare
@@ -258,26 +284,51 @@ namespace vcpkg
return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); });
}
- static std::vector<std::string> get_VS2017_installation_instances(const VcpkgPaths& paths)
+ const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const
{
- const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
- const std::wstring cmd = System::create_powershell_script_cmd(script);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd);
- Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances");
- return Strings::split(ec_data.output, "\n");
+ return this->ifw_installerbase_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); });
+ }
+
+ const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const
+ {
+ return this->ifw_binarycreator_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; });
+ }
+
+ const fs::path& VcpkgPaths::get_ifw_repogen_exe() const
+ {
+ return this->ifw_repogen_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; });
}
- static Optional<fs::path> get_VS2015_installation_instance()
+ struct VisualStudioInstance
{
- const Optional<std::wstring> vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS");
- if (auto v = vs2015_cmntools_optional.get())
+ fs::path root_path;
+ std::string version;
+ std::string release_type;
+ std::string preference_weight; // Mostly unused, just for verification that order is as intended
+
+ std::string major_version() const { return version.substr(0, 2); }
+ };
+
+ static std::vector<VisualStudioInstance> get_visual_studio_instances(const VcpkgPaths& paths)
+ {
+ const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
+ const std::wstring cmd = System::create_powershell_script_cmd(script);
+ const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances");
+
+ const std::vector<std::string> instances_as_strings = Strings::split(ec_data.output, "\n");
+ std::vector<VisualStudioInstance> output;
+ for (const std::string& instance_as_string : instances_as_strings)
{
- const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because
- // the env variable has a trailing backslash
- return vs2015_cmntools.parent_path().parent_path();
+ const std::vector<std::string> split = Strings::split(instance_as_string, "::");
+ output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)});
}
- return nullopt;
+ return output;
}
static std::vector<Toolset> find_toolset_instances(const VcpkgPaths& paths)
@@ -286,99 +337,122 @@ namespace vcpkg
const auto& fs = paths.get_filesystem();
- const std::vector<std::string> vs2017_installation_instances = get_VS2017_installation_instances(paths);
// Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations.
std::vector<fs::path> paths_examined;
std::vector<Toolset> found_toolsets;
- // VS2015
- const Optional<fs::path> vs_2015_installation_instance = get_VS2015_installation_instance();
- if (auto v = vs_2015_installation_instance.get())
- {
- const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat";
+ const std::vector<VisualStudioInstance> vs_instances = get_visual_studio_instances(paths);
+ const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) {
+ return vs_instance.major_version() == "14";
+ }) != vs_instances.cend();
- paths_examined.push_back(vs2015_vcvarsall_bat);
- if (fs.exists(vs2015_vcvarsall_bat))
+ for (const VisualStudioInstance& vs_instance : vs_instances)
+ {
+ const std::string major_version = vs_instance.major_version();
+ if (major_version == "15")
{
- const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe";
- paths_examined.push_back(vs2015_dumpbin_exe);
+ const fs::path vc_dir = vs_instance.root_path / "VC";
- const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin";
+ // Skip any instances that do not have vcvarsall.
+ const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build";
+ const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat";
+ paths_examined.push_back(vcvarsall_bat);
+ if (!fs.exists(vcvarsall_bat)) continue;
+
+ // Get all supported architectures
std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vs2015_bin_dir / "vcvars32.bat"))
+ if (fs.exists(vcvarsall_dir / "vcvars32.bat"))
supported_architectures.push_back({L"x86", CPU::X86, CPU::X86});
- if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat"))
- supported_architectures.push_back({L"x64", CPU::X64, CPU::X64});
- if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat"))
+ if (fs.exists(vcvarsall_dir / "vcvars64.bat"))
+ supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64});
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat"))
supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat"))
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat"))
supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat"))
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat"))
+ supported_architectures.push_back({L"x86_arm64", CPU::X86, CPU::ARM64});
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat"))
supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat"))
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat"))
supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM});
-
- if (fs.exists(vs2015_dumpbin_exe))
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat"))
+ supported_architectures.push_back({L"amd64_arm64", CPU::X64, CPU::ARM64});
+
+ // Locate the "best" MSVC toolchain version
+ const fs::path msvc_path = vc_dir / "Tools" / "MSVC";
+ std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path);
+ Util::unstable_keep_if(msvc_subdirectories,
+ [&fs](const fs::path& path) { return fs.is_directory(path); });
+
+ // 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)
{
- found_toolsets.push_back(
- {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_architectures});
+ const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
+ paths_examined.push_back(dumpbin_path);
+ if (fs.exists(dumpbin_path))
+ {
+ found_toolsets.push_back(Toolset{
+ vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures});
+
+ if (v140_is_available)
+ {
+ found_toolsets.push_back(Toolset{vs_instance.root_path,
+ dumpbin_path,
+ vcvarsall_bat,
+ {L"-vcvars_ver=14.0"},
+ V_140,
+ supported_architectures});
+ }
+
+ break;
+ }
}
+
+ continue;
}
- }
- // VS2017
- Optional<Toolset> vs2017_toolset;
- for (const fs::path& instance : vs2017_installation_instances)
- {
- const fs::path vc_dir = instance / "VC";
-
- // Skip any instances that do not have vcvarsall.
- const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build";
- const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat";
- paths_examined.push_back(vcvarsall_bat);
- if (!fs.exists(vcvarsall_bat)) continue;
-
- // Get all supported architectures
- std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vcvarsall_dir / "vcvars32.bat"))
- supported_architectures.push_back({L"x86", CPU::X86, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvars64.bat"))
- supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat"))
- supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat"))
- supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat"))
- supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat"))
- supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM});
-
- // Locate the "best" MSVC toolchain version
- const fs::path msvc_path = vc_dir / "Tools" / "MSVC";
- std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path);
- Util::unstable_keep_if(msvc_subdirectories, [&fs](const fs::path& path) { return fs.is_directory(path); });
-
- // 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)
+ if (major_version == "14")
{
- const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
- paths_examined.push_back(dumpbin_path);
- if (fs.exists(dumpbin_path))
+ const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat";
+
+ paths_examined.push_back(vcvarsall_bat);
+ if (fs.exists(vcvarsall_bat))
{
- vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141", supported_architectures};
- break;
+ const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe";
+ paths_examined.push_back(vs2015_dumpbin_exe);
+
+ const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin";
+ std::vector<ToolsetArchOption> supported_architectures;
+ if (fs.exists(vs2015_bin_dir / "vcvars32.bat"))
+ supported_architectures.push_back({L"x86", CPU::X86, CPU::X86});
+ if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat"))
+ supported_architectures.push_back({L"x64", CPU::X64, CPU::X64});
+ if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat"))
+ supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64});
+ if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat"))
+ supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM});
+ if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat"))
+ supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86});
+ if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat"))
+ supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM});
+
+ if (fs.exists(vs2015_dumpbin_exe))
+ {
+ found_toolsets.push_back({vs_instance.root_path,
+ vs2015_dumpbin_exe,
+ vcvarsall_bat,
+ {},
+ V_140,
+ supported_architectures});
+ }
}
}
- if (auto value = vs2017_toolset.get())
- {
- found_toolsets.push_back(*value);
- break;
- }
}
if (found_toolsets.empty())
@@ -395,24 +469,54 @@ namespace vcpkg
return found_toolsets;
}
- const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const
+ const Toolset& VcpkgPaths::get_toolset(const Optional<std::string>& toolset_version,
+ const Optional<fs::path>& visual_studio_path) const
{
// Invariant: toolsets are non-empty and sorted with newest at back()
- const auto& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); });
+ const std::vector<Toolset>& vs_toolsets =
+ this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); });
+
+ std::vector<const Toolset*> candidates = Util::element_pointers(vs_toolsets);
+ const auto tsv = toolset_version.get();
+ const auto vsp = visual_studio_path.get();
- if (toolset_version.empty())
+ if (tsv && vsp)
{
- return vs_toolsets.back();
+ const std::wstring w_toolset_version = Strings::to_utf16(*tsv);
+ const fs::path vs_root_path = *vsp;
+ Util::stable_keep_if(candidates, [&](const Toolset* t) {
+ return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path;
+ });
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !candidates.empty(),
+ "Could not find Visual Studio instace at %s with %s toolset.",
+ vs_root_path.generic_string(),
+ *tsv);
+
+ Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1);
+ return *candidates.back();
}
- else
+
+ if (tsv)
{
- const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) {
- return toolset_version == Strings::to_utf8(toolset.version);
- });
+ const std::wstring w_toolset_version = Strings::to_utf16(*tsv);
+ Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; });
Checks::check_exit(
- VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version);
- return *toolset;
+ VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv);
+ }
+
+ if (vsp)
+ {
+ const fs::path vs_root_path = *vsp;
+ Util::stable_keep_if(candidates,
+ [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; });
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !candidates.empty(),
+ "Could not find Visual Studio instace at %s.",
+ vs_root_path.generic_string());
}
+
+ return *candidates.front();
}
Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); }