diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 1858a320f2..fd7d832b32 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -119,6 +119,12 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args); } + namespace X_VSInstances + { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + namespace Hash { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); diff --git a/toolsrc/include/vcpkg/visualstudio.h b/toolsrc/include/vcpkg/visualstudio.h index b93b145d9d..cd99db3527 100644 --- a/toolsrc/include/vcpkg/visualstudio.h +++ b/toolsrc/include/vcpkg/visualstudio.h @@ -6,6 +6,8 @@ namespace vcpkg::VisualStudio { + std::vector get_visual_studio_instances(const VcpkgPaths& paths); + std::vector find_toolset_instances_preferred_first(const VcpkgPaths& paths); } diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 7204b6e78e..db265514ff 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -46,6 +46,7 @@ namespace vcpkg::Commands {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, {"fetch", &Fetch::perform_and_exit}, + {"x-vsinstances", &X_VSInstances::perform_and_exit}, }; return t; } diff --git a/toolsrc/src/vcpkg/commands.xvsinstances.cpp b/toolsrc/src/vcpkg/commands.xvsinstances.cpp new file mode 100644 index 0000000000..3aa54f4242 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.xvsinstances.cpp @@ -0,0 +1,29 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Commands::X_VSInstances +{ + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("x-vsinstances"), + 0, + 0, + {{}, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE); + + const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths); + for (const std::string& instance : instances) + { + System::println(instance); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index 9480a11bfe..4f6b2a37b7 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -22,6 +22,17 @@ namespace vcpkg::VisualStudio LEGACY }; + static std::string release_type_to_string(const ReleaseType& release_type) + { + switch (release_type) + { + case ReleaseType::STABLE: return "STABLE"; + case ReleaseType::PRERELEASE: return "PRERELEASE"; + case ReleaseType::LEGACY: return "LEGACY"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + static bool preferred_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) { const auto get_preference_weight = [](const ReleaseType& type) -> int { @@ -51,10 +62,15 @@ namespace vcpkg::VisualStudio std::string version; ReleaseType release_type; + std::string to_string() const + { + return Strings::format("%s, %s, %s", root_path.u8string(), version, release_type_to_string(release_type)); + } + std::string major_version() const { return version.substr(0, 2); } }; - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) + static std::vector get_visual_studio_instances_internal(const VcpkgPaths& paths) { const auto& fs = paths.get_filesystem(); std::vector instances; @@ -114,9 +130,9 @@ namespace vcpkg::VisualStudio { // We want lexically_normal(), but it is not available // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. - auto common7_tools = fs::path{*path_as_string}; - append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path()); - append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); + auto common7_tools = fs::path {*path_as_string}; + append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path()); + append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path().parent_path()); } // VS2015 instance from Program Files @@ -125,6 +141,13 @@ namespace vcpkg::VisualStudio return instances; } + std::vector get_visual_studio_instances(const VcpkgPaths& paths) + { + std::vector sorted {get_visual_studio_instances_internal(paths)}; + std::sort(sorted.begin(), sorted.end(), VisualStudioInstance::preferred_first_comparator); + return Util::fmap(sorted, [](const VisualStudioInstance& instance) { return instance.to_string(); }); + } + std::vector find_toolset_instances_preferred_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; @@ -137,8 +160,8 @@ namespace vcpkg::VisualStudio std::vector found_toolsets; std::vector excluded_toolsets; - const SortedVector sorted{get_visual_studio_instances(paths), - VisualStudioInstance::preferred_first_comparator}; + const SortedVector sorted {get_visual_studio_instances_internal(paths), + VisualStudioInstance::preferred_first_comparator}; const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; @@ -194,7 +217,7 @@ namespace vcpkg::VisualStudio paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - const Toolset v141_toolset{ + const Toolset v141_toolset { vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; const auto english_language_pack = dumpbin_path.parent_path() / "1033"; @@ -209,12 +232,12 @@ namespace vcpkg::VisualStudio if (v140_is_available) { - const Toolset v140_toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; + const Toolset v140_toolset {vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; found_toolsets.push_back(v140_toolset); } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index abfe8a242a..315c481745 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -233,6 +233,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 42493d623c..3e0ccd885f 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -213,6 +213,9 @@ Source Files\vcpkg\base + + Source Files\vcpkg +