[vcpkg-build] Fix regression in build command.

Missing dependencies were not being computed correctly after the internal call to build failed. Solution is to return the already-computed list from build.
This commit is contained in:
Robert Schumacher 2017-04-23 01:30:43 -07:00
parent e48fdb66a5
commit ee0201cfae
4 changed files with 55 additions and 30 deletions

View File

@ -31,8 +31,25 @@ namespace vcpkg::Commands
std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset);
BuildResult build_package(const SourceParagraph& source_paragraph, const PackageSpec& spec, const VcpkgPaths& paths, const fs::path& port_dir, const StatusParagraphs& status_db);
void perform_and_exit(const PackageSpec& spec, const fs::path& port_dir, const std::unordered_set<std::string>& options, const VcpkgPaths& paths);
struct ExtendedBuildResult
{
BuildResult code;
std::vector<PackageSpec> unmet_dependencies;
};
ExtendedBuildResult build_package(
const SourceParagraph& source_paragraph,
const PackageSpec& spec,
const VcpkgPaths& paths,
const fs::path& port_dir,
const StatusParagraphs& status_db);
void perform_and_exit(
const PackageSpec& spec,
const fs::path& port_dir,
const std::unordered_set<std::string>& options,
const VcpkgPaths& paths);
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}

View File

@ -37,16 +37,29 @@ namespace vcpkg::Commands::Build
return Strings::wformat(LR"("%s" %s %s 2>&1)", toolset.vcvarsall.native(), Strings::utf8_to_utf16(triplet.architecture()), tonull);
}
BuildResult build_package(const SourceParagraph& source_paragraph, const PackageSpec& spec, const VcpkgPaths& paths, const fs::path& port_dir, const StatusParagraphs& status_db)
ExtendedBuildResult build_package(
const SourceParagraph& source_paragraph,
const PackageSpec& spec,
const VcpkgPaths& paths,
const fs::path& port_dir,
const StatusParagraphs& status_db)
{
Checks::check_exit(VCPKG_LINE_INFO, spec.name() == source_paragraph.name, "inconsistent arguments to build_package()");
const Triplet& triplet = spec.triplet();
for (auto&& dep : filter_dependencies(source_paragraph.depends, triplet))
{
if (status_db.find_installed(dep, triplet) == status_db.end())
std::vector<PackageSpec> missing_specs;
for (auto&& dep : filter_dependencies(source_paragraph.depends, triplet))
{
return BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES;
if (status_db.find_installed(dep, triplet) == status_db.end())
{
missing_specs.push_back(PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO));
}
}
// Fail the build if any dependencies were missing
if (!missing_specs.empty())
{
return { BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs) };
}
}
@ -79,14 +92,14 @@ namespace vcpkg::Commands::Build
{
Metrics::track_property("error", "build failed");
Metrics::track_property("build_error", spec.to_string());
return BuildResult::BUILD_FAILED;
return { BuildResult::BUILD_FAILED, {} };
}
const size_t error_count = PostBuildLint::perform_all_checks(spec, paths);
if (error_count != 0)
{
return BuildResult::POST_BUILD_CHECKS_FAILED;
return { BuildResult::POST_BUILD_CHECKS_FAILED, {} };
}
create_binary_control_file(paths, source_paragraph, triplet);
@ -94,7 +107,7 @@ namespace vcpkg::Commands::Build
// const fs::path port_buildtrees_dir = paths.buildtrees / spec.name;
// delete_directory(port_buildtrees_dir);
return BuildResult::SUCCEEDED;
return { BuildResult::SUCCEEDED, {} };
}
const std::string& to_string(const BuildResult build_result)
@ -146,30 +159,23 @@ namespace vcpkg::Commands::Build
const SourceParagraph& spgh = *maybe_spgh.get();
StatusParagraphs status_db = database_load_check(paths);
const BuildResult result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db);
if (result == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
const auto result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db);
if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
{
std::vector<InstallPlanAction> unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db);
Util::erase_remove_if(unmet_dependencies, [&spec](const InstallPlanAction& p)
{
return (p.spec == spec) || (p.plan_type == InstallPlanType::ALREADY_INSTALLED);
});
Checks::check_exit(VCPKG_LINE_INFO, !unmet_dependencies.empty());
System::println(System::Color::error, "The build command requires all dependencies to be already installed.");
System::println("The following dependencies are missing:");
System::println("");
for (const InstallPlanAction& p : unmet_dependencies)
for (const auto& p : result.unmet_dependencies)
{
System::println(" %s", p.spec);
System::println(" %s", p);
}
System::println("");
Checks::exit_fail(VCPKG_LINE_INFO);
}
if (result != BuildResult::SUCCEEDED)
if (result.code != BuildResult::SUCCEEDED)
{
System::println(System::Color::error, Build::create_error_message(result, spec));
System::println(System::Color::error, Build::create_error_message(result.code, spec));
System::println(Build::create_user_troubleshooting_message(spec));
Checks::exit_fail(VCPKG_LINE_INFO);
}

View File

@ -66,11 +66,13 @@ namespace vcpkg::Commands::CI
{
System::println("Building package %s... ", display_name);
auto&& source_paragraph = action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO);
const BuildResult result = Commands::Build::build_package(source_paragraph,
action.spec,
paths,
paths.port_dir(action.spec),
status_db);
const auto result_ex = Commands::Build::build_package(source_paragraph,
action.spec,
paths,
paths.port_dir(action.spec),
status_db);
const auto result = result_ex.code;
timing.back() = build_timer.to_string();
results.back() = result;
if (result != BuildResult::SUCCEEDED)

View File

@ -317,15 +317,15 @@ namespace vcpkg::Commands::Install
case InstallPlanType::BUILD_AND_INSTALL:
{
System::println("Building package %s... ", display_name);
const Build::BuildResult result = Commands::Build::build_package(
const auto result = Commands::Build::build_package(
action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO),
action.spec,
paths,
paths.port_dir(action.spec),
status_db);
if (result != Build::BuildResult::SUCCEEDED)
if (result.code != Build::BuildResult::SUCCEEDED)
{
System::println(System::Color::error, Build::create_error_message(result, action.spec));
System::println(System::Color::error, Build::create_error_message(result.code, action.spec));
System::println(Build::create_user_troubleshooting_message(action.spec));
Checks::exit_fail(VCPKG_LINE_INFO);
}