mirror of
https://github.com/cemu-project/vcpkg.git
synced 2025-02-23 11:07:10 +01:00
[vcpkg] Fix "just-in-time" requirements calculation
This commit is contained in:
parent
99d30fa105
commit
8b97ae2dc1
@ -127,6 +127,15 @@ namespace vcpkg::Util
|
||||
std::sort(begin(cont), end(cont));
|
||||
}
|
||||
|
||||
template<class Range>
|
||||
void sort_unique_erase(Range& cont)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
std::sort(begin(cont), end(cont));
|
||||
cont.erase(std::unique(begin(cont), end(cont)), end(cont));
|
||||
}
|
||||
|
||||
template<class Range1, class Range2>
|
||||
bool all_equal(const Range1& r1, const Range2& r2)
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg::Build
|
||||
@ -125,7 +126,7 @@ namespace vcpkg::Build
|
||||
const Triplet& triplet,
|
||||
fs::path&& port_dir,
|
||||
const BuildPackageOptions& build_package_options,
|
||||
const std::unordered_set<std::string>& feature_list)
|
||||
const std::set<std::string>& feature_list)
|
||||
: scf(src)
|
||||
, triplet(triplet)
|
||||
, port_dir(std::move(port_dir))
|
||||
@ -138,7 +139,7 @@ namespace vcpkg::Build
|
||||
const Triplet& triplet;
|
||||
fs::path port_dir;
|
||||
const BuildPackageOptions& build_package_options;
|
||||
const std::unordered_set<std::string>& feature_list;
|
||||
const std::set<std::string>& feature_list;
|
||||
};
|
||||
|
||||
ExtendedBuildResult build_package(const VcpkgPaths& paths,
|
||||
|
@ -120,6 +120,7 @@ namespace vcpkg::Commands
|
||||
namespace Hash
|
||||
{
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
|
||||
std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -39,12 +39,12 @@ namespace vcpkg::Dependencies
|
||||
|
||||
InstallPlanAction(const PackageSpec& spec,
|
||||
InstalledPackageView&& spghs,
|
||||
const std::unordered_set<std::string>& features,
|
||||
const std::set<std::string>& features,
|
||||
const RequestType& request_type);
|
||||
|
||||
InstallPlanAction(const PackageSpec& spec,
|
||||
const SourceControlFile& scf,
|
||||
const std::unordered_set<std::string>& features,
|
||||
const std::set<std::string>& features,
|
||||
const RequestType& request_type);
|
||||
|
||||
std::string displayname() const;
|
||||
@ -57,7 +57,7 @@ namespace vcpkg::Dependencies
|
||||
InstallPlanType plan_type;
|
||||
RequestType request_type;
|
||||
Build::BuildPackageOptions build_options;
|
||||
std::unordered_set<std::string> feature_list;
|
||||
std::set<std::string> feature_list;
|
||||
};
|
||||
|
||||
enum class RemovePlanType
|
||||
|
@ -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 std::vector<FeatureSpec> compute_required_feature_specs(const BuildPackageConfig& config,
|
||||
const StatusParagraphs& status_db)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (fspec.feature().empty())
|
||||
{
|
||||
// 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
|
||||
{
|
||||
ret.push_back(FeatureSpec{fspec.spec(), "core"});
|
||||
for (auto&& default_feature : it->get()->package.default_features)
|
||||
ret.push_back(FeatureSpec{fspec.spec(), default_feature});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
const PackageSpec spec = PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, config.triplet)
|
||||
.value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
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())
|
||||
{
|
||||
std::vector<FeatureSpec> missing_specs;
|
||||
for (auto&& dep : filter_dependencies(config.scf.core_paragraph->depends, triplet))
|
||||
{
|
||||
auto dep_specs = FeatureSpec::from_strings_and_triplet({dep}, triplet);
|
||||
for (auto&& feature : dep_specs)
|
||||
{
|
||||
if (!status_db.is_installed(feature))
|
||||
{
|
||||
missing_specs.push_back(std::move(feature));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fail the build if any dependencies were missing
|
||||
if (!missing_specs.empty())
|
||||
{
|
||||
return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)};
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace vcpkg::Commands::Hash
|
||||
{
|
||||
static void do_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type)
|
||||
std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type)
|
||||
{
|
||||
const std::string cmd_line = Strings::format(
|
||||
R"("%s" -E %ssum %s)", cmake_exe_path.u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string());
|
||||
@ -27,7 +27,7 @@ namespace vcpkg::Commands::Hash
|
||||
|
||||
auto hash = output.substr(0, start);
|
||||
Util::erase_remove_if(hash, isspace);
|
||||
System::println(hash);
|
||||
return hash;
|
||||
}
|
||||
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
@ -45,11 +45,13 @@ namespace vcpkg::Commands::Hash
|
||||
|
||||
if (args.command_arguments.size() == 1)
|
||||
{
|
||||
do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512");
|
||||
auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512");
|
||||
System::println(hash);
|
||||
}
|
||||
if (args.command_arguments.size() == 2)
|
||||
{
|
||||
do_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]);
|
||||
auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]);
|
||||
System::println(hash);
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
|
@ -30,8 +30,8 @@ namespace vcpkg::Dependencies
|
||||
Optional<const SourceControlFile*> source_control_file;
|
||||
PackageSpec spec;
|
||||
std::unordered_map<std::string, FeatureNodeEdges> edges;
|
||||
std::unordered_set<std::string> to_install_features;
|
||||
std::unordered_set<std::string> original_features;
|
||||
std::set<std::string> to_install_features;
|
||||
std::set<std::string> original_features;
|
||||
bool will_remove = false;
|
||||
bool transient_uninstalled = true;
|
||||
RequestType request_type = RequestType::AUTO_SELECTED;
|
||||
@ -143,7 +143,7 @@ namespace vcpkg::Dependencies
|
||||
|
||||
InstallPlanAction::InstallPlanAction(const PackageSpec& spec,
|
||||
const SourceControlFile& scf,
|
||||
const std::unordered_set<std::string>& features,
|
||||
const std::set<std::string>& features,
|
||||
const RequestType& request_type)
|
||||
: spec(spec)
|
||||
, source_control_file(scf)
|
||||
@ -155,7 +155,7 @@ namespace vcpkg::Dependencies
|
||||
|
||||
InstallPlanAction::InstallPlanAction(const PackageSpec& spec,
|
||||
InstalledPackageView&& ipv,
|
||||
const std::unordered_set<std::string>& features,
|
||||
const std::set<std::string>& features,
|
||||
const RequestType& request_type)
|
||||
: spec(spec)
|
||||
, installed_package(std::move(ipv))
|
||||
|
@ -54,6 +54,11 @@ namespace vcpkg
|
||||
const Triplet& triplet,
|
||||
const std::string& feature)
|
||||
{
|
||||
if (feature == "core")
|
||||
{
|
||||
// The core feature maps to .feature == ""
|
||||
return find(name, triplet, "");
|
||||
}
|
||||
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;
|
||||
@ -64,6 +69,11 @@ namespace vcpkg
|
||||
const Triplet& triplet,
|
||||
const std::string& feature) const
|
||||
{
|
||||
if (feature == "core")
|
||||
{
|
||||
// The core feature maps to .feature == ""
|
||||
return find(name, triplet, "");
|
||||
}
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user