Esempio n. 1
0
    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;
    }
Esempio n. 2
0
    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();
    }
Esempio n. 3
0
    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);
    }
Esempio n. 4
0
    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;
    }
Esempio n. 5
0
    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);
    }
Esempio n. 6
0
    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);
    }
Esempio n. 7
0
    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;
    }