diff --git a/toolsrc/include/vcpkg/commands.setinstalled.h b/toolsrc/include/vcpkg/commands.setinstalled.h index 38cd813697eae4..c5723669bd7307 100644 --- a/toolsrc/include/vcpkg/commands.setinstalled.h +++ b/toolsrc/include/vcpkg/commands.setinstalled.h @@ -12,8 +12,7 @@ namespace vcpkg::Commands::SetInstalled const PortFileProvider::PathsPortFileProvider& provider, IBinaryProvider& binary_provider, const CMakeVars::CMakeVarProvider& cmake_vars, - const std::vector& specs, - const Build::BuildPackageOptions& install_plan_options, + Dependencies::ActionPlan action_plan, DryRun dry_run, const Optional& pkgsconfig_path); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 495056884b0b08..e23aa924e12efe 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -21,6 +21,8 @@ namespace vcpkg /// struct PackageSpec { + constexpr static StringLiteral MANIFEST_NAME = "default"; + PackageSpec() = default; PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) { } diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h index e4b5d9cb5f6231..e26580729b5bfe 100644 --- a/toolsrc/include/vcpkg/portfileprovider.h +++ b/toolsrc/include/vcpkg/portfileprovider.h @@ -32,7 +32,10 @@ namespace vcpkg::PortFileProvider std::vector load_all_control_files() const override; private: + const SourceControlFileLocation* load_manifest_file() const; + Files::Filesystem& filesystem; + fs::path manifest; std::vector ports_dirs; mutable std::unordered_map cache; }; diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp index 742a7a536f00ef..a99c3af4a902d0 100644 --- a/toolsrc/src/vcpkg/commands.setinstalled.cpp +++ b/toolsrc/src/vcpkg/commands.setinstalled.cpp @@ -39,21 +39,10 @@ namespace vcpkg::Commands::SetInstalled const PortFileProvider::PathsPortFileProvider& provider, IBinaryProvider& binary_provider, const CMakeVars::CMakeVarProvider& cmake_vars, - const std::vector& specs, - const Build::BuildPackageOptions& install_plan_options, + Dependencies::ActionPlan action_plan, DryRun dry_run, const Optional& maybe_pkgsconfig) { - // We have a set of user-requested specs. - // We need to know all the specs which are required to fulfill dependencies for those specs. - // Therefore, we see what we would install into an empty installed tree, so we can use the existing code. - auto action_plan = Dependencies::create_feature_install_plan(provider, cmake_vars, specs, {}); - - for (auto&& action : action_plan.install_actions) - { - action.build_options = install_plan_options; - } - cmake_vars.load_tag_vars(action_plan, provider); Build::compute_all_abis(paths, action_plan, cmake_vars, {}); @@ -155,13 +144,23 @@ namespace vcpkg::Commands::SetInstalled { pkgsconfig = it_pkgsconfig->second; } + + // We have a set of user-requested specs. + // We need to know all the specs which are required to fulfill dependencies for those specs. + // Therefore, we see what we would install into an empty installed tree, so we can use the existing code. + auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {}); + + for (auto&& action : action_plan.install_actions) + { + action.build_options = Build::default_build_package_options; + } + perform_and_exit_ex(args, paths, provider, *binary_provider, *cmake_vars, - specs, - vcpkg::Build::default_build_package_options, + std::move(action_plan), dry_run ? DryRun::Yes : DryRun::No, pkgsconfig); } diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index e9af12929f9601..d4757cfcc408a4 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -627,7 +627,19 @@ namespace vcpkg::Dependencies } pgraph.install(feature_specs); - return pgraph.serialize(options); + auto res = pgraph.serialize(options); + + const auto is_manifest_spec = [](const auto& action) { + return action.spec.name() == PackageSpec::MANIFEST_NAME; + }; + + Util::erase_remove_if(res.install_actions, is_manifest_spec); + + Checks::check_exit(VCPKG_LINE_INFO, + !std::any_of(res.remove_actions.begin(), res.remove_actions.end(), is_manifest_spec), + "\"default\" should never be installed"); + + return res; } void PackageGraph::mark_for_reinstall(const PackageSpec& first_remove_spec, diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 053acb2ecb3de9..ec8eba8dd1e0c9 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -743,48 +743,30 @@ namespace vcpkg::Install if (paths.manifest_mode_enabled()) { - std::error_code ec; - const auto path_to_manifest = paths.manifest_root_dir / "vcpkg.json"; - auto res = Paragraphs::try_load_manifest(paths.get_filesystem(), "user manifest", path_to_manifest, ec); - - if (ec) + Optional pkgsconfig; + auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG); + if (it_pkgsconfig != options.settings.end()) { - Checks::exit_with_message(VCPKG_LINE_INFO, - "Failed to load manifest file (%s): %s\n", - path_to_manifest.u8string(), - ec.message()); + pkgsconfig = fs::u8path(it_pkgsconfig->second); } std::vector specs; - if (auto val = res.get()) - { - for (auto& dep : (*val)->core_paragraph->dependencies) - { - specs.push_back(FullPackageSpec{ - {std::move(dep.name), default_triplet}, - std::move(dep.features), - }); - } - } - else - { - print_error_message(res.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } + specs.emplace_back(PackageSpec{PackageSpec::MANIFEST_NAME, default_triplet}); + auto install_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, {}); - Optional pkgsconfig; - auto it_pkgsconfig = options.settings.find(OPTION_WRITE_PACKAGES_CONFIG); - if (it_pkgsconfig != options.settings.end()) + for (InstallPlanAction& action : install_plan.install_actions) { - pkgsconfig = fs::u8path(it_pkgsconfig->second); + action.build_options = install_plan_options; + action.build_options.use_head_version = Build::UseHeadVersion::NO; + action.build_options.editable = Build::Editable::NO; } + Commands::SetInstalled::perform_and_exit_ex(args, paths, provider, *binaryprovider, var_provider, - specs, - install_plan_options, + std::move(install_plan), dry_run ? Commands::DryRun::Yes : Commands::DryRun::No, pkgsconfig); } diff --git a/toolsrc/src/vcpkg/portfileprovider.cpp b/toolsrc/src/vcpkg/portfileprovider.cpp index 707b763a414ef7..c0538fdb8264d5 100644 --- a/toolsrc/src/vcpkg/portfileprovider.cpp +++ b/toolsrc/src/vcpkg/portfileprovider.cpp @@ -29,6 +29,10 @@ namespace vcpkg::PortFileProvider const std::vector& ports_dirs_paths) : filesystem(paths.get_filesystem()) { + if (paths.manifest_mode_enabled()) + { + manifest = paths.manifest_root_dir / fs::u8path("vcpkg.json"); + } auto& fs = paths.get_filesystem(); for (auto&& overlay_path : ports_dirs_paths) { @@ -60,6 +64,38 @@ namespace vcpkg::PortFileProvider ports_dirs.emplace_back(paths.ports); } + const SourceControlFileLocation* PathsPortFileProvider::load_manifest_file() const + { + if (!manifest.empty()) + { + std::error_code ec; + auto maybe_scf = Paragraphs::try_load_manifest(filesystem, "manifest", manifest, ec); + if (ec) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Failed to read manifest file %s: %s", manifest.u8string(), ec.message()); + } + + if (auto scf = maybe_scf.get()) + { + auto it = cache.emplace(std::piecewise_construct, + std::forward_as_tuple(PackageSpec::MANIFEST_NAME), + std::forward_as_tuple(std::move(*scf), manifest.parent_path())); + return &it.first->second; + } + else + { + vcpkg::print_error_message(maybe_scf.error()); + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Failed to load manifest file %s.", manifest.u8string()); + } + } + else + { + return nullptr; + } + } + ExpectedS PathsPortFileProvider::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); @@ -68,6 +104,18 @@ namespace vcpkg::PortFileProvider return cache_it->second; } + if (spec == PackageSpec::MANIFEST_NAME) + { + if (auto p = load_manifest_file()) + { + return *p; + } + else + { + Checks::unreachable(VCPKG_LINE_INFO); + } + } + for (auto&& ports_dir : ports_dirs) { // Try loading individual port @@ -88,7 +136,7 @@ namespace vcpkg::PortFileProvider { vcpkg::print_error_message(maybe_scf.error()); Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Failed to load port from %s", spec, ports_dir.u8string()); + VCPKG_LINE_INFO, "Error: Failed to load port %s from %s", spec, ports_dir.u8string()); } continue; @@ -130,6 +178,12 @@ namespace vcpkg::PortFileProvider // Reload cache with ports contained in all ports_dirs cache.clear(); std::vector ret; + + if (auto p = load_manifest_file()) + { + ret.push_back(p); + } + for (auto&& ports_dir : ports_dirs) { // Try loading individual port