aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/commands_installation.cpp
diff options
context:
space:
mode:
authorAlexander Karatarakis <alkarata@microsoft.com>2016-11-15 11:56:46 -0800
committerAlexander Karatarakis <alkarata@microsoft.com>2016-11-15 11:58:13 -0800
commit2584f3e3def7f09bc373117985013ac019aa76d6 (patch)
tree6ef2e0b666bd7917b644d420abdad77e6c667d6f /toolsrc/src/commands_installation.cpp
parenta72be4b6b9b63a7a11f507782c1c26fdd2b18ad0 (diff)
downloadvcpkg-2584f3e3def7f09bc373117985013ac019aa76d6.tar.gz
vcpkg-2584f3e3def7f09bc373117985013ac019aa76d6.zip
Major refactor/rework of dependency resolution
Diffstat (limited to 'toolsrc/src/commands_installation.cpp')
-rw-r--r--toolsrc/src/commands_installation.cpp100
1 files changed, 53 insertions, 47 deletions
diff --git a/toolsrc/src/commands_installation.cpp b/toolsrc/src/commands_installation.cpp
index 460fa1818..b900b56c8 100644
--- a/toolsrc/src/commands_installation.cpp
+++ b/toolsrc/src/commands_installation.cpp
@@ -9,7 +9,6 @@
#include "vcpkg_Dependencies.h"
#include "vcpkg_Input.h"
#include "vcpkg_Maps.h"
-#include "Paragraphs.h"
#include "vcpkg_info.h"
namespace vcpkg
@@ -21,17 +20,15 @@ namespace vcpkg
std::ofstream(binary_control_file) << bpgh;
}
- static void build_internal(const package_spec& spec, const vcpkg_paths& paths, const fs::path& port_dir)
+ static void build_internal(const SourceParagraph& source_paragraph, const package_spec& spec, const vcpkg_paths& paths, const fs::path& port_dir)
{
- auto pghs = Paragraphs::get_paragraphs(port_dir / "CONTROL");
- Checks::check_exit(pghs.size() == 1, "Error: invalid control file");
- SourceParagraph source_paragraph(pghs[0]);
+ Checks::check_exit(spec.name() == source_paragraph.name, "inconsistent arguments to build_internal()");
+ auto&& target_triplet = spec.target_triplet();
const fs::path ports_cmake_script_path = paths.ports_cmake;
- auto&& target_triplet = spec.target_triplet();
const std::wstring command = Strings::wformat(LR"("%%VS140COMNTOOLS%%..\..\VC\vcvarsall.bat" %s && cmake -DCMD=BUILD -DPORT=%s -DTARGET_TRIPLET=%s "-DCURRENT_PORT_DIR=%s/." -P "%s")",
Strings::utf8_to_utf16(target_triplet.architecture()),
- Strings::utf8_to_utf16(spec.name()),
+ Strings::utf8_to_utf16(source_paragraph.name),
Strings::utf8_to_utf16(target_triplet.canonical_name()),
port_dir.generic_wstring(),
ports_cmake_script_path.generic_wstring());
@@ -65,11 +62,6 @@ namespace vcpkg
// delete_directory(port_buildtrees_dir);
}
- static void build_internal(const package_spec& spec, const vcpkg_paths& paths)
- {
- return build_internal(spec, paths, paths.ports / spec.name());
- }
-
void install_command(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet)
{
static const std::string example = create_example_string("install zlib zlib:x64-windows curl boost");
@@ -78,49 +70,47 @@ namespace vcpkg
std::vector<package_spec> specs = Input::check_and_get_package_specs(args.command_arguments, default_target_triplet, example.c_str());
Input::check_triplets(specs, paths);
- std::vector<package_spec> install_plan = Dependencies::create_dependency_ordered_install_plan(paths, specs, status_db);
+ auto install_plan = Dependencies::create_install_plan(paths, specs, status_db);
Checks::check_exit(!install_plan.empty(), "Install plan cannot be empty");
- std::string specs_string = to_string(install_plan[0]);
+
+ std::string specs_string = to_string(install_plan[0].first);
for (size_t i = 1; i < install_plan.size(); ++i)
{
specs_string.push_back(',');
- specs_string.append(to_string(install_plan[i]));
+ specs_string.append(to_string(install_plan[i].first));
}
TrackProperty("installplan", specs_string);
Environment::ensure_utilities_on_path(paths);
- for (const package_spec& spec : install_plan)
+ for (const auto& action : install_plan)
{
- if (status_db.find_installed(spec.name(), spec.target_triplet()) != status_db.end())
- {
- System::println(System::color::success, "Package %s is already installed", spec);
- continue;
- }
-
- fs::path package_path = paths.package_dir(spec);
-
- expected<std::string> file_contents = Files::get_contents(package_path / "CONTROL");
-
try
{
- if (file_contents.error_code())
+ if (action.second.plan == Dependencies::install_plan_kind::ALREADY_INSTALLED)
{
- build_internal(spec, paths);
- file_contents = Files::get_contents(package_path / "CONTROL");
- if (file_contents.error_code())
+ if (std::find(specs.begin(), specs.end(), action.first) != specs.end())
{
- file_contents.get_or_throw();
+ System::println(System::color::success, "Package %s is already installed", action.first);
}
}
-
- auto pghs = Paragraphs::parse_paragraphs(file_contents.get_or_throw());
- Checks::check_throw(pghs.size() == 1, "multiple paragraphs in control file");
- install_package(paths, BinaryParagraph(pghs[0]), status_db);
- System::println(System::color::success, "Package %s is installed", spec);
+ else if (action.second.plan == Dependencies::install_plan_kind::BUILD_AND_INSTALL)
+ {
+ build_internal(*action.second.spgh, action.first, paths, paths.port_dir(action.first));
+ auto bpgh = try_load_cached_package(paths, action.first).get_or_throw();
+ install_package(paths, bpgh, status_db);
+ System::println(System::color::success, "Package %s is installed", action.first);
+ }
+ else if (action.second.plan == Dependencies::install_plan_kind::INSTALL)
+ {
+ install_package(paths, *action.second.bpgh, status_db);
+ System::println(System::color::success, "Package %s is installed", action.first);
+ }
+ else
+ Checks::unreachable();
}
catch (const std::exception& e)
{
- System::println(System::color::error, "Error: Could not install package %s: %s", spec, e.what());
+ System::println(System::color::error, "Error: Could not install package %s: %s", action.first, e.what());
exit(EXIT_FAILURE);
}
}
@@ -142,29 +132,41 @@ namespace vcpkg
Input::check_triplet(spec.target_triplet(), paths);
// Explicitly load and use the portfile's build dependencies when resolving the build command (instead of a cached package's dependencies).
- auto first_level_deps = Dependencies::get_unmet_package_build_dependencies(paths, spec);
+ auto maybe_spgh = try_load_port(paths, spec.name());
+ Checks::check_exit(!maybe_spgh.error_code(), "Could not find package named %s: %s", spec, maybe_spgh.error_code().message());
+ auto& spgh = *maybe_spgh.get();
+
+ auto first_level_deps = filter_dependencies(spgh.depends, spec.target_triplet());
+
std::vector<package_spec> first_level_deps_specs;
for (auto&& dep : first_level_deps)
{
first_level_deps_specs.push_back(package_spec::from_name_and_triplet(dep, spec.target_triplet()).get_or_throw());
}
- std::unordered_set<package_spec> unmet_dependencies = Dependencies::get_unmet_dependencies(paths, first_level_deps_specs, status_db);
+ auto unmet_dependencies = Dependencies::create_install_plan(paths, first_level_deps_specs, status_db);
+ unmet_dependencies.erase(
+ std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [](auto& p)
+ {
+ return p.second.plan == Dependencies::install_plan_kind::ALREADY_INSTALLED;
+ }),
+ unmet_dependencies.end());
+
if (!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 package_spec& p : unmet_dependencies)
+ for (const auto& p : unmet_dependencies)
{
- System::println(" %s", to_string(p));
+ System::println(" %s", to_string(p.first));
}
System::println("");
exit(EXIT_FAILURE);
}
Environment::ensure_utilities_on_path(paths);
- build_internal(spec, paths);
+ build_internal(spgh, spec, paths, paths.port_dir(spec));
exit(EXIT_SUCCESS);
}
@@ -173,17 +175,21 @@ namespace vcpkg
static const std::string example = create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)");
args.check_exact_arg_count(2, example.c_str());
- expected<package_spec> current_spec = package_spec::from_string(args.command_arguments[0], default_target_triplet);
- if (auto spec = current_spec.get())
+ expected<package_spec> maybe_current_spec = package_spec::from_string(args.command_arguments[0], default_target_triplet);
+ if (auto spec = maybe_current_spec.get())
{
Input::check_triplet(spec->target_triplet(), paths);
Environment::ensure_utilities_on_path(paths);
const fs::path port_dir = args.command_arguments.at(1);
- build_internal(*spec, paths, port_dir);
- exit(EXIT_SUCCESS);
+ auto maybe_spgh = try_load_port(port_dir);
+ if (auto spgh = maybe_spgh.get())
+ {
+ build_internal(*spgh, *spec, paths, port_dir);
+ exit(EXIT_SUCCESS);
+ }
}
- System::println(System::color::error, "Error: %s: %s", current_spec.error_code().message(), args.command_arguments[0]);
+ System::println(System::color::error, "Error: %s: %s", maybe_current_spec.error_code().message(), args.command_arguments[0]);
print_example(Strings::format("%s zlib:x64-windows", args.command).c_str());
exit(EXIT_FAILURE);
}