aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg/build.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'toolsrc/src/vcpkg/build.cpp')
-rw-r--r--toolsrc/src/vcpkg/build.cpp117
1 files changed, 76 insertions, 41 deletions
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index c169a778e..ff7554b78 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -66,7 +66,8 @@ namespace vcpkg::Build::Command
Build::CleanBuildtrees::NO,
Build::CleanPackages::NO};
- const std::unordered_set<std::string> features_as_set(full_spec.features.begin(), full_spec.features.end());
+ std::set<std::string> features_as_set(full_spec.features.begin(), full_spec.features.end());
+ features_as_set.emplace("core");
const Build::BuildPackageConfig build_config{
*scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set};
@@ -260,56 +261,93 @@ namespace vcpkg::Build
paths.get_filesystem().write_contents(binary_control_file, start);
}
- static ExtendedBuildResult do_build_package(const VcpkgPaths& paths,
- const BuildPackageConfig& config,
- const StatusParagraphs& status_db)
+ static std::vector<FeatureSpec> compute_required_feature_specs(const BuildPackageConfig& config,
+ const StatusParagraphs& status_db)
{
- const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet)
- .value_or_exit(VCPKG_LINE_INFO);
-
const Triplet& triplet = config.triplet;
+
+ auto dep_strings =
+ Util::fmap_flatten(config.feature_list, [&](std::string const& feature) -> std::vector<std::string> {
+ if (feature == "core")
+ {
+ return filter_dependencies(config.scf.core_paragraph->depends, triplet);
+ }
+
+ auto it =
+ Util::find_if(config.scf.feature_paragraphs,
+ [&](std::unique_ptr<FeatureParagraph> const& fpgh) { return fpgh->name == feature; });
+ Checks::check_exit(VCPKG_LINE_INFO, it != config.scf.feature_paragraphs.end());
+
+ return filter_dependencies(it->get()->depends, triplet);
+ });
+
+ auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet);
+ Util::sort_unique_erase(dep_fspecs);
+
+ // expand defaults
+ std::vector<FeatureSpec> ret;
+ for (auto&& fspec : dep_fspecs)
{
- std::vector<FeatureSpec> missing_specs;
- for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet))
+ if (fspec.feature().empty())
{
- auto dep_specs = FeatureSpec::from_strings_and_triplet({dep}, triplet);
- for (auto&& feature : dep_specs)
+ // reference to default features
+ auto it = status_db.find_installed(fspec.spec());
+ if (it == status_db.end())
+ {
+ // not currently installed, so just leave the default reference so it will fail later
+ ret.push_back(fspec);
+ }
+ else
{
- if (!status_db.is_installed(feature))
- {
- missing_specs.push_back(std::move(feature));
- }
+ ret.push_back(FeatureSpec{fspec.spec(), "core"});
+ for (auto&& default_feature : it->get()->package.default_features)
+ ret.push_back(FeatureSpec{fspec.spec(), default_feature});
}
}
- // Fail the build if any dependencies were missing
- if (!missing_specs.empty())
+ else
{
- return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)};
+ ret.push_back(fspec);
}
}
+ Util::sort_unique_erase(ret);
+
+ return ret;
+ }
+
+ static ExtendedBuildResult do_build_package(const VcpkgPaths& paths,
+ const BuildPackageConfig& config,
+ const StatusParagraphs& status_db)
+ {
+ auto& fs = paths.get_filesystem();
+ const Triplet& triplet = config.triplet;
+
+ const PackageSpec spec =
+ PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO);
+
+ std::vector<FeatureSpec> required_fspecs = compute_required_feature_specs(config, status_db);
+
+ // Find all features that aren't installed. This destroys required_fspecs.
+ Util::unstable_keep_if(required_fspecs,
+ [&](FeatureSpec const& fspec) { return !status_db.is_installed(fspec); });
+
+ if (!required_fspecs.empty())
+ {
+ return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)};
+ }
const fs::path& cmake_exe_path = paths.get_cmake_exe();
const fs::path& git_exe_path = paths.get_git_exe();
const fs::path ports_cmake_script_path = paths.ports_cmake;
+
const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet);
- std::string features;
+ std::string features = Strings::join(";", config.feature_list);
+
std::string all_features;
- if (GlobalState::feature_packages)
+ for (auto& feature : config.scf.feature_paragraphs)
{
- for (auto&& feature : config.feature_list)
- {
- features.append(feature + ";");
- }
- if (!features.empty())
- {
- features.pop_back();
- }
- for (auto& feature : config.scf.feature_paragraphs)
- {
- all_features.append(feature->name + ";");
- }
+ all_features.append(feature->name + ";");
}
const Toolset& toolset = paths.get_toolset(pre_build_info);
@@ -351,7 +389,7 @@ namespace vcpkg::Build
}
}
- const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec));
+ const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec));
const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info);
@@ -360,16 +398,13 @@ namespace vcpkg::Build
{
return BuildResult::POST_BUILD_CHECKS_FAILED;
}
- if (GlobalState::feature_packages)
+ for (auto&& feature : config.feature_list)
{
- for (auto&& feature : config.feature_list)
+ for (auto&& f_pgh : config.scf.feature_paragraphs)
{
- for (auto&& f_pgh : config.scf.feature_paragraphs)
- {
- if (f_pgh->name == feature)
- bcf->features.push_back(
- create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet));
- }
+ if (f_pgh->name == feature)
+ bcf->features.push_back(
+ create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet));
}
}