diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2016-11-15 11:56:46 -0800 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2016-11-15 11:58:13 -0800 |
| commit | 2584f3e3def7f09bc373117985013ac019aa76d6 (patch) | |
| tree | 6ef2e0b666bd7917b644d420abdad77e6c667d6f /toolsrc/src/commands_installation.cpp | |
| parent | a72be4b6b9b63a7a11f507782c1c26fdd2b18ad0 (diff) | |
| download | vcpkg-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.cpp | 100 |
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); } |
