mirror of https://github.com/microsoft/vcpkg.git
Overhaul VS selection. Add triplet option to specify VS instance
This commit is contained in:
parent
7f68aa6630
commit
9a963f7eff
|
|
@ -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}")
|
||||
message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}")
|
||||
message("VCPKG_VISUAL_STUDIO_PATH=${VCPKG_VISUAL_STUDIO_PATH}")
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
const Toolset& VcpkgPaths::get_toolset(const Optional<std::string>& toolset_version,
|
||||
const Optional<fs::path>& visual_studio_path) const
|
||||
{
|
||||
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 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 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 (tsv)
|
||||
{
|
||||
return vs2017_v140_toolsets.back();
|
||||
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);
|
||||
}
|
||||
|
||||
return *toolset;
|
||||
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.back();
|
||||
}
|
||||
|
||||
Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue