std::vector<StatusParagraphAndAssociatedFiles> get_installed_files(const VcpkgPaths& paths, const StatusParagraphs& status_db) { auto& fs = paths.get_filesystem(); std::vector<StatusParagraphAndAssociatedFiles> installed_files; for (const std::unique_ptr<StatusParagraph>& pgh : status_db) { if (pgh->state != InstallState::INSTALLED) { continue; } const fs::path listfile_path = paths.listfile_path(pgh->package); std::vector<std::string> installed_files_of_current_pgh = fs.read_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO); Strings::trim_all_and_remove_whitespace_strings(&installed_files_of_current_pgh); upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path); // Remove the directories Util::erase_remove_if(installed_files_of_current_pgh, [](const std::string& file) { return file.back() == '/'; }); StatusParagraphAndAssociatedFiles pgh_and_files = { *pgh, SortedVector<std::string>(std::move(installed_files_of_current_pgh))}; installed_files.push_back(std::move(pgh_and_files)); } return installed_files; }
Expected<BinaryParagraph> try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) { Expected<std::unordered_map<std::string, std::string>> pghs = get_single_paragraph(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); if (auto p = pghs.get()) { return BinaryParagraph(*p); } return pghs.error(); }
void write_update(const VcpkgPaths& paths, const StatusParagraph& p) { static int update_id = 0; auto& fs = paths.get_filesystem(); auto my_update_id = update_id++; auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); fs.write_contents(tmp_update_filename, Strings::serialize(p)); fs.rename(tmp_update_filename, update_filename); }
StatusParagraphs database_load_check(const VcpkgPaths& paths) { auto& fs = paths.get_filesystem(); auto updates_dir = paths.vcpkg_dir_updates; std::error_code ec; fs.create_directory(paths.installed, ec); fs.create_directory(paths.vcpkg_dir, ec); fs.create_directory(paths.vcpkg_dir_info, ec); fs.create_directory(updates_dir, ec); const fs::path& status_file = paths.vcpkg_dir_status_file; const fs::path status_file_old = status_file.parent_path() / "status-old"; const fs::path status_file_new = status_file.parent_path() / "status-new"; StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old); auto update_files = fs.get_files_non_recursive(updates_dir); if (update_files.empty()) { // updates directory is empty, control file is up-to-date. return current_status_db; } for (auto&& file : update_files) { if (!fs.is_regular_file(file)) continue; if (file.filename() == "incomplete") continue; auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); for (auto&& p : pghs) { current_status_db.insert(std::make_unique<StatusParagraph>(std::move(p))); } } fs.write_contents(status_file_new, Strings::serialize(current_status_db)); fs.rename(status_file_new, status_file); for (auto&& file : update_files) { if (!fs.is_regular_file(file)) continue; fs.remove(file); } return current_status_db; }
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); if (args.command_arguments.size() == 1) { const std::string filter = args.command_arguments.at(0); Util::erase_remove_if(source_control_files, [&](const std::unique_ptr<SourceControlFile>& source_control_file) { const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) { return false; } for (const Dependency& dependency : source_paragraph.depends) { if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) { return false; } } return true; }); } if (!options.switches.empty()) { const std::string graph_as_string = create_graph_as_string(options.switches, source_control_files); System::println(graph_as_string); Checks::exit_success(VCPKG_LINE_INFO); } for (auto&& source_control_file : source_control_files) { const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); System::println("%s: %s", source_paragraph.name, s); } Checks::exit_success(VCPKG_LINE_INFO); }
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string example = Strings::format( "The argument should be a substring to search for, or no argument to display all libraries.\n%s", Commands::Help::create_example_string("search png")); args.check_max_arg_count(1, example); const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); if (!sources_and_errors.errors.empty()) { if (vcpkg::g_debugging) { print_error_message(sources_and_errors.errors); } else { for (auto&& error : sources_and_errors.errors) { System::println( System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); } System::println(System::Color::warning, "Use '--debug' to get more information about the parse failures.\n"); } } auto& source_paragraphs = sources_and_errors.paragraphs; if (options.find(OPTION_GRAPH) != options.cend()) { const std::string graph_as_string = create_graph_as_string(source_paragraphs); System::println(graph_as_string); Checks::exit_success(VCPKG_LINE_INFO); } if (args.command_arguments.empty()) { for (const auto& source_control_file : source_paragraphs) { do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { do_print(source_control_file->core_paragraph->name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } } else { const auto& icontains = Strings::case_insensitive_ascii_contains; // At this point there is 1 argument auto&& args_zero = args.command_arguments[0]; for (const auto& source_control_file : source_paragraphs) { auto&& sp = *source_control_file->core_paragraph; bool contains_name = icontains(sp.name, args_zero); if (contains_name || icontains(sp.description, args_zero)) { do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); } for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { if (contains_name || icontains(feature_paragraph->name, args_zero) || icontains(feature_paragraph->description, args_zero)) { do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); } } } } System::println( "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" " https://github.com/Microsoft/vcpkg/issues"); Checks::exit_success(VCPKG_LINE_INFO); }
std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; const auto& fs = paths.get_filesystem(); // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. std::vector<fs::path> paths_examined; std::vector<Toolset> found_toolsets; std::vector<Toolset> excluded_toolsets; const SortedVector<VisualStudioInstance> sorted{get_visual_studio_instances_internal(paths), VisualStudioInstance::preferred_first_comparator}; const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; }) != sorted.end(); for (const VisualStudioInstance& vs_instance : sorted) { const std::string major_version = vs_instance.major_version(); if (major_version >= "15") { const fs::path vc_dir = vs_instance.root_path / "VC"; // Skip any instances that do not have vcvarsall. const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; paths_examined.push_back(vcvarsall_bat); if (!fs.exists(vcvarsall_bat)) continue; // Get all supported architectures std::vector<ToolsetArchOption> supported_architectures; if (fs.exists(vcvarsall_dir / "vcvars32.bat")) supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvars64.bat")) supported_architectures.push_back({"amd64", CPU::X64, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path); Util::erase_remove_if(msvc_subdirectories, [&fs](const fs::path& path) { return !fs.is_directory(path); }); // Sort them so that latest comes first std::sort( msvc_subdirectories.begin(), msvc_subdirectories.end(), [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); }); for (const fs::path& subdir : msvc_subdirectories) { const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { const Toolset v141_toolset{ vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; const auto english_language_pack = dumpbin_path.parent_path() / "1033"; if (!fs.exists(english_language_pack)) { excluded_toolsets.push_back(v141_toolset); break; } found_toolsets.push_back(v141_toolset); if (v140_is_available) { const Toolset v140_toolset{vs_instance.root_path, dumpbin_path, vcvarsall_bat, {"-vcvars_ver=14.0"}, V_140, supported_architectures}; found_toolsets.push_back(v140_toolset); } break; } } continue; } if (major_version == "14" || major_version == "12") { const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; paths_examined.push_back(vcvarsall_bat); if (fs.exists(vcvarsall_bat)) { const fs::path vs_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs_dumpbin_exe); const fs::path vs_bin_dir = vcvarsall_bat.parent_path() / "bin"; std::vector<ToolsetArchOption> supported_architectures; if (fs.exists(vs_bin_dir / "vcvars32.bat")) supported_architectures.push_back({"x86", CPU::X86, CPU::X86}); if (fs.exists(vs_bin_dir / "amd64\\vcvars64.bat")) supported_architectures.push_back({"x64", CPU::X64, CPU::X64}); if (fs.exists(vs_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vs_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM}); if (fs.exists(vs_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vs_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM}); if (fs.exists(vs_dumpbin_exe)) { const Toolset toolset = {vs_instance.root_path, vs_dumpbin_exe, vcvarsall_bat, {}, major_version == "14" ? V_140 : V_120, supported_architectures}; const auto english_language_pack = vs_dumpbin_exe.parent_path() / "1033"; if (!fs.exists(english_language_pack)) { excluded_toolsets.push_back(toolset); break; } found_toolsets.push_back(toolset); } } } } if (!excluded_toolsets.empty()) { System::println( System::Color::warning, "Warning: The following VS instances are excluded because the English language pack is unavailable."); for (const Toolset& toolset : excluded_toolsets) { System::println(" %s", toolset.visual_studio_root_path.u8string()); } System::println(System::Color::warning, "Please install the English language pack."); } if (found_toolsets.empty()) { System::println(System::Color::error, "Could not locate a complete toolset."); System::println("The following paths were examined:"); for (const fs::path& path : paths_examined) { System::println(" %s", path.u8string()); } Checks::exit_fail(VCPKG_LINE_INFO); } return found_toolsets; }