From f6d52648ecdd5d57a9ca592e1425950d465aeef5 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 24 Feb 2020 14:38:51 -0800 Subject: [PATCH] [vcpkg] Fix issue #9916; `vcpkg upgrade` did not `load_tag_vars()` (#10202) --- toolsrc/include/vcpkg/cmakevars.h | 53 +++++-------------- toolsrc/src/vcpkg/build.cpp | 3 +- toolsrc/src/vcpkg/cmakevars.cpp | 62 ++++++++++++++++++++++- toolsrc/src/vcpkg/commands.ci.cpp | 7 +-- toolsrc/src/vcpkg/commands.dependinfo.cpp | 3 +- toolsrc/src/vcpkg/commands.env.cpp | 3 +- toolsrc/src/vcpkg/commands.upgrade.cpp | 5 +- toolsrc/src/vcpkg/install.cpp | 8 ++- 8 files changed, 90 insertions(+), 54 deletions(-) diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h index 8d131d45e..1c02376b9 100644 --- a/toolsrc/include/vcpkg/cmakevars.h +++ b/toolsrc/include/vcpkg/cmakevars.h @@ -1,15 +1,21 @@ #pragma once -#include -#include +#include #include #include +namespace vcpkg::Dependencies +{ + struct ActionPlan; +} + namespace vcpkg::CMakeVars { struct CMakeVarProvider { + virtual ~CMakeVarProvider() = default; + virtual Optional&> get_generic_triplet_vars( Triplet triplet) const = 0; @@ -25,45 +31,10 @@ namespace vcpkg::CMakeVars virtual void load_tag_vars(Span specs, const PortFileProvider::PortFileProvider& port_provider) const = 0; + + void load_tag_vars(const vcpkg::Dependencies::ActionPlan& action_plan, + const PortFileProvider::PortFileProvider& port_provider) const; }; - struct TripletCMakeVarProvider : Util::ResourceBase, CMakeVarProvider - { - private: - fs::path create_tag_extraction_file( - const Span>& spec_abi_settings) const; - - fs::path create_dep_info_extraction_file(const Span specs) const; - - void launch_and_split(const fs::path& script_path, - std::vector>>& vars) const; - - public: - explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) {} - - void load_generic_triplet_vars(Triplet triplet) const override; - - void load_dep_info_vars(Span specs) const override; - - void load_tag_vars(Span specs, - const PortFileProvider::PortFileProvider& port_provider) const override; - - Optional&> get_generic_triplet_vars( - Triplet triplet) const override; - - Optional&> get_dep_info_vars( - const PackageSpec& spec) const override; - - Optional&> get_tag_vars( - const PackageSpec& spec) const override; - - private: - const VcpkgPaths& paths; - const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); - const fs::path get_tags_path = paths.scripts / "vcpkg_get_tags.cmake"; - const fs::path get_dep_info_path = paths.scripts / "vcpkg_get_dep_info.cmake"; - mutable std::unordered_map> dep_resolution_vars; - mutable std::unordered_map> tag_vars; - mutable std::unordered_map> generic_triplet_vars; - }; + std::unique_ptr make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths); } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index d3f6302db..93b12f391 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -43,7 +43,8 @@ namespace vcpkg::Build::Command { vcpkg::Util::unused(options); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; var_provider.load_dep_info_vars(std::array{full_spec.package_spec}); var_provider.load_tag_vars(std::array{full_spec}, provider); diff --git a/toolsrc/src/vcpkg/cmakevars.cpp b/toolsrc/src/vcpkg/cmakevars.cpp index 42bed5501..98b2546ed 100644 --- a/toolsrc/src/vcpkg/cmakevars.cpp +++ b/toolsrc/src/vcpkg/cmakevars.cpp @@ -1,17 +1,77 @@ #include "pch.h" +#include #include #include +#include #include #include +#include using namespace vcpkg; using vcpkg::Optional; -using vcpkg::CMakeVars::TripletCMakeVarProvider; namespace vcpkg::CMakeVars { + void CMakeVarProvider::load_tag_vars(const vcpkg::Dependencies::ActionPlan& action_plan, + const PortFileProvider::PortFileProvider& port_provider) const + { + std::vector install_package_specs; + for (auto&& action : action_plan.install_actions) + { + install_package_specs.emplace_back(FullPackageSpec{action.spec, action.feature_list}); + } + + load_tag_vars(install_package_specs, port_provider); + } + + namespace + { + struct TripletCMakeVarProvider : Util::ResourceBase, CMakeVarProvider + { + explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) {} + + void load_generic_triplet_vars(Triplet triplet) const override; + + void load_dep_info_vars(Span specs) const override; + + void load_tag_vars(Span specs, + const PortFileProvider::PortFileProvider& port_provider) const override; + + Optional&> get_generic_triplet_vars( + Triplet triplet) const override; + + Optional&> get_dep_info_vars( + const PackageSpec& spec) const override; + + Optional&> get_tag_vars( + const PackageSpec& spec) const override; + + public: + fs::path create_tag_extraction_file( + const Span>& spec_abi_settings) const; + + fs::path create_dep_info_extraction_file(const Span specs) const; + + void launch_and_split(const fs::path& script_path, + std::vector>>& vars) const; + + const VcpkgPaths& paths; + const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); + const fs::path get_tags_path = paths.scripts / "vcpkg_get_tags.cmake"; + const fs::path get_dep_info_path = paths.scripts / "vcpkg_get_dep_info.cmake"; + mutable std::unordered_map> dep_resolution_vars; + mutable std::unordered_map> tag_vars; + mutable std::unordered_map> generic_triplet_vars; + }; + } + + std::unique_ptr make_triplet_cmake_var_provider(const vcpkg::VcpkgPaths& paths) + { + return std::make_unique(paths); + } + fs::path TripletCMakeVarProvider::create_tag_extraction_file( const Span>& spec_abi_settings) const { diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 00e25e223..2fbe78b42 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -223,7 +223,7 @@ namespace vcpkg::Commands::CI std::map abi_tag_map; }; - static bool supported_for_triplet(const CMakeVars::TripletCMakeVarProvider& var_provider, + static bool supported_for_triplet(const CMakeVars::CMakeVarProvider& var_provider, const InstallPlanAction* install_plan) { auto&& scfl = install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO); @@ -253,7 +253,7 @@ namespace vcpkg::Commands::CI const VcpkgPaths& paths, const std::set& exclusions, const PortFileProvider::PortFileProvider& provider, - const CMakeVars::TripletCMakeVarProvider& var_provider, + const CMakeVars::CMakeVarProvider& var_provider, const std::vector& specs, const bool purge_tombstones) { @@ -449,7 +449,8 @@ namespace vcpkg::Commands::CI StatusParagraphs status_db = database_load_check(paths); PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; const Build::BuildPackageOptions install_plan_options = { Build::UseHeadVersion::NO, diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 7023547da..f153626fa 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -252,7 +252,8 @@ namespace vcpkg::Commands::DependInfo } PathsPortFileProvider provider(paths, args.overlay_ports.get()); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; // By passing an empty status_db, we should get a plan containing all dependencies. // All actions in the plan should be install actions, as there's no installed packages to remove. diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index 6d959d425..5b673b965 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -40,7 +40,8 @@ namespace vcpkg::Commands::Env const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; var_provider.load_generic_triplet_vars(triplet); diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index 960e9bbb3..fbce1a421 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -45,7 +45,8 @@ namespace vcpkg::Commands::Upgrade // Load ports from ports dirs PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; // input sanitization const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { @@ -180,6 +181,8 @@ namespace vcpkg::Commands::Upgrade Checks::exit_fail(VCPKG_LINE_INFO); } + var_provider.load_tag_vars(action_plan, provider); + const Install::InstallSummary summary = Install::perform(action_plan, keep_going, paths, status_db, var_provider); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index e2a8ce4c5..2874f39f4 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -677,22 +677,20 @@ namespace vcpkg::Install //// Load ports from ports dirs PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); - CMakeVars::TripletCMakeVarProvider var_provider(paths); + auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); + auto& var_provider = *var_provider_storage; // Note: action_plan will hold raw pointers to SourceControlFileLocations from this map auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db); - std::vector install_package_specs; for (auto&& action : action_plan.install_actions) { action.build_options = install_plan_options; if (action.request_type != RequestType::USER_REQUESTED) action.build_options.use_head_version = Build::UseHeadVersion::NO; - - install_package_specs.emplace_back(FullPackageSpec{action.spec, action.feature_list}); } - var_provider.load_tag_vars(install_package_specs, provider); + var_provider.load_tag_vars(action_plan, provider); // install plan will be empty if it is already installed - need to change this at status paragraph part Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty");