diff options
| -rw-r--r-- | scripts/get_triplet_environment.cmake | 3 | ||||
| -rw-r--r-- | toolsrc/include/VcpkgPaths.h | 5 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Build.h | 3 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Util.h | 15 | ||||
| -rw-r--r-- | toolsrc/src/PostBuildLint.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/VcpkgPaths.cpp | 120 | ||||
| -rw-r--r-- | toolsrc/src/commands_env.cpp | 4 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Build.cpp | 12 |
8 files changed, 97 insertions, 67 deletions
diff --git a/scripts/get_triplet_environment.cmake b/scripts/get_triplet_environment.cmake index 69e06bf97..b32f840d2 100644 --- a/scripts/get_triplet_environment.cmake +++ b/scripts/get_triplet_environment.cmake @@ -5,4 +5,5 @@ message("c35112b6-d1ba-415b-aa5d-81de856ef8eb") message("VCPKG_TARGET_ARCHITECTURE=${VCPKG_TARGET_ARCHITECTURE}") message("VCPKG_CMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}") message("VCPKG_CMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}") -message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}")
\ No newline at end of file +message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}") +message("VCPKG_VISUAL_STUDIO_PATH=${VCPKG_VISUAL_STUDIO_PATH}")
\ No newline at end of file diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 4b4527434..d4640fba2 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -17,6 +17,7 @@ namespace vcpkg struct Toolset { + fs::path visual_studio_root_path; fs::path dumpbin; fs::path vcvarsall; std::vector<std::wstring> vcvarsall_options; @@ -66,7 +67,8 @@ namespace vcpkg /// <remarks> /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. /// </remarks> - const Toolset& 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; Files::Filesystem& get_filesystem() const; @@ -78,6 +80,5 @@ namespace vcpkg Lazy<fs::path> ifw_binarycreator_exe; Lazy<fs::path> ifw_repogen_exe; Lazy<std::vector<Toolset>> toolsets; - Lazy<std::vector<Toolset>> toolsets_vs2017_v140; }; } diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 78e89d4de..5ba675757 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -79,7 +79,8 @@ namespace vcpkg::Build std::string target_architecture; std::string cmake_system_name; std::string cmake_system_version; - std::string platform_toolset; + Optional<std::string> platform_toolset; + Optional<fs::path> visual_studio_path; }; std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index e5ead6d3a..a87045d73 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -67,6 +67,21 @@ namespace vcpkg::Util return std::find_if(cont.cbegin(), cont.cend(), pred); } + template<class Container> + using ToVectorOfConstPointersT = std::decay_t<decltype(*std::begin(std::declval<Container>()))>; + + template<class Container, class T = ToVectorOfConstPointersT<Container>> + std::vector<const T*> to_vector_of_const_pointers(const Container& cont) + { + std::vector<const T*> output; + for (auto i = cont.cbegin(), cend = cont.end(); i != cend; ++i) + { + output.push_back(&(*i)); + } + + return output; + } + template<class Container, class Pred> auto find_if_not(const Container& cont, Pred pred) { diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 416d4a636..a0699e15c 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -722,7 +722,7 @@ namespace vcpkg::PostBuildLint const auto& fs = paths.get_filesystem(); // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 9f85992be..f080783c4 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -337,14 +337,14 @@ namespace vcpkg // VS2015 const Optional<fs::path> vs_2015_installation_instance = get_vs2015_installation_instance(); - if (const auto v = vs_2015_installation_instance.get()) + if (const auto vs_2015_root_path = vs_2015_installation_instance.get()) { - const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2015_vcvarsall_bat); if (fs.exists(vs2015_vcvarsall_bat)) { - const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; + const fs::path vs2015_dumpbin_exe = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; @@ -364,19 +364,25 @@ namespace vcpkg if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back( - {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, {}, V_140, supported_architectures}); + found_toolsets.push_back({*vs_2015_root_path, + vs2015_dumpbin_exe, + vs2015_vcvarsall_bat, + {}, + V_140, + supported_architectures}); } } } + const bool v140_is_available = !found_toolsets.empty(); + const std::vector<std::string> vs2017_installation_instances = get_vs2017_installation_instances(paths); // VS2017 - Optional<Toolset> vs2017_toolset; for (const std::string& instance : vs2017_installation_instances) { - const fs::path vc_dir = fs::path{instance} / "VC"; + 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"; @@ -415,14 +421,22 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + found_toolsets.push_back( + Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + break; } } - if (const auto value = vs2017_toolset.get()) - { - found_toolsets.push_back(*value); - } } if (found_toolsets.empty()) @@ -439,64 +453,54 @@ namespace vcpkg return found_toolsets; } - static std::vector<Toolset> create_vs2017_v140_toolset_instances(const std::vector<Toolset>& vs_toolsets) - { - std::vector<Toolset> vs2017_v140_toolsets; - - // In constrast to v141 and above, there can only be a single instance of v140 (VS2017 vs VS2015). - const auto it = Util::find_if(vs_toolsets, [&](const Toolset& t) { return t.version == V_140; }); - - // If v140 is not available, then VS2017 cant use them. Return empty. - if (it == vs_toolsets.cend()) - { - return vs2017_v140_toolsets; - } - - // If it does exist, then create a matching v140 toolset for each v141 toolset - const Toolset v140_toolset = *it; - for (const Toolset& toolset : vs_toolsets) - { - if (toolset.version != V_141) - { - continue; - } - - Toolset t = Toolset{ - toolset.dumpbin, toolset.vcvarsall, {L"-vcvars_ver=14.0"}, V_140, toolset.supported_architectures}; - vs2017_v140_toolsets.push_back(std::move(t)); - } - - return vs2017_v140_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 { - const std::wstring& w_toolset_version = Strings::to_utf16(toolset_version); - // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector<Toolset>& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - if (w_toolset_version.empty()) + std::vector<const Toolset*> candidates = Util::to_vector_of_const_pointers(vs_toolsets); + const auto tsv = toolset_version.get(); + const auto vsp = visual_studio_path.get(); + + 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(); } - const auto toolset = - Util::find_if(vs_toolsets, [&](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); + if (tsv) + { + 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, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + } - // If v140 is the selected toolset and VS2017 is available, then use VS2017's vcvarsall with the - // -vcvars_ver=14.0 option - const std::vector<Toolset>& vs2017_v140_toolsets = this->toolsets_vs2017_v140.get_lazy( - [&vs_toolsets]() { return create_vs2017_v140_toolset_instances(vs_toolsets); }); - if (w_toolset_version == V_140 && !vs2017_v140_toolsets.empty()) + if (vsp) { - return vs2017_v140_toolsets.back(); + 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 *toolset; + return *candidates.back(); } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index 073c501f5..6dad3e882 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -13,8 +13,8 @@ namespace vcpkg::Commands::Env args.check_and_get_optional_command_arguments({}); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - System::cmd_execute_clean( - Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 853f84998..9be20629d 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -138,7 +138,7 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.ports_cmake; const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); std::string features; @@ -386,7 +386,15 @@ namespace vcpkg::Build if (variable_name == "VCPKG_PLATFORM_TOOLSET") { - pre_build_info.platform_toolset = variable_value; + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional<std::string>{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional<fs::path>{variable_value}; continue; } |
