From e9d2a830206fac08f47e55c739a3f3fbe29855e9 Mon Sep 17 00:00:00 2001 From: "Curtis.Bezault" Date: Tue, 2 Apr 2019 10:48:37 -0700 Subject: [PATCH 1/2] Check scripts/cmake/* and buildsystems/vcpkg.cmake for changes when hashing --- toolsrc/src/vcpkg/build.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f20367e00b7..50bcacd130f 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -479,13 +479,13 @@ namespace vcpkg::Build const int max_port_file_count = 100; // the order of recursive_directory_iterator is undefined so save the names to sort - std::vector port_files; + std::vector hashed_files; for (auto &port_file : fs::stdfs::recursive_directory_iterator(config.port_dir)) { if (fs::is_regular_file(status(port_file))) { - port_files.push_back(port_file); - if (port_files.size() > max_port_file_count) + hashed_files.push_back(port_file); + if (hashed_files.size() > max_port_file_count) { abi_tag_entries.emplace_back(AbiEntry{ "no_hash_max_portfile", "" }); break; @@ -493,12 +493,20 @@ namespace vcpkg::Build } } - if (port_files.size() <= max_port_file_count) + if (hashed_files.size() <= max_port_file_count) { - std::sort(port_files.begin(), port_files.end()); + for (auto &script_file : fs::stdfs::recursive_directory_iterator(paths.scripts)) + { + if (fs::is_regular_file(status(script_file))) + { + hashed_files.push_back(script_file); + } + } + + std::sort(hashed_files.begin(), hashed_files.end()); int counter = 0; - for (auto & port_file : port_files) + for (auto & hashed_file : hashed_files) { // When vcpkg takes a dependency on C++17 it can use fs::relative, // which will give a stable ordering and better names in the key entry. @@ -506,15 +514,15 @@ namespace vcpkg::Build std::string key = Strings::format("file_%03d", counter++); if (GlobalState::debugging) { - System::println("[DEBUG] mapping %s from %s", key, port_file.string()); + System::println("[DEBUG] mapping %s from %s", key, hashed_file.string()); } - abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, port_file, "SHA1") }); + abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, hashed_file, "SHA1") }); } } abi_tag_entries.emplace_back(AbiEntry{ - "vcpkg_fixup_cmake_targets", - vcpkg::Hash::get_file_hash(fs, paths.scripts / "cmake" / "vcpkg_fixup_cmake_targets.cmake", "SHA1")}); + "vcpkg", + vcpkg::Hash::get_file_hash(fs, paths.scripts / "buildsystems" / "vcpkg.cmake", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); From 79682317c9e087dc1d1ae450e3edd03b0fa0cc59 Mon Sep 17 00:00:00 2001 From: "Curtis.Bezault" Date: Tue, 9 Apr 2019 15:04:44 -0700 Subject: [PATCH 2/2] Print what port installed confliciting files --- toolsrc/include/vcpkg/base/strings.h | 26 ++++++-- toolsrc/src/vcpkg/install.cpp | 95 +++++++++++++++++++--------- 2 files changed, 85 insertions(+), 36 deletions(-) diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 4b39b0a2876..04e85107eb7 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -56,12 +56,10 @@ namespace vcpkg::Strings bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); bool ends_with(const std::string& s, StringLiteral pattern); - template - std::string join(const char* delimiter, const Container& v, Transformer transformer) + template + std::string join(const char* delimiter, InputIterator begin, InputIterator end, + Transformer transformer) { - const auto begin = v.begin(); - const auto end = v.end(); - if (begin == end) { return std::string(); @@ -77,6 +75,24 @@ namespace vcpkg::Strings return output; } + + template + std::string join(const char* delimiter, const Container& v, Transformer transformer) + { + const auto begin = v.begin(); + const auto end = v.end(); + + return join(delimiter, begin, end, transformer); + } + + template + std::string join(const char* delimiter, InputIterator begin, InputIterator end) + { + using Element = decltype(*begin); + return join(delimiter, begin, end, + [](const Element& x) -> const Element& { return x; }); + } + template std::string join(const char* delimiter, const Container& v) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 4348768718a..7fc8b294bb8 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -19,6 +19,8 @@ namespace vcpkg::Install { using namespace Dependencies; + using file_pack = std::pair; + InstallDir InstallDir::from_destination_root(const fs::path& destination_root, const std::string& destination_subdirectory, const fs::path& listfile) @@ -139,18 +141,12 @@ namespace vcpkg::Install fs.write_lines(listfile, output); } - static void remove_first_n_chars(std::vector* strings, const size_t n) + static std::vector extract_files_in_triplet( + const std::vector& pgh_and_files, + const Triplet& triplet, + const size_t remove_chars = 0) { - for (std::string& s : *strings) - { - s.erase(0, n); - } - }; - - static std::vector extract_files_in_triplet( - const std::vector& pgh_and_files, const Triplet& triplet) - { - std::vector output; + std::vector output; for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) { if (t.pgh.package.spec.triplet() != triplet) @@ -158,10 +154,16 @@ namespace vcpkg::Install continue; } - Util::Vectors::concatenate(&output, t.files); + const std::string name = t.pgh.package.displayname(); + + for (const std::string &file : t.files) + { + output.emplace_back(file_pack{std::string(file, remove_chars), name}); + } } - std::sort(output.begin(), output.end()); + std::sort(output.begin(), output.end(), + [](const file_pack &lhs, const file_pack &rhs) { return lhs.first < rhs.first; }); return output; } @@ -171,22 +173,21 @@ namespace vcpkg::Install const std::vector package_file_paths = fs.get_files_recursive(package_dir); const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { - std::string as_string = path.generic_string(); - as_string.erase(0, package_remove_char_count); - return std::move(as_string); + return std::move(std::string(path.generic_string(), package_remove_char_count)); }); return SortedVector(std::move(package_files)); } - static SortedVector build_list_of_installed_files( - const std::vector& pgh_and_files, const Triplet& triplet) + static SortedVector build_list_of_installed_files( + const std::vector& pgh_and_files, + const Triplet& triplet) { - std::vector installed_files = extract_files_in_triplet(pgh_and_files, triplet); const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash - remove_first_n_chars(&installed_files, installed_remove_char_count); + std::vector installed_files = + extract_files_in_triplet(pgh_and_files, triplet, installed_remove_char_count); - return SortedVector(std::move(installed_files)); + return SortedVector(std::move(installed_files)); } InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) @@ -197,25 +198,57 @@ namespace vcpkg::Install const SortedVector package_files = build_list_of_package_files(paths.get_filesystem(), package_dir); - const SortedVector installed_files = build_list_of_installed_files(pgh_and_files, triplet); + const SortedVector installed_files = + build_list_of_installed_files(pgh_and_files, triplet); - std::vector intersection; - std::set_intersection(package_files.begin(), - package_files.end(), - installed_files.begin(), + struct intersection_compare + { + bool operator()(const std::string &lhs, const file_pack &rhs) { return lhs < rhs.first; } + bool operator()(const file_pack &lhs, const std::string &rhs) { return lhs.first < rhs; } + }; + + std::vector intersection; + + std::set_intersection(installed_files.begin(), installed_files.end(), - std::back_inserter(intersection)); + package_files.begin(), + package_files.end(), + std::back_inserter(intersection), + intersection_compare()); + + std::sort(intersection.begin(), intersection.end(), + [](const file_pack &lhs, const file_pack &rhs) + { + return lhs.second < rhs.second; + }); if (!intersection.empty()) { const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); System::println(System::Color::error, - "The following files are already installed in %s and are in conflict with %s", + "The following files are already installed in %s by and are in conflict with %s\n", triplet_install_path.generic_string(), bcf.core_paragraph.spec); - System::print("\n "); - System::println(Strings::join("\n ", intersection)); - System::println(); + + auto i = intersection.begin(); + while (i != intersection.end()) { + System::println("%s:", i->second); + auto next = std::find_if(i, intersection.end(), + [i](const auto &val) + { + return i->second != val.second; + }); + + System::println(Strings::join("\n ", i, next, + [](const file_pack &file) + { + return file.first; + })); + System::println(); + + i = next; + } + return InstallResult::FILE_CONFLICTS; }