diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
index ec14f8a97d..a95a680903 100644
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ b/toolsrc/include/vcpkg/binaryparagraph.h
@@ -7,6 +7,13 @@
namespace vcpkg
{
+ enum class ConsistencyState : unsigned
+ {
+ UNKNOWN = 0,
+ CONSISTENT,
+ INCONSISTENT,
+ };
+
///
/// Built package metadata
///
@@ -23,6 +30,8 @@ namespace vcpkg
std::string dir() const;
+ bool is_consistent() const;
+
PackageSpec spec;
std::string version;
std::string description;
@@ -33,6 +42,8 @@ namespace vcpkg
std::string abi;
SourceParagraph::TYPE type;
std::unordered_map external_files;
+
+ mutable ConsistencyState consistency = ConsistencyState::UNKNOWN;
};
struct BinaryControlFile
diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp
index 2e9415dab7..88d257e7e2 100644
--- a/toolsrc/src/vcpkg/binaryparagraph.cpp
+++ b/toolsrc/src/vcpkg/binaryparagraph.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include
+#include
#include
#include
#include
@@ -27,6 +28,32 @@ namespace vcpkg
static const std::string EXTERNALFILES = "External-Files";
}
+ bool BinaryParagraph::is_consistent() const
+ {
+ switch (consistency)
+ {
+ case ConsistencyState::UNKNOWN :
+ for (const auto& file_hash : external_files)
+ {
+ const auto& realfs = Files::get_real_filesystem();
+
+ if (realfs.is_regular_file(file_hash.first) &&
+ Hash::get_file_hash(realfs, file_hash.first, "SHA1") != file_hash.second)
+ {
+ consistency = ConsistencyState::INCONSISTENT;
+ return false;
+ }
+ }
+
+ consistency = ConsistencyState::CONSISTENT;
+ return true;
+ case ConsistencyState::CONSISTENT : return true;
+ case ConsistencyState::INCONSISTENT : return false;
+ }
+
+ Checks::unreachable(VCPKG_LINE_INFO);
+ }
+
BinaryParagraph::BinaryParagraph() = default;
BinaryParagraph::BinaryParagraph(std::unordered_map fields)
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index 110a571b07..1f0dda5900 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -475,11 +475,15 @@ namespace vcpkg::Build
{
hashes.emplace_back(external_file, it_hash->second);
}
- else if (fs.is_regular_file(external_file))
+ else if (Files::get_real_filesystem().is_regular_file(external_file))
{
- auto emp = s_hash_cache.emplace(external_file.u8string(),
- Hash::get_file_hash(fs, external_file, "SHA1"));
- hashes.emplace_back(external_file, emp.first->second);
+ auto emp = s_hash_cache.emplace(
+ external_file.u8string(),
+ Hash::get_file_hash(
+ Files::get_real_filesystem(),
+ external_file, "SHA1"));
+
+ hashes.emplace_back(external_file.u8string(), emp.first->second);
}
else
{
diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp
index b604c9acfe..50c310dbbc 100644
--- a/toolsrc/src/vcpkg/dependencies.cpp
+++ b/toolsrc/src/vcpkg/dependencies.cpp
@@ -664,13 +664,17 @@ namespace vcpkg::Dependencies
if (auto p_installed = cluster.installed.get())
{
- if (p_installed->original_features.find(feature) != p_installed->original_features.end())
+ if (p_installed->original_features.find(feature) != p_installed->original_features.end() &&
+ p_installed->ipv.core->package.is_consistent())
{
return MarkPlusResult::SUCCESS;
}
}
- // This feature was or will be uninstalled, therefore we need to rebuild
+ //The feature was not previously installed or the external files of the
+ //port are no longer consistent with the last installation of this port
+ //(they've either been modified or removed). Mark the cluster
+ //(aka the entire port) to be removed before re-adding it.
mark_minus(cluster, graph, graph_plan, prevent_default_features);
return follow_plus_dependencies(feature, cluster, graph, graph_plan, prevent_default_features);