From e62d1361288e83eba786395b60361ab35ba83800 Mon Sep 17 00:00:00 2001 From: Phil Christensen Date: Mon, 3 Feb 2020 14:22:52 -0800 Subject: [vcpkg] Add Supports: field. Use contents of triplets instead of names for dependency resolution. (#8601) * remove unfinished "supports" tag * extract "supports" from control files But do nothing with the value * Start `Supports` documentation * Use Supports in a bunch of control files I only tried matching the already existing logic in the portfile.cmake. * Cmake var provider (#8) * Cmake var provider (#9) * fix windows build (#10) * Add missing files to build * Fix test (#11) * adding hooks for cmake variables in expressions * Adding hooks for 'supports' in CI test * Fix test (#12) * Add overrides to evaluation environment * use "supported" tag in CI testing * cleanup comment * Fix issues with PR * [var_provider] Get library linkage variables from triplet * Fix compilation errors in tests * Add unimplemented functions * Fix unit tests part 1 * Fix issue when buildtrees dir does not exist * Change binary output hash * Fix handling of * feature * Add core feature when using * * Do not add Default-Features when installing 'core' * [vcpkg] WIP. 6 failing tests. * [vcpkg] WIP. 1 failing tests. * [vcpkg] WIP. 0 failing tests. * [vcpkg] Removed 'remove_graph'. 0 failing tests. * [vcpkg] Removed 'install_graph'. 0 failing tests. * [vcpkg] Remove AnyAction; replace with ActionPlan * [vcpkg] Minor cleanup. * [vcpkg][z3][qt5-connectivity][qt5-purchasing] Improve error messages while parsing. Fix a few trivial port issues. * [vcpkg] Work around ICE with MSVC v140 * [vcpkg] Add purge on fail to decompress for CI * [vcpkg] Fix parsing of nested parentheses in qualifiers * [vcpkg] Fix Linux builds (explicit qualification in declaration) * [vcpkg] Fix Build-Depends implying default features. Fix qualified dependencies regression. * [mmx] Add to skip list and full rebuild -- mmx causes problems by installing 'sched.h' * [libpqxx][mqtt-cpp] Prevent installing include/CMakeLists.txt * [cppitertools] Fix installed include namespace (should be include/cppitertools) * [libsoundio] Move headers into soundio/ subdirectory as per original cmake * [ci.baseline] Temporarily skip charls due to conflict with dcmtk * [vcpkg] Add restricted include files post build check -- bump global abi version * [libsoundio] Hotfix stray line in portfile * [vcpkg] Fix regression: CMake information was not being displayed for build-and-install actions * [jsonnet] Fix installation of internal headers; use system nlohmann-json * [grpc][upb] Teach grpc to use packaged upb. Add find_package(upb). Remove inappropriate upb features. * [zfp] Move problematic 'include/bitstream.h' to 'include/zfp/bitstream.h' * [x265] Bump control version to trigger rebuild after zfp conflict * [akali] Disable parallel configure * [dirent][dlfcn-win32][getopt-win32][pthreads] Grandfather into VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [ci.baseline] Update baseline for improved upb support * [tgui] Disable parallel configure * [libiconv] Enable VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [aws-sdk-cpp] Disable parallel configure * [vcpkg] Implement policy VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [aws-sdk-cpp] Fix amount of escaping semicolons -- Note: I do not know the root cause requiring this change * [libodb-sqlite] Fix configuring into source directory * [gettext] Grandfather into VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [libodb] DISABLE_PARALLEL_CONFIGURE * [vcpkg] Add 'config.h' and 'local.h' to restricted header list * [mcpp] Remove unused and problematic include 'config.h' from installed files * [teemo] Move installed headers into subdirectory to prevent conflicts with x265 * [ci.baseline] Update current OSX. Skip libmesh on all platforms due to heavy conflicts. * [vcpkg] Add 'slice.h' as a restricted header * [osg] Improve accuracy of dependencies (disable some, add some to Depends) * [vcpkg] Skip invoking a subprocess for 0 specs in load_tag_vars * [ci.baseline] Skip mongo-c-driver on osx due to flakiness * [teemo] Fix incorrect include file read * [osg] Fix dependency typo: glut -> freeglut * [vcpkg] Recover some lost performance with the addition of vcpkg_get_tags. A huge performance cost was loading the triplet files over and over; instead, we splice the sources into a macro and load it once, then just call that macro for each port. Remove use of hashing because we aren't cross-process-safe anyway (global static will do instead). * [vcpkg] Change Supports atom 'windows' to include UWP. Improve Supports field documentation. * [vcpkg] Add docs for VCPKG_ENV_PASSTHROUGH and VCPKG_DEP_INFO_OVERRIDE_VARS * Fix typo Co-authored-by: Curtis J Bezault Co-authored-by: Victor Romero Co-authored-by: Robert Schumacher --- toolsrc/include/vcpkg-test/mockcmakevarprovider.h | 38 +++++++++ toolsrc/include/vcpkg-test/util.h | 23 ++++++ toolsrc/include/vcpkg/base/graphs.h | 47 +---------- toolsrc/include/vcpkg/base/span.h | 3 +- toolsrc/include/vcpkg/base/util.h | 14 +++- toolsrc/include/vcpkg/binaryparagraph.h | 11 ++- toolsrc/include/vcpkg/build.h | 36 ++++++--- toolsrc/include/vcpkg/cmakevars.h | 69 ++++++++++++++++ toolsrc/include/vcpkg/dependencies.h | 98 +++++++---------------- toolsrc/include/vcpkg/install.h | 14 ++-- toolsrc/include/vcpkg/logicexpression.h | 16 +++- toolsrc/include/vcpkg/packagespec.h | 29 ++++++- toolsrc/include/vcpkg/portfileprovider.h | 38 +++++++++ toolsrc/include/vcpkg/sourceparagraph.h | 88 +++++++++++--------- toolsrc/include/vcpkg/statusparagraph.h | 1 + toolsrc/include/vcpkg/update.h | 2 +- 16 files changed, 352 insertions(+), 175 deletions(-) create mode 100644 toolsrc/include/vcpkg-test/mockcmakevarprovider.h create mode 100644 toolsrc/include/vcpkg/cmakevars.h create mode 100644 toolsrc/include/vcpkg/portfileprovider.h (limited to 'toolsrc/include') diff --git a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h new file mode 100644 index 000000000..03defdcdd --- /dev/null +++ b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +namespace vcpkg::Test +{ + struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider + { + void load_generic_triplet_vars(const Triplet& triplet) const override { generic_triplet_vars[triplet] = {}; } + + void load_dep_info_vars(Span specs) const override + { + for (auto&& spec : specs) + dep_info_vars[spec] = {}; + } + + void load_tag_vars(Span specs, + const PortFileProvider::PortFileProvider& port_provider) const override + { + for (auto&& spec : specs) + tag_vars[spec.package_spec] = {}; + Util::unused(port_provider); + } + + Optional&> get_generic_triplet_vars( + const Triplet& triplet) const override; + + Optional&> get_dep_info_vars( + const PackageSpec& spec) const override; + + Optional&> get_tag_vars( + const PackageSpec& spec) const override; + + mutable std::unordered_map> dep_info_vars; + mutable std::unordered_map> tag_vars; + mutable std::unordered_map> generic_triplet_vars; + }; +} diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h index 259b0ba7e..088a39b7d 100644 --- a/toolsrc/include/vcpkg-test/util.h +++ b/toolsrc/include/vcpkg-test/util.h @@ -17,6 +17,12 @@ namespace vcpkg::Test { + std::unique_ptr make_control_file( + const char* name, + const char* depends, + const std::vector>& features = {}, + const std::vector& default_features = {}); + std::unique_ptr make_status_pgh(const char* name, const char* depends = "", const char* default_features = "", @@ -27,6 +33,23 @@ namespace vcpkg::Test const char* depends = "", const char* triplet = "x86-windows"); + /// + /// Map of source control files by their package name. + /// + struct PackageSpecMap + { + std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept : triplet(t) {} + + PackageSpec emplace(const char* name, + const char* depends = "", + const std::vector>& features = {}, + const std::vector& default_features = {}); + + PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl); + }; + vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS); template diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h index 683735b1c..f368a872d 100644 --- a/toolsrc/include/vcpkg/base/graphs.h +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -1,11 +1,10 @@ #pragma once +#include #include -#include -#include +#include #include -#include #include namespace vcpkg::Graphs @@ -95,10 +94,8 @@ namespace vcpkg::Graphs } } - template - std::vector topological_sort(VertexContainer starting_vertices, - const AdjacencyProvider& f, - Randomizer* randomizer) + template + std::vector topological_sort(Range starting_vertices, const AdjacencyProvider& f, Randomizer* randomizer) { std::vector sorted; std::unordered_map exploration_status; @@ -112,40 +109,4 @@ namespace vcpkg::Graphs return sorted; } - - template - struct Graph final : AdjacencyProvider - { - public: - void add_vertex(const V& v) { this->m_edges[v]; } - - void add_edge(const V& u, const V& v) - { - this->m_edges[v]; - this->m_edges[u].insert(v); - } - - std::vector vertex_list() const - { - std::vector vertex_list; - for (auto&& vertex : this->m_edges) - vertex_list.emplace_back(vertex.first); - return vertex_list; - } - - std::vector adjacency_list(const V& vertex) const override - { - const std::unordered_set& as_set = this->m_edges.at(vertex); - return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy - } - - V load_vertex_data(const V& vertex) const override { return vertex; } - - // Note: this function indicates how tied this template is to the exact type it will be templated upon. - // Possible fix: This type shouldn't implement to_string() and should instead be derived from? - std::string to_string(const V& spec) const override { return spec->spec.to_string(); } - - private: - std::unordered_map> m_edges; - }; } diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h index 4c805e2b4..a5ba884af 100644 --- a/toolsrc/include/vcpkg/base/span.h +++ b/toolsrc/include/vcpkg/base/span.h @@ -23,14 +23,13 @@ namespace vcpkg constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) {} constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} - constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} template constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N) { } - template + template>> constexpr Span(std::remove_const_t (&arr)[N]) noexcept : m_ptr(arr), m_count(N) { } diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index ad628e071..849781b95 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -18,7 +18,7 @@ namespace vcpkg::Util namespace Vectors { template> - void concatenate(std::vector* augend, const Container& addend) + void append(std::vector* augend, const Container& addend) { augend->insert(augend->end(), addend.begin(), addend.end()); } @@ -122,6 +122,12 @@ namespace vcpkg::Util std::sort(begin(cont), end(cont), comp); } + template + bool any_of(Range&& rng, Pred pred) + { + return std::any_of(rng.begin(), rng.end(), std::move(pred)); + } + template Range&& sort_unique_erase(Range&& cont) { @@ -220,4 +226,10 @@ namespace vcpkg::Util void unused(const Ts&...) { } + + template + T copy(const T& t) + { + return t; + } } diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index 457205384..223a1fb86 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -13,8 +13,14 @@ namespace vcpkg { BinaryParagraph(); explicit BinaryParagraph(Parse::RawParagraph fields); - BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag); - BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); + BinaryParagraph(const SourceParagraph& spgh, + const Triplet& triplet, + const std::string& abi_tag, + const std::vector& deps); + BinaryParagraph(const SourceParagraph& spgh, + const FeatureParagraph& fpgh, + const Triplet& triplet, + const std::vector& deps); std::string displayname() const; @@ -30,6 +36,7 @@ namespace vcpkg std::vector default_features; std::vector depends; std::string abi; + Type type; }; struct BinaryControlFile diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index be5424296..57663ebe5 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -21,6 +22,7 @@ namespace vcpkg::Build { void perform_and_exit_ex(const FullPackageSpec& full_spec, const SourceControlFileLocation& scfl, + const PortFileProvider::PathsPortFileProvider& provider, const ParsedArguments& options, const VcpkgPaths& paths); @@ -88,6 +90,12 @@ namespace vcpkg::Build YES }; + enum class PurgeDecompressFailure + { + NO = 0, + YES + }; + struct BuildPackageOptions { UseHeadVersion use_head_version; @@ -99,6 +107,7 @@ namespace vcpkg::Build DownloadTool download_tool; BinaryCaching binary_caching; FailOnTombstone fail_on_tombstone; + PurgeDecompressFailure purge_decompress_failure; }; enum class BuildResult @@ -130,12 +139,9 @@ namespace vcpkg::Build /// struct PreBuildInfo { - /// - /// Runs the triplet file in a "capture" mode to create a PreBuildInfo - /// - static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, - const Triplet& triplet, - Optional port = nullopt); + PreBuildInfo(const VcpkgPaths& paths, + const Triplet& triplet, + const std::unordered_map& cmakevars); std::string triplet_abi_tag; std::string target_architecture; @@ -193,12 +199,18 @@ namespace vcpkg::Build BuildPackageConfig(const SourceControlFileLocation& scfl, const Triplet& triplet, const BuildPackageOptions& build_package_options, - const std::set& feature_list) + const CMakeVars::CMakeVarProvider& var_provider, + const std::unordered_map>& feature_dependencies, + const std::vector& package_dependencies, + const std::vector& feature_list) : scfl(scfl) , scf(*scfl.source_control_file) , triplet(triplet) , port_dir(scfl.source_location) , build_package_options(build_package_options) + , var_provider(var_provider) + , feature_dependencies(feature_dependencies) + , package_dependencies(package_dependencies) , feature_list(feature_list) { } @@ -206,9 +218,13 @@ namespace vcpkg::Build const SourceControlFileLocation& scfl; const SourceControlFile& scf; const Triplet& triplet; - fs::path port_dir; + const fs::path& port_dir; const BuildPackageOptions& build_package_options; - const std::set& feature_list; + const CMakeVars::CMakeVarProvider& var_provider; + + const std::unordered_map>& feature_dependencies; + const std::vector& package_dependencies; + const std::vector& feature_list; }; ExtendedBuildResult build_package(const VcpkgPaths& paths, @@ -223,6 +239,7 @@ namespace vcpkg::Build ONLY_RELEASE_CRT, EMPTY_INCLUDE_FOLDER, ALLOW_OBSOLETE_MSVCRT, + ALLOW_RESTRICTED_HEADERS, // Must be last COUNT, }; @@ -234,6 +251,7 @@ namespace vcpkg::Build BuildPolicy::ONLY_RELEASE_CRT, BuildPolicy::EMPTY_INCLUDE_FOLDER, BuildPolicy::ALLOW_OBSOLETE_MSVCRT, + BuildPolicy::ALLOW_RESTRICTED_HEADERS, }; const std::string& to_string(BuildPolicy policy); diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h new file mode 100644 index 000000000..c634866d0 --- /dev/null +++ b/toolsrc/include/vcpkg/cmakevars.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include + +#include +#include + +namespace vcpkg::CMakeVars +{ + struct CMakeVarProvider + { + virtual Optional&> get_generic_triplet_vars( + const Triplet& triplet) const = 0; + + virtual Optional&> get_dep_info_vars( + const PackageSpec& spec) const = 0; + + virtual Optional&> get_tag_vars( + const PackageSpec& spec) const = 0; + + virtual void load_generic_triplet_vars(const Triplet& triplet) const = 0; + + virtual void load_dep_info_vars(Span specs) const = 0; + + virtual void load_tag_vars(Span specs, + const PortFileProvider::PortFileProvider& port_provider) const = 0; + }; + + 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(const 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( + const 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; + }; +} diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index e9018b1b8..eb9d42b6d 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -3,7 +3,9 @@ #include #include #include +#include #include +#include #include #include @@ -43,15 +45,12 @@ namespace vcpkg::Dependencies InstallPlanAction() noexcept; - InstallPlanAction(InstalledPackageView&& spghs, - const std::set& features, - const RequestType& request_type); + InstallPlanAction(InstalledPackageView&& spghs, const RequestType& request_type); InstallPlanAction(const PackageSpec& spec, const SourceControlFileLocation& scfl, - const std::set& features, const RequestType& request_type, - std::vector&& dependencies); + std::unordered_map>&& dependencies); std::string displayname() const; @@ -63,9 +62,11 @@ namespace vcpkg::Dependencies InstallPlanType plan_type; RequestType request_type; Build::BuildPackageOptions build_options; - std::set feature_list; - std::vector computed_dependencies; + std::unordered_map> feature_dependencies; + std::vector package_dependencies; + + std::vector feature_list; }; enum class RemovePlanType @@ -87,15 +88,14 @@ namespace vcpkg::Dependencies RequestType request_type; }; - struct AnyAction + struct ActionPlan { - AnyAction(InstallPlanAction&& iplan) : install_action(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {} - - Optional install_action; - Optional remove_action; + bool empty() const { return remove_actions.empty() && already_installed.empty() && install_actions.empty(); } + size_t size() const { return remove_actions.size() + already_installed.size() + install_actions.size(); } - const PackageSpec& spec() const; + std::vector remove_actions; + std::vector already_installed; + std::vector install_actions; }; enum class ExportPlanType @@ -127,80 +127,36 @@ namespace vcpkg::Dependencies Optional m_installed_package; }; - struct PortFileProvider - { - virtual Optional get_control_file(const std::string& src_name) const = 0; - virtual std::vector load_all_control_files() const = 0; - }; - - struct MapPortFileProvider : Util::ResourceBase, PortFileProvider - { - explicit MapPortFileProvider(const std::unordered_map& map); - Optional get_control_file(const std::string& src_name) const override; - std::vector load_all_control_files() const override; - - private: - const std::unordered_map& ports; - }; - - struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider - { - explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, - const std::vector* ports_dirs_paths); - Optional get_control_file(const std::string& src_name) const override; - std::vector load_all_control_files() const override; - - private: - Files::Filesystem& filesystem; - std::vector ports_dirs; - mutable std::unordered_map cache; - }; - struct ClusterGraph; - struct GraphPlan; struct CreateInstallPlanOptions { Graphs::Randomizer* randomizer = nullptr; }; - struct PackageGraph - { - PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db); - ~PackageGraph(); - - void install(const FeatureSpec& spec, - const std::unordered_set& prevent_default_features = {}) const; - void upgrade(const PackageSpec& spec) const; - - std::vector serialize(const CreateInstallPlanOptions& options = {}) const; - - private: - std::unique_ptr m_graph_plan; - std::unique_ptr m_graph; - }; - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); std::vector create_export_plan(const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_feature_install_plan( - const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db); - /// Figure out which actions are required to install features specifications in `specs`. /// Contains the ports of the current environment. /// Feature specifications to resolve dependencies for. /// Status of installed packages in the current environment. - std::vector create_feature_install_plan(const PortFileProvider& provider, - const std::vector& specs, - const StatusParagraphs& status_db, - const CreateInstallPlanOptions& options = {}); - - void print_plan(const std::vector& action_plan, + ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& provider, + const CMakeVars::CMakeVarProvider& var_provider, + const std::vector& specs, + const StatusParagraphs& status_db, + const CreateInstallPlanOptions& options = {}); + + ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& provider, + const CMakeVars::CMakeVarProvider& var_provider, + const std::vector& specs, + const StatusParagraphs& status_db, + const CreateInstallPlanOptions& options = {}); + + void print_plan(const ActionPlan& action_plan, const bool is_recursive = true, const fs::path& default_ports_dir = ""); } diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 2e92764dc..e020c8653 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -20,7 +20,7 @@ namespace vcpkg::Install struct SpecSummary { - SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action); + SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action); const BinaryParagraph* get_binary_paragraph() const; @@ -28,7 +28,7 @@ namespace vcpkg::Install Build::ExtendedBuildResult build_result; vcpkg::Chrono::ElapsedTime timing; - const Dependencies::AnyAction* action; + const Dependencies::InstallPlanAction* action; }; struct InstallSummary @@ -58,8 +58,9 @@ namespace vcpkg::Install }; Build::ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - StatusParagraphs& status_db); + Dependencies::InstallPlanAction& action, + StatusParagraphs& status_db, + const CMakeVars::CMakeVarProvider& var_provider); enum class InstallResult { @@ -74,10 +75,11 @@ namespace vcpkg::Install const BinaryControlFile& binary_paragraph, StatusParagraphs* status_db); - InstallSummary perform(const std::vector& action_plan, + InstallSummary perform(Dependencies::ActionPlan& action_plan, const KeepGoing keep_going, const VcpkgPaths& paths, - StatusParagraphs& status_db); + StatusParagraphs& status_db, + const CMakeVars::CMakeVarProvider& var_provider); extern const CommandStructure COMMAND_STRUCTURE; diff --git a/toolsrc/include/vcpkg/logicexpression.h b/toolsrc/include/vcpkg/logicexpression.h index 8795971b9..3a3d0debe 100644 --- a/toolsrc/include/vcpkg/logicexpression.h +++ b/toolsrc/include/vcpkg/logicexpression.h @@ -1,10 +1,24 @@ #pragma once #include +#include +#include namespace vcpkg { + struct ExpressionContext + { + // map of cmake variables and their values. + const std::unordered_map& cmake_context; + + // The legacy context is a string (typically the name of the triplet). + // An identifier was considered 'true' if it is a substring of this. + // It is now used for backwards compatability diagnostic messages and + // will be eventually removed. + const std::string& legacy_context; + }; + // Evaluate simple vcpkg logic expressions. An identifier in the expression is considered 'true' // if it is a substring of the evaluation_context (typically the name of the triplet) - bool evaluate_expression(const std::string& expression, const std::string& evaluation_context); + ExpectedT evaluate_expression(const std::string& expression, const ExpressionContext& context); } \ No newline at end of file diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index c87c6a2c6..628352cdb 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -23,6 +23,9 @@ namespace vcpkg /// struct PackageSpec { + PackageSpec() noexcept = default; + PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) {} + static ExpectedT from_name_and_triplet(const std::string& name, const Triplet& triplet); @@ -103,7 +106,14 @@ namespace vcpkg PackageSpec package_spec; std::vector features; - static std::vector to_feature_specs(const std::vector& specs); + FullPackageSpec() noexcept = default; + explicit FullPackageSpec(PackageSpec spec, std::vector features = {}) + : package_spec(std::move(spec)), features(std::move(features)) + { + } + + std::vector to_feature_specs(const std::vector& default_features, + const std::vector& all_features) const; static ExpectedT from_string(const std::string& spec_as_string, const Triplet& default_triplet); @@ -145,4 +155,21 @@ namespace std { bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } }; + + template<> + struct hash + { + size_t operator()(const vcpkg::FeatureSpec& value) const + { + size_t hash = std::hash()(value.spec()); + hash = hash * 31 + std::hash()(value.feature()); + return hash; + } + }; + + template<> + struct equal_to + { + bool operator()(const vcpkg::FeatureSpec& left, const vcpkg::FeatureSpec& right) const { return left == right; } + }; } diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h new file mode 100644 index 000000000..79f69d9ae --- /dev/null +++ b/toolsrc/include/vcpkg/portfileprovider.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg::PortFileProvider +{ + struct PortFileProvider + { + virtual Optional get_control_file(const std::string& src_name) const = 0; + virtual std::vector load_all_control_files() const = 0; + }; + + struct MapPortFileProvider : Util::ResourceBase, PortFileProvider + { + explicit MapPortFileProvider(const std::unordered_map& map); + Optional get_control_file(const std::string& src_name) const override; + std::vector load_all_control_files() const override; + + private: + const std::unordered_map& ports; + }; + + struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider + { + explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, + const std::vector* ports_dirs_paths); + Optional get_control_file(const std::string& src_name) const override; + std::vector load_all_control_files() const override; + + private: + Files::Filesystem& filesystem; + std::vector ports_dirs; + mutable std::unordered_map cache; + }; +} diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index 95347770a..0574afe74 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -7,6 +7,8 @@ #include #include +#include + #include #include @@ -21,15 +23,28 @@ namespace vcpkg static Dependency parse_dependency(std::string name, std::string qualifier); }; - std::vector filter_dependencies(const std::vector& deps, const Triplet& t); - std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); - std::vector filter_dependencies_to_features(const std::vector& deps, const Triplet& t); + std::vector filter_dependencies(const std::vector& deps, + const Triplet& t, + const std::unordered_map& cmake_vars); // zlib[uwp] becomes Dependency{"zlib", "uwp"} std::vector expand_qualified_dependencies(const std::vector& depends); std::string to_string(const Dependency& dep); + struct Type + { + enum + { + UNKNOWN, + PORT, + ALIAS, + } type; + + static std::string to_string(const Type&); + static Type from_string(const std::string&); + }; + /// /// Port metadata of additional feature in a package (part of CONTROL file) /// @@ -50,9 +65,10 @@ namespace vcpkg std::string description; std::string maintainer; std::string homepage; - std::vector supports; std::vector depends; std::vector default_features; + Type type; + std::string supports_expression; }; /// @@ -60,21 +76,48 @@ namespace vcpkg /// struct SourceControlFile { + SourceControlFile() = default; + SourceControlFile(const SourceControlFile& scf) + : core_paragraph(std::make_unique(*scf.core_paragraph)) + { + for (const auto& feat_ptr : scf.feature_paragraphs) + { + feature_paragraphs.emplace_back(std::make_unique(*feat_ptr)); + } + } + static Parse::ParseExpected parse_control_file( - std::vector&& control_paragraphs); + const fs::path& path_to_control, std::vector&& control_paragraphs); std::unique_ptr core_paragraph; std::vector> feature_paragraphs; Optional find_feature(const std::string& featurename) const; + Optional&> find_dependencies_for_feature(const std::string& featurename) const; }; /// - /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was loaded - /// from. + /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was + /// loaded from. /// struct SourceControlFileLocation { + SourceControlFileLocation(const SourceControlFileLocation& scfl) + : source_control_file(std::make_unique(*scfl.source_control_file)) + , source_location(scfl.source_location) + { + } + + SourceControlFileLocation(std::unique_ptr&& scf, fs::path&& source) + : source_control_file(std::move(scf)), source_location(std::move(source)) + { + } + + SourceControlFileLocation(std::unique_ptr&& scf, const fs::path& source) + : source_control_file(std::move(scf)), source_location(source) + { + } + std::unique_ptr source_control_file; fs::path source_location; }; @@ -84,35 +127,4 @@ namespace vcpkg { return print_error_message({&error_info_list, 1}); } - - struct Supports - { - static ExpectedT> parse(const std::vector& strs); - - using Architecture = System::CPUArchitecture; - - enum class Platform - { - WINDOWS, - UWP, - }; - enum class Linkage - { - DYNAMIC, - STATIC, - }; - enum class ToolsetVersion - { - V140, - V141, - }; - - bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); - - private: - std::vector architectures; - std::vector platforms; - std::vector crt_linkages; - std::vector toolsets; - }; } diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h index 6e832fe2f..ec850607d 100644 --- a/toolsrc/include/vcpkg/statusparagraph.h +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -56,6 +56,7 @@ namespace vcpkg const PackageSpec& spec() const { return core->package.spec; } std::vector dependencies() const; + std::unordered_map> feature_dependencies() const; const StatusParagraph* core; std::vector features; diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h index b85f7b2b3..6091da778 100644 --- a/toolsrc/include/vcpkg/update.h +++ b/toolsrc/include/vcpkg/update.h @@ -17,7 +17,7 @@ namespace vcpkg::Update VersionDiff version_diff; }; - std::vector find_outdated_packages(const Dependencies::PortFileProvider& provider, + std::vector find_outdated_packages(const PortFileProvider::PortFileProvider& provider, const StatusParagraphs& status_db); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); -- cgit v1.2.3