aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/VcpkgPaths.cpp
diff options
context:
space:
mode:
authorAlexander Karatarakis <alkarata@microsoft.com>2017-10-05 18:25:34 -0700
committerAlexander Karatarakis <alkarata@microsoft.com>2017-10-05 18:29:34 -0700
commitf0c23aeb6b238ee0ba2dc272ee4c193f2f777460 (patch)
treef998f1e1adf60222613ad4ff7607866ada63d369 /toolsrc/src/VcpkgPaths.cpp
parent86f3a9dbbdc360db3716b878dd37f2dbec8e983c (diff)
downloadvcpkg-f0c23aeb6b238ee0ba2dc272ee4c193f2f777460.tar.gz
vcpkg-f0c23aeb6b238ee0ba2dc272ee4c193f2f777460.zip
Completely rework Visual Studio detection
- Now using vswhere.exe to detect all VS instance (2015 + 2017) - Default version preference order is now: stable, prerelease, legacy - Within each preference weight, the latest one is chosen - findVisualStudioInstallationInstances.ps1 now has a parameter to choose VS instance
Diffstat (limited to 'toolsrc/src/VcpkgPaths.cpp')
-rw-r--r--toolsrc/src/VcpkgPaths.cpp209
1 files changed, 113 insertions, 96 deletions
diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp
index f080783c4..8264ec293 100644
--- a/toolsrc/src/VcpkgPaths.cpp
+++ b/toolsrc/src/VcpkgPaths.cpp
@@ -302,26 +302,33 @@ namespace vcpkg
[this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; });
}
- static std::vector<std::string> get_vs2017_installation_instances(const VcpkgPaths& paths)
+ struct VisualStudioInstance
+ {
+ 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 VS 2017 instances");
- return Strings::split(ec_data.output, "\n");
- }
+ Checks::check_exit(
+ VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances");
- static Optional<fs::path> get_vs2015_installation_instance()
- {
- const Optional<std::wstring> vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS");
- if (const auto v = vs2015_cmntools_optional.get())
+ 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)
@@ -335,108 +342,118 @@ namespace vcpkg
std::vector<Toolset> found_toolsets;
- // VS2015
- const Optional<fs::path> vs_2015_installation_instance = get_vs2015_installation_instance();
- if (const auto vs_2015_root_path = vs_2015_installation_instance.get())
- {
- const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "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))
+ // VS2017
+ 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 = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe";
- paths_examined.push_back(vs2015_dumpbin_exe);
+ const fs::path vc_dir = vs_instance.root_path / "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;
- const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin";
+ // 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 / "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))
+ // 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({*vs_2015_root_path,
- vs2015_dumpbin_exe,
- vs2015_vcvarsall_bat,
- {},
- V_140,
- 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;
+ }
}
- }
- }
- const bool v140_is_available = !found_toolsets.empty();
-
- const std::vector<std::string> vs2017_installation_instances = get_vs2017_installation_instances(paths);
+ continue;
+ }
- // VS2017
- for (const std::string& instance : vs2017_installation_instances)
- {
- const fs::path vs_root_path = fs::path{instance};
- const fs::path vc_dir = vs_root_path / "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))
- {
- found_toolsets.push_back(
- Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures});
+ const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat";
- if (v140_is_available)
+ paths_examined.push_back(vcvarsall_bat);
+ if (fs.exists(vcvarsall_bat))
+ {
+ 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(Toolset{vs_root_path,
- dumpbin_path,
- vcvarsall_bat,
- {L"-vcvars_ver=14.0"},
- V_140,
- supported_architectures});
+ found_toolsets.push_back({vs_instance.root_path,
+ vs2015_dumpbin_exe,
+ vcvarsall_bat,
+ {},
+ V_140,
+ supported_architectures});
}
-
- break;
}
+
+ continue;
}
+
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Expected major version 14 or 15 but got: %s", major_version);
}
if (found_toolsets.empty())
@@ -460,7 +477,7 @@ namespace vcpkg
const std::vector<Toolset>& vs_toolsets =
this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); });
- std::vector<const Toolset*> candidates = Util::to_vector_of_const_pointers(vs_toolsets);
+ std::vector<const Toolset*> candidates = Util::element_pointers(vs_toolsets);
const auto tsv = toolset_version.get();
const auto vsp = visual_studio_path.get();
@@ -500,7 +517,7 @@ namespace vcpkg
vs_root_path.generic_string());
}
- return *candidates.back();
+ return *candidates.front();
}
Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); }