mirror of
https://github.com/cemu-project/vcpkg.git
synced 2025-02-24 03:27:12 +01:00
partial end to end feature packages hdf5
added vcpkg feature package support to other commands remove comments change qualifier bracket to parens added features to qualified dependencies
This commit is contained in:
parent
bd7cd7f56d
commit
307b761df4
@ -31,5 +31,11 @@ namespace vcpkg
|
||||
std::vector<std::string> depends;
|
||||
};
|
||||
|
||||
struct BinaryControlFile
|
||||
{
|
||||
BinaryParagraph core_paragraph;
|
||||
std::vector<BinaryParagraph> features;
|
||||
};
|
||||
|
||||
void serialize(const BinaryParagraph& pgh, std::string& out_str);
|
||||
}
|
@ -20,7 +20,7 @@ namespace vcpkg::Paragraphs
|
||||
|
||||
Parse::ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& control_path);
|
||||
|
||||
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec);
|
||||
Expected<BinaryControlFile> try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec);
|
||||
|
||||
struct LoadResults
|
||||
{
|
||||
|
@ -15,13 +15,24 @@ namespace vcpkg
|
||||
|
||||
struct Triplet;
|
||||
|
||||
struct Dependency
|
||||
struct Features
|
||||
{
|
||||
std::string name;
|
||||
std::string qualifier;
|
||||
std::vector<std::string> features;
|
||||
};
|
||||
|
||||
const std::string& to_string(const Dependency& dep);
|
||||
Features parse_feature_list(const std::string& name);
|
||||
|
||||
struct Dependency
|
||||
{
|
||||
Features depend;
|
||||
std::string qualifier;
|
||||
|
||||
std::string name() const;
|
||||
static Dependency parse_dependency(std::string name, std::string qualifier);
|
||||
};
|
||||
|
||||
const std::string to_string(const Dependency& dep);
|
||||
|
||||
struct FeatureParagraph
|
||||
{
|
||||
|
@ -17,6 +17,9 @@ namespace vcpkg
|
||||
const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); }
|
||||
const_iterator find(const std::string& name, const Triplet& triplet) const;
|
||||
iterator find(const std::string& name, const Triplet& triplet);
|
||||
std::vector<std::unique_ptr<StatusParagraph>*> StatusParagraphs::find_all(const std::string& name,
|
||||
const Triplet& triplet);
|
||||
iterator find(const std::string& name, const Triplet& triplet, const std::string& feature);
|
||||
|
||||
const_iterator find_installed(const PackageSpec& spec) const
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ namespace vcpkg::Commands
|
||||
const fs::path& source_dir,
|
||||
const InstallDir& dirs);
|
||||
void install_package(const VcpkgPaths& paths,
|
||||
const BinaryParagraph& binary_paragraph,
|
||||
const BinaryControlFile& binary_paragraph,
|
||||
StatusParagraphs* status_db);
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ namespace vcpkg::Dependencies
|
||||
InstallPlanAction(InstallPlanAction&&) = default;
|
||||
InstallPlanAction& operator=(const InstallPlanAction&) = delete;
|
||||
InstallPlanAction& operator=(InstallPlanAction&&) = default;
|
||||
std::string displayname() const;
|
||||
|
||||
PackageSpec spec;
|
||||
AnyParagraph any_paragraph;
|
||||
@ -205,7 +206,9 @@ namespace vcpkg::Dependencies
|
||||
std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster,
|
||||
GraphPlan& graph_plan);
|
||||
void mark_minus(Cluster& cluster, std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster, GraphPlan& graph_plan);
|
||||
|
||||
void mark_plus_default(Cluster& cluster,
|
||||
std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster,
|
||||
GraphPlan& graph_plan);
|
||||
std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<PackageSpec, SourceControlFile>& map,
|
||||
const std::vector<FullPackageSpec>& specs,
|
||||
const StatusParagraphs& status_db);
|
||||
|
@ -87,7 +87,17 @@ namespace vcpkg
|
||||
this->depends = filter_dependencies(fpgh.depends, triplet);
|
||||
}
|
||||
|
||||
std::string BinaryParagraph::displayname() const { return this->spec.to_string(); }
|
||||
std::string BinaryParagraph::displayname() const
|
||||
{
|
||||
if (this->feature == "")
|
||||
{
|
||||
return this->spec.name() + "[core]:" + this->spec.triplet().to_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->spec.name() + "[" + this->feature + "]:" + this->spec.triplet().to_string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string BinaryParagraph::dir() const { return this->spec.dir(); }
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "ParagraphParseResult.h"
|
||||
#include "Paragraphs.h"
|
||||
#include "vcpkg_Files.h"
|
||||
#include "vcpkg_Util.h"
|
||||
|
||||
using namespace vcpkg::Parse;
|
||||
|
||||
@ -226,14 +227,21 @@ namespace vcpkg::Paragraphs
|
||||
return error_info;
|
||||
}
|
||||
|
||||
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
||||
Expected<BinaryControlFile> try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec)
|
||||
{
|
||||
Expected<std::unordered_map<std::string, std::string>> pghs =
|
||||
get_single_paragraph(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
|
||||
Expected<std::vector<std::unordered_map<std::string, std::string>>> pghs =
|
||||
get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL");
|
||||
|
||||
if (auto p = pghs.get())
|
||||
{
|
||||
return BinaryParagraph(*p);
|
||||
BinaryControlFile bcf;
|
||||
bcf.core_paragraph = BinaryParagraph(p->front());
|
||||
p->erase(p->begin());
|
||||
|
||||
bcf.features =
|
||||
Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); });
|
||||
|
||||
return bcf;
|
||||
}
|
||||
|
||||
return pghs.error();
|
||||
|
@ -152,18 +152,61 @@ namespace vcpkg
|
||||
return std::move(control_file);
|
||||
}
|
||||
|
||||
Features parse_feature_list(const std::string& name)
|
||||
{
|
||||
Features f;
|
||||
int end = (int)name.find(']');
|
||||
if (end != std::string::npos)
|
||||
{
|
||||
int start = (int)name.find('[');
|
||||
|
||||
auto feature_name_list = name.substr(start + 1, end - start - 1);
|
||||
f.name = name.substr(0, start);
|
||||
f.features = parse_comma_list(feature_name_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.name = name;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
Dependency Dependency::parse_dependency(std::string name, std::string qualifier)
|
||||
{
|
||||
Dependency dep;
|
||||
dep.qualifier = qualifier;
|
||||
dep.depend = parse_feature_list(name);
|
||||
return dep;
|
||||
}
|
||||
|
||||
std::string Dependency::name() const
|
||||
{
|
||||
std::string str = this->depend.name;
|
||||
if (this->depend.features.empty()) return str;
|
||||
|
||||
str += "[";
|
||||
for (auto&& s : this->depend.features)
|
||||
{
|
||||
str += s + ",";
|
||||
}
|
||||
str.pop_back();
|
||||
str += "]";
|
||||
return str;
|
||||
}
|
||||
|
||||
std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
|
||||
{
|
||||
return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency {
|
||||
auto pos = depend_string.find(' ');
|
||||
if (pos == std::string::npos) return {depend_string, ""};
|
||||
if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, "");
|
||||
// expect of the form "\w+ \[\w+\]"
|
||||
Dependency dep;
|
||||
dep.name = depend_string.substr(0, pos);
|
||||
|
||||
dep.depend.name = depend_string.substr(0, pos);
|
||||
if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')')
|
||||
{
|
||||
// Error, but for now just slurp the entire string.
|
||||
return {depend_string, ""};
|
||||
return Dependency::parse_dependency(depend_string, "");
|
||||
}
|
||||
dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3);
|
||||
return dep;
|
||||
@ -210,13 +253,17 @@ namespace vcpkg
|
||||
{
|
||||
if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos)
|
||||
{
|
||||
ret.push_back(dep.name);
|
||||
ret.emplace_back(dep.name());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::string& to_string(const Dependency& dep) { return dep.name; }
|
||||
const std::string to_string(const Dependency& dep)
|
||||
{
|
||||
std::string name = dep.name();
|
||||
return name;
|
||||
}
|
||||
|
||||
ExpectedT<Supports, std::vector<std::string>> Supports::parse(const std::vector<std::string>& strs)
|
||||
{
|
||||
|
@ -27,6 +27,30 @@ namespace vcpkg
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<StatusParagraph>*> StatusParagraphs::find_all(const std::string& name,
|
||||
const Triplet& triplet)
|
||||
{
|
||||
std::vector<std::unique_ptr<StatusParagraph>*> spghs;
|
||||
for (auto&& p : *this)
|
||||
{
|
||||
if (p->package.spec.name() == name && p->package.spec.triplet() == triplet)
|
||||
{
|
||||
spghs.emplace_back(&p);
|
||||
}
|
||||
}
|
||||
return spghs;
|
||||
}
|
||||
|
||||
StatusParagraphs::iterator StatusParagraphs::find(const std::string& name,
|
||||
const Triplet& triplet,
|
||||
const std::string& feature)
|
||||
{
|
||||
return std::find_if(begin(), end(), [&](const std::unique_ptr<StatusParagraph>& pgh) {
|
||||
const PackageSpec& spec = pgh->package.spec;
|
||||
return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature;
|
||||
});
|
||||
}
|
||||
|
||||
StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name,
|
||||
const Triplet& triplet) const
|
||||
{
|
||||
@ -43,7 +67,7 @@ namespace vcpkg
|
||||
{
|
||||
Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph");
|
||||
const PackageSpec& spec = pgh->package.spec;
|
||||
auto ptr = find(spec.name(), spec.triplet());
|
||||
auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature);
|
||||
if (ptr == end())
|
||||
{
|
||||
paragraphs.push_back(std::move(pgh));
|
||||
|
@ -46,7 +46,7 @@ namespace vcpkg::Commands::DependInfo
|
||||
for (auto&& source_control_file : source_control_files)
|
||||
{
|
||||
const SourceParagraph& source_paragraph = *source_control_file->core_paragraph;
|
||||
auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name; });
|
||||
auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); });
|
||||
System::println("%s: %s", source_paragraph.name, s);
|
||||
}
|
||||
|
||||
|
@ -211,10 +211,10 @@ namespace vcpkg::Commands::Install
|
||||
}
|
||||
}
|
||||
|
||||
void install_package(const VcpkgPaths& paths, const BinaryParagraph& binary_paragraph, StatusParagraphs* status_db)
|
||||
void install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db)
|
||||
{
|
||||
const fs::path package_dir = paths.package_dir(binary_paragraph.spec);
|
||||
const Triplet& triplet = binary_paragraph.spec.triplet();
|
||||
const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec);
|
||||
const Triplet& triplet = bcf.core_paragraph.spec.triplet();
|
||||
const std::vector<StatusParagraphAndAssociatedFiles> pgh_and_files = get_installed_files(paths, *status_db);
|
||||
|
||||
const SortedVector<std::string> package_files =
|
||||
@ -234,7 +234,7 @@ namespace vcpkg::Commands::Install
|
||||
System::println(System::Color::error,
|
||||
"The following files are already installed in %s and are in conflict with %s",
|
||||
triplet_install_path.generic_string(),
|
||||
binary_paragraph.spec);
|
||||
bcf.core_paragraph.spec);
|
||||
System::print("\n ");
|
||||
System::println(Strings::join("\n ", intersection));
|
||||
System::println("");
|
||||
@ -242,27 +242,42 @@ namespace vcpkg::Commands::Install
|
||||
}
|
||||
|
||||
StatusParagraph source_paragraph;
|
||||
source_paragraph.package = binary_paragraph;
|
||||
source_paragraph.package = bcf.core_paragraph;
|
||||
source_paragraph.want = Want::INSTALL;
|
||||
source_paragraph.state = InstallState::HALF_INSTALLED;
|
||||
for (auto&& dep : source_paragraph.package.depends)
|
||||
{
|
||||
if (status_db->find_installed(dep, source_paragraph.package.spec.triplet()) == status_db->end())
|
||||
{
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
write_update(paths, source_paragraph);
|
||||
status_db->insert(std::make_unique<StatusParagraph>(source_paragraph));
|
||||
|
||||
std::vector<StatusParagraph> features_spghs;
|
||||
for (auto&& feature : bcf.features)
|
||||
{
|
||||
features_spghs.emplace_back();
|
||||
|
||||
StatusParagraph& feature_paragraph = features_spghs.back();
|
||||
feature_paragraph.package = feature;
|
||||
feature_paragraph.want = Want::INSTALL;
|
||||
feature_paragraph.state = InstallState::HALF_INSTALLED;
|
||||
|
||||
write_update(paths, feature_paragraph);
|
||||
status_db->insert(std::make_unique<StatusParagraph>(feature_paragraph));
|
||||
}
|
||||
|
||||
const InstallDir install_dir = InstallDir::from_destination_root(
|
||||
paths.installed, triplet.to_string(), paths.listfile_path(binary_paragraph));
|
||||
paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph));
|
||||
|
||||
install_files_and_write_listfile(paths.get_filesystem(), package_dir, install_dir);
|
||||
|
||||
source_paragraph.state = InstallState::INSTALLED;
|
||||
write_update(paths, source_paragraph);
|
||||
status_db->insert(std::make_unique<StatusParagraph>(source_paragraph));
|
||||
|
||||
for (auto&& feature_paragraph : features_spghs)
|
||||
{
|
||||
feature_paragraph.state = InstallState::INSTALLED;
|
||||
write_update(paths, feature_paragraph);
|
||||
status_db->insert(std::make_unique<StatusParagraph>(feature_paragraph));
|
||||
}
|
||||
}
|
||||
|
||||
using Build::BuildResult;
|
||||
@ -312,8 +327,8 @@ namespace vcpkg::Commands::Install
|
||||
}
|
||||
System::println("Building package %s... done", display_name);
|
||||
|
||||
const BinaryParagraph bpgh =
|
||||
Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO);
|
||||
const BinaryControlFile bpgh =
|
||||
Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO);
|
||||
System::println("Installing package %s... ", display_name);
|
||||
install_package(paths, bpgh, &status_db);
|
||||
System::println(System::Color::success, "Installing package %s... done", display_name);
|
||||
@ -322,10 +337,11 @@ namespace vcpkg::Commands::Install
|
||||
|
||||
if (plan_type == InstallPlanType::BUILD_AND_INSTALL && g_feature_packages)
|
||||
{
|
||||
const std::string display_name_feature = action.displayname();
|
||||
if (use_head_version)
|
||||
System::println("Building package %s from HEAD... ", display_name);
|
||||
System::println("Building package %s from HEAD... ", display_name_feature);
|
||||
else
|
||||
System::println("Building package %s... ", display_name);
|
||||
System::println("Building package %s... ", display_name_feature);
|
||||
|
||||
const Build::BuildPackageConfig build_config{
|
||||
*action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO),
|
||||
@ -339,13 +355,13 @@ namespace vcpkg::Commands::Install
|
||||
System::println(System::Color::error, Build::create_error_message(result.code, action.spec));
|
||||
return result.code;
|
||||
}
|
||||
System::println("Building package %s... done", display_name);
|
||||
System::println("Building package %s... done", display_name_feature);
|
||||
|
||||
const BinaryParagraph bpgh =
|
||||
Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO);
|
||||
System::println("Installing package %s... ", display_name);
|
||||
install_package(paths, bpgh, &status_db);
|
||||
System::println(System::Color::success, "Installing package %s... done", display_name);
|
||||
const BinaryControlFile bcf =
|
||||
Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO);
|
||||
System::println("Installing package %s... ", display_name_feature);
|
||||
install_package(paths, bcf, &status_db);
|
||||
System::println(System::Color::success, "Installing package %s... done", display_name_feature);
|
||||
return BuildResult::SUCCEEDED;
|
||||
}
|
||||
|
||||
@ -357,7 +373,9 @@ namespace vcpkg::Commands::Install
|
||||
System::Color::warning, "Package %s is already built -- not building from HEAD", display_name);
|
||||
}
|
||||
System::println("Installing package %s... ", display_name);
|
||||
install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db);
|
||||
install_package(paths,
|
||||
BinaryControlFile{action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO)},
|
||||
&status_db);
|
||||
System::println(System::Color::success, "Installing package %s... done", display_name);
|
||||
return BuildResult::SUCCEEDED;
|
||||
}
|
||||
@ -365,11 +383,27 @@ namespace vcpkg::Commands::Install
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
static void print_plan(const std::vector<const InstallPlanAction*> rebuilt_plans,
|
||||
const std::vector<const InstallPlanAction*> new_plans)
|
||||
{
|
||||
const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) {
|
||||
return Dependencies::to_output_string(p->request_type, p->displayname());
|
||||
});
|
||||
|
||||
const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) {
|
||||
return Dependencies::to_output_string(p->request_type, p->displayname());
|
||||
});
|
||||
|
||||
if (rebuilt_plans.size() > 0) System::println("The following packages will be rebuilt:\n%s", rebuilt_string);
|
||||
if (new_plans.size() > 0) System::println("The following packages will be installed:\n%s", new_string);
|
||||
}
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
|
||||
{
|
||||
static const std::string OPTION_DRY_RUN = "--dry-run";
|
||||
static const std::string OPTION_USE_HEAD_VERSION = "--head";
|
||||
static const std::string OPTION_NO_DOWNLOADS = "--no-downloads";
|
||||
static const std::string OPTION_RECURSE = "--recurse";
|
||||
|
||||
// input sanitization
|
||||
static const std::string example =
|
||||
@ -383,14 +417,130 @@ namespace vcpkg::Commands::Install
|
||||
Input::check_triplet(spec.triplet(), paths);
|
||||
|
||||
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments(
|
||||
{OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS});
|
||||
{OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE});
|
||||
const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend();
|
||||
const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend();
|
||||
const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend();
|
||||
const bool isRecursive = options.find(OPTION_RECURSE) != options.cend();
|
||||
|
||||
// create the plan
|
||||
StatusParagraphs status_db = database_load_check(paths);
|
||||
|
||||
if (g_feature_packages)
|
||||
{
|
||||
const std::vector<FullPackageSpec> full_specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
|
||||
return Input::check_and_get_full_package_spec(arg, default_triplet, example);
|
||||
});
|
||||
|
||||
std::unordered_map<PackageSpec, SourceControlFile> scf_map;
|
||||
auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
|
||||
for (auto&& port : all_ports.paragraphs)
|
||||
{
|
||||
auto pkg_spec = PackageSpec::from_name_and_triplet(port->core_paragraph->name, default_triplet)
|
||||
.value_or_exit(VCPKG_LINE_INFO);
|
||||
scf_map[pkg_spec] = std::move(*port);
|
||||
}
|
||||
std::vector<Dependencies::AnyAction> action_plan =
|
||||
Dependencies::create_feature_install_plan(scf_map, full_specs, status_db);
|
||||
// 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 for feature packages");
|
||||
|
||||
const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version),
|
||||
Build::to_allow_downloads(!no_downloads)};
|
||||
|
||||
std::vector<const RemovePlanAction*> remove_plans;
|
||||
|
||||
std::vector<const InstallPlanAction*> rebuilt_plans;
|
||||
std::vector<const InstallPlanAction*> new_plans;
|
||||
|
||||
// removal will happen before install
|
||||
for (auto&& action : action_plan)
|
||||
{
|
||||
if (auto install_action = action.install_plan.get())
|
||||
{
|
||||
auto it = Util::find_if(
|
||||
remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; });
|
||||
if (it != remove_plans.end())
|
||||
{
|
||||
rebuilt_plans.emplace_back(install_action);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_plans.emplace_back(install_action);
|
||||
}
|
||||
}
|
||||
else if (auto remove_action = action.remove_plan.get())
|
||||
{
|
||||
remove_plans.emplace_back(remove_action);
|
||||
}
|
||||
}
|
||||
|
||||
print_plan(rebuilt_plans, new_plans);
|
||||
|
||||
if (remove_plans.size() > 0 && !isRecursive)
|
||||
{
|
||||
System::println(System::Color::warning,
|
||||
"If you are sure you want to rebuild the above packages, run the command with the "
|
||||
"--recurse option");
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
// execute the plan
|
||||
for (const Dependencies::AnyAction& any_action : action_plan)
|
||||
{
|
||||
if (auto install_action = any_action.install_plan.get())
|
||||
{
|
||||
const BuildResult result =
|
||||
perform_install_plan_action(paths, *install_action, install_plan_options, status_db);
|
||||
if (result != BuildResult::SUCCEEDED)
|
||||
{
|
||||
System::println(Build::create_user_troubleshooting_message(install_action->spec));
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
else if (auto remove_action = any_action.remove_plan.get())
|
||||
{
|
||||
static const std::string OPTION_PURGE = "--purge";
|
||||
static const std::string OPTION_NO_PURGE = "--no-purge";
|
||||
|
||||
const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end();
|
||||
if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages)
|
||||
{
|
||||
// User specified --purge and --no-purge
|
||||
System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge.");
|
||||
System::print(example);
|
||||
Checks::exit_fail(VCPKG_LINE_INFO);
|
||||
}
|
||||
const std::string display_name = remove_action->spec.to_string();
|
||||
switch (remove_action->plan_type)
|
||||
{
|
||||
case RemovePlanType::NOT_INSTALLED:
|
||||
System::println(System::Color::success, "Package %s is not installed", display_name);
|
||||
break;
|
||||
case RemovePlanType::REMOVE:
|
||||
System::println("Removing package %s... ", display_name);
|
||||
Commands::Remove::remove_package(paths, remove_action->spec, &status_db);
|
||||
System::println(System::Color::success, "Removing package %s... done", display_name);
|
||||
break;
|
||||
case RemovePlanType::UNKNOWN:
|
||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
if (alsoRemoveFolderFromPackages)
|
||||
{
|
||||
System::println("Purging package %s... ", display_name);
|
||||
Files::Filesystem& fs = paths.get_filesystem();
|
||||
std::error_code ec;
|
||||
fs.remove_all(paths.packages / remove_action->spec.dir(), ec);
|
||||
System::println(System::Color::success, "Purging package %s... done", display_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
Dependencies::PathsPortFile paths_port_file(paths);
|
||||
std::vector<InstallPlanAction> install_plan =
|
||||
Dependencies::create_install_plan(paths_port_file, specs, status_db);
|
||||
|
@ -17,13 +17,19 @@ namespace vcpkg::Commands::Remove
|
||||
void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db)
|
||||
{
|
||||
auto& fs = paths.get_filesystem();
|
||||
StatusParagraph& pkg = **status_db->find(spec.name(), spec.triplet());
|
||||
auto spghs = status_db->find_all(spec.name(), spec.triplet());
|
||||
auto core_pkg = **status_db->find(spec.name(), spec.triplet(), "");
|
||||
|
||||
for (auto&& spgh : spghs)
|
||||
{
|
||||
StatusParagraph& pkg = **spgh;
|
||||
if (pkg.state != InstallState::INSTALLED) continue;
|
||||
pkg.want = Want::PURGE;
|
||||
pkg.state = InstallState::HALF_INSTALLED;
|
||||
write_update(paths, pkg);
|
||||
}
|
||||
|
||||
auto maybe_lines = fs.read_lines(paths.listfile_path(pkg.package));
|
||||
auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package));
|
||||
|
||||
if (auto lines = maybe_lines.get())
|
||||
{
|
||||
@ -80,12 +86,17 @@ namespace vcpkg::Commands::Remove
|
||||
}
|
||||
}
|
||||
|
||||
fs.remove(paths.listfile_path(pkg.package));
|
||||
fs.remove(paths.listfile_path(core_pkg.package));
|
||||
}
|
||||
|
||||
for (auto&& spgh : spghs)
|
||||
{
|
||||
StatusParagraph& pkg = **spgh;
|
||||
if (pkg.state != InstallState::HALF_INSTALLED) continue;
|
||||
pkg.state = InstallState::NOT_INSTALLED;
|
||||
write_update(paths, pkg);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_plan(const std::map<RemovePlanType, std::vector<const RemovePlanAction*>>& group_by_plan_type)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace vcpkg::Commands::Search
|
||||
s.append(Strings::format("%s;", name));
|
||||
for (const Dependency& d : source_paragraph.depends)
|
||||
{
|
||||
const std::string dependency_name = replace_dashes_with_underscore(d.name);
|
||||
const std::string dependency_name = replace_dashes_with_underscore(d.name());
|
||||
s.append(Strings::format("%s -> %s;", name, dependency_name));
|
||||
}
|
||||
}
|
||||
|
@ -347,13 +347,13 @@ namespace UnitTest1
|
||||
spec_map.get_package_spec(
|
||||
{{{"Source", "a"}, {"Version", "1.3"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[1]"}},
|
||||
{{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}},
|
||||
{{"Feature", "3"}, {"Description", "the first feature for a"}, {"Build-Depends", "a[2]"}}}),
|
||||
{{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", "b[2]"}},
|
||||
{{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", "a[2]"}}}),
|
||||
{"3"}};
|
||||
auto spec_b = FullPackageSpec{spec_map.get_package_spec({
|
||||
{{"Source", "b"}, {"Version", "1.3"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "2"}, {"Description", "the first feature for a"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}},
|
||||
})};
|
||||
|
||||
auto install_plan = Dependencies::create_feature_install_plan(
|
||||
@ -434,7 +434,7 @@ namespace UnitTest1
|
||||
{"1"}};
|
||||
|
||||
auto install_plan = Dependencies::create_feature_install_plan(
|
||||
spec_map.map, {spec_b, spec_x}, StatusParagraphs(std::move(status_paragraphs)));
|
||||
spec_map.map, {spec_b}, StatusParagraphs(std::move(status_paragraphs)));
|
||||
|
||||
Assert::AreEqual(size_t(5), install_plan.size());
|
||||
remove_plan_check(&install_plan[0], "x");
|
||||
@ -523,5 +523,45 @@ namespace UnitTest1
|
||||
features_check(&install_plan[6], "a", {"one", "core"});
|
||||
features_check(&install_plan[7], "c", {"core"});
|
||||
}
|
||||
|
||||
TEST_METHOD(default_features_test)
|
||||
{
|
||||
using Pgh = std::unordered_map<std::string, std::string>;
|
||||
|
||||
std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
|
||||
|
||||
PackageSpecMap spec_map(Triplet::X86_WINDOWS);
|
||||
|
||||
auto spec_a = FullPackageSpec{
|
||||
spec_map.get_package_spec(
|
||||
{{{"Source", "a"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for a"}, {"Build-Depends", "b[2]"}},
|
||||
{{"Feature", "2"}, {"Description", "the second feature for a"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "3"}, {"Description", "the third feature for a"}, {"Build-Depends", ""}}}),
|
||||
{""}};
|
||||
auto spec_b = FullPackageSpec{
|
||||
spec_map.get_package_spec({
|
||||
{{"Source", "b"}, {"Version", "1.3"}, {"Default-Features", "1, 2"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for b"}, {"Build-Depends", "c[1]"}},
|
||||
{{"Feature", "2"}, {"Description", "the second feature for b"}, {"Build-Depends", ""}},
|
||||
}),
|
||||
{""}};
|
||||
|
||||
auto spec_c = FullPackageSpec{
|
||||
spec_map.get_package_spec({
|
||||
{{"Source", "c"}, {"Version", "1.3"}, {"Default-Features", "2"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "1"}, {"Description", "the first feature for c"}, {"Build-Depends", ""}},
|
||||
{{"Feature", "2"}, {"Description", "the second feature for c"}, {"Build-Depends", ""}},
|
||||
}),
|
||||
{""}};
|
||||
|
||||
auto install_plan = Dependencies::create_feature_install_plan(
|
||||
spec_map.map, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
|
||||
|
||||
Assert::AreEqual(size_t(3), install_plan.size());
|
||||
features_check(&install_plan[0], "c", {"core", "1", "2"});
|
||||
features_check(&install_plan[1], "b", {"core", "1", "2"});
|
||||
features_check(&install_plan[2], "a", {"core", "1", "2"});
|
||||
}
|
||||
};
|
||||
}
|
@ -17,7 +17,7 @@ namespace UnitTest1
|
||||
{
|
||||
auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)"));
|
||||
Assert::AreEqual(size_t(1), v.size());
|
||||
Assert::AreEqual("libA", v[0].name.c_str());
|
||||
Assert::AreEqual("libA", v[0].depend.name.c_str());
|
||||
Assert::AreEqual("windows", v[0].qualifier.c_str());
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace UnitTest1
|
||||
Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str());
|
||||
Assert::AreEqual("d", pgh->core_paragraph->description.c_str());
|
||||
Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str());
|
||||
Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size());
|
||||
Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str());
|
||||
}
|
||||
@ -77,8 +77,8 @@ namespace UnitTest1
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Three_Depends)
|
||||
@ -93,9 +93,9 @@ namespace UnitTest1
|
||||
auto& pgh = *m_pgh.get();
|
||||
|
||||
Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name.c_str());
|
||||
Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name.c_str());
|
||||
Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str());
|
||||
Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str());
|
||||
Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str());
|
||||
}
|
||||
|
||||
TEST_METHOD(SourceParagraph_Three_Supports)
|
||||
@ -131,9 +131,9 @@ namespace UnitTest1
|
||||
Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str());
|
||||
Assert::AreEqual("", pgh->core_paragraph->description.c_str());
|
||||
Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size());
|
||||
Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name.c_str());
|
||||
Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str());
|
||||
Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str());
|
||||
Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name.c_str());
|
||||
Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str());
|
||||
Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str());
|
||||
}
|
||||
|
||||
@ -411,6 +411,18 @@ namespace UnitTest1
|
||||
Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec);
|
||||
}
|
||||
|
||||
TEST_METHOD(package_spec_feature_parse_with_arch)
|
||||
{
|
||||
vcpkg::ExpectedT<vcpkg::FullPackageSpec, vcpkg::PackageSpecParseResult> spec =
|
||||
vcpkg::FullPackageSpec::from_string("zlib[feature]:x64-uwp", vcpkg::Triplet::X86_WINDOWS);
|
||||
Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, spec.error());
|
||||
Assert::AreEqual("zlib", spec.get()->package_spec.name().c_str());
|
||||
Assert::IsTrue(spec.get()->features.size() == 1);
|
||||
Assert::AreEqual("feature", spec.get()->features.front().c_str());
|
||||
Assert::AreEqual(vcpkg::Triplet::X64_UWP.canonical_name(),
|
||||
spec.get()->package_spec.triplet().canonical_name());
|
||||
}
|
||||
|
||||
TEST_METHOD(utf8_to_utf16)
|
||||
{
|
||||
auto str = vcpkg::Strings::to_utf16("abc");
|
||||
|
@ -88,29 +88,37 @@ namespace vcpkg::Build
|
||||
return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull);
|
||||
}
|
||||
|
||||
static void create_binary_control_file(const VcpkgPaths& paths,
|
||||
const SourceParagraph& source_paragraph,
|
||||
static void create_binary_feature_control_file(const SourceParagraph& source_paragraph,
|
||||
const FeatureParagraph& feature_paragraph,
|
||||
const Triplet& triplet,
|
||||
const BuildInfo& build_info)
|
||||
BinaryControlFile& bcf)
|
||||
{
|
||||
BinaryParagraph bpgh = BinaryParagraph(source_paragraph, triplet);
|
||||
BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet);
|
||||
bcf.features.emplace_back(std::move(bpgh));
|
||||
}
|
||||
|
||||
static void create_binary_control_file(const SourceParagraph& source_paragraph,
|
||||
const Triplet& triplet,
|
||||
const BuildInfo& build_info,
|
||||
BinaryControlFile& bcf)
|
||||
{
|
||||
BinaryParagraph bpgh(source_paragraph, triplet);
|
||||
if (auto p_ver = build_info.version.get())
|
||||
{
|
||||
bpgh.version = *p_ver;
|
||||
}
|
||||
const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL";
|
||||
paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh));
|
||||
bcf.core_paragraph = std::move(bpgh);
|
||||
}
|
||||
|
||||
static void create_binary_feature_control_file(const VcpkgPaths& paths,
|
||||
const SourceParagraph& source_paragraph,
|
||||
const FeatureParagraph& feature_paragraph,
|
||||
const Triplet& triplet,
|
||||
const BuildInfo& build_info)
|
||||
static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf)
|
||||
{
|
||||
BinaryParagraph bpgh = BinaryParagraph(source_paragraph, feature_paragraph, triplet);
|
||||
const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL";
|
||||
paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh));
|
||||
std::string start = Strings::serialize(bcf.core_paragraph);
|
||||
for (auto&& feature : bcf.features)
|
||||
{
|
||||
start += "\n" + Strings::serialize(feature);
|
||||
}
|
||||
const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL";
|
||||
paths.get_filesystem().write_contents(binary_control_file, start);
|
||||
}
|
||||
|
||||
ExtendedBuildResult build_package(const VcpkgPaths& paths,
|
||||
@ -196,6 +204,10 @@ namespace vcpkg::Build
|
||||
auto build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec));
|
||||
const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
|
||||
|
||||
BinaryControlFile bcf;
|
||||
|
||||
create_binary_control_file(config.src, triplet, build_info, bcf);
|
||||
|
||||
if (error_count != 0)
|
||||
{
|
||||
return {BuildResult::POST_BUILD_CHECKS_FAILED, {}};
|
||||
@ -209,13 +221,13 @@ namespace vcpkg::Build
|
||||
for (auto&& f_pgh : config.scf->feature_paragraphs)
|
||||
{
|
||||
if (f_pgh->name == feature)
|
||||
create_binary_feature_control_file(
|
||||
paths, *config.scf->core_paragraph, *f_pgh, triplet, build_info);
|
||||
create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
create_binary_control_file(paths, config.src, triplet, build_info);
|
||||
|
||||
write_binary_control_file(paths, bcf);
|
||||
|
||||
// const fs::path port_buildtrees_dir = paths.buildtrees / spec.name;
|
||||
// delete_directory(port_buildtrees_dir);
|
||||
|
@ -101,6 +101,25 @@ namespace vcpkg::Dependencies
|
||||
this->plan_type = InstallPlanType::UNKNOWN;
|
||||
}
|
||||
|
||||
std::string InstallPlanAction::displayname() const
|
||||
{
|
||||
if (this->feature_list.empty())
|
||||
{
|
||||
return this->spec.to_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string features;
|
||||
for (auto&& feature : this->feature_list)
|
||||
{
|
||||
features += feature + ",";
|
||||
}
|
||||
features.pop_back();
|
||||
|
||||
return this->spec.name() + "[" + features + "]:" + this->spec.triplet().to_string();
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right)
|
||||
{
|
||||
return left->spec.name() < right->spec.name();
|
||||
@ -319,9 +338,9 @@ namespace vcpkg::Dependencies
|
||||
? RequestType::USER_REQUESTED
|
||||
: RequestType::AUTO_SELECTED;
|
||||
|
||||
Expected<BinaryParagraph> maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec);
|
||||
if (auto bpgh = maybe_bpgh.get())
|
||||
return ExportPlanAction{spec, {nullopt, *bpgh, nullopt}, request_type};
|
||||
Expected<BinaryControlFile> maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec);
|
||||
if (auto bcf = maybe_bpgh.get())
|
||||
return ExportPlanAction{spec, {nullopt, bcf->core_paragraph, nullopt}, request_type};
|
||||
|
||||
auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto scf = maybe_scf.get())
|
||||
@ -366,6 +385,20 @@ namespace vcpkg::Dependencies
|
||||
return f_specs;
|
||||
}
|
||||
|
||||
void mark_plus_default(Cluster& cluster,
|
||||
std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster,
|
||||
GraphPlan& graph_plan)
|
||||
{
|
||||
mark_plus("core", cluster, pkg_to_cluster, graph_plan);
|
||||
if (auto scf = cluster.source_control_file.get())
|
||||
{
|
||||
for (auto&& default_feature : (*scf)->core_paragraph->default_features)
|
||||
{
|
||||
mark_plus(default_feature, cluster, pkg_to_cluster, graph_plan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool mark_plus(const std::string& feature,
|
||||
Cluster& cluster,
|
||||
std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster,
|
||||
@ -404,21 +437,12 @@ namespace vcpkg::Dependencies
|
||||
graph_plan.install_graph.add_vertex({&cluster});
|
||||
auto& tracked = cluster.to_install_features;
|
||||
tracked.insert(updated_feature);
|
||||
if (tracked.find("core") == tracked.end() && tracked.find("") == tracked.end())
|
||||
{
|
||||
cluster.to_install_features.insert("core");
|
||||
for (auto&& depend : cluster.edges["core"].build_edges)
|
||||
{
|
||||
auto& depend_cluster = pkg_to_cluster[depend.spec];
|
||||
mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan);
|
||||
graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster});
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& depend : cluster.edges[updated_feature].build_edges)
|
||||
{
|
||||
auto& depend_cluster = pkg_to_cluster[depend.spec];
|
||||
mark_plus(depend.feature_name, depend_cluster, pkg_to_cluster, graph_plan);
|
||||
mark_plus_default(depend_cluster, pkg_to_cluster, graph_plan);
|
||||
if (&depend_cluster == &cluster) continue;
|
||||
graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster});
|
||||
}
|
||||
@ -448,6 +472,7 @@ namespace vcpkg::Dependencies
|
||||
mark_plus(original_feature, cluster, pkg_to_cluster, graph_plan);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<PackageSpec, SourceControlFile>& map,
|
||||
const std::vector<FullPackageSpec>& specs,
|
||||
const StatusParagraphs& status_db)
|
||||
@ -515,6 +540,7 @@ namespace vcpkg::Dependencies
|
||||
for (auto&& spec : specs)
|
||||
{
|
||||
Cluster& spec_cluster = pkg_spec_to_package_node[spec.package_spec];
|
||||
mark_plus_default(spec_cluster, pkg_spec_to_package_node, graph_plan);
|
||||
for (auto&& feature : spec.features)
|
||||
{
|
||||
mark_plus(feature, spec_cluster, pkg_spec_to_package_node, graph_plan);
|
||||
|
@ -191,7 +191,7 @@ namespace vcpkg
|
||||
|
||||
for (const std::unique_ptr<StatusParagraph>& pgh : status_db)
|
||||
{
|
||||
if (pgh->state != InstallState::INSTALLED)
|
||||
if (pgh->state != InstallState::INSTALLED || pgh->package.feature != "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user