Where does the hash before .clean under buildtrees/<package>/src in vcpkg come from
intro
If you inspect the structure of vcpkg in your local file system, you may notice that the source code of the package is located in a directory like this:
tsecer@harry: ls -d vcpkg/buildtrees/curl/src/url-8_14_1-c688bafef9.clean vcpkg/buildtrees/curl/src/url-8_14_1-c688bafef9.clean
The interesting part is what the hash value is, e.g. c688bafef9 in the example above. where does it come from and what is it used for?
inside vcpkg
It's not diffault to track down the source code that generates this hash in vcpkg. And the code is copied here for easy reading:
# Hash the archive hash along with the patches. Take the first 10 chars of the hash
file(SHA512 "${arg_ARCHIVE}" patchset_hash)
foreach(patch IN LISTS arg_PATCHES)
cmake_path(ABSOLUTE_PATH patch
BASE_DIRECTORY "${CURRENT_PORT_DIR}"
OUTPUT_VARIABLE absolute_patch
)
if(NOT EXISTS "${absolute_patch}")
message(FATAL_ERROR "Could not find patch: '${patch}'")
endif()
file(SHA512 "${absolute_patch}" current_hash)
string(APPEND patchset_hash "${current_hash}")
endforeach()
string(SHA512 patchset_hash "${patchset_hash}")
string(SUBSTRING "${patchset_hash}" 0 10 patchset_hash)
cmake_path(APPEND working_directory "${arg_SOURCE_BASE}-${patchset_hash}"
OUTPUT_VARIABLE source_path
)
if(_VCPKG_EDITABLE AND EXISTS "${source_path}")
set("${out_source_path}" "${source_path}" PARENT_SCOPE)
message(STATUS "Using source at ${source_path}")
return()
elseif(NOT _VCPKG_EDITABLE)
cmake_path(APPEND_STRING source_path ".clean")
if(EXISTS "${source_path}")
message(STATUS "Cleaning sources at ${source_path}. Use --editable to skip cleaning for the packages you specify.")
file(REMOVE_RECURSE "${source_path}")
endif()
endif()
The logic here is straightforward too: It derives from the SHA512 hash value of the string which is assembled from the archive file and hash values of all patch files.
patch set matters
- orders
Since the hashes of all patches are constructed in the order defined in the patch set, the final hash will change if the patch sequence is adjusted, even if the file content remains unchanged.
- content
A new local package will be created for each patch set no matter how tiny the patch set is.
verify
If the order of the patches is modified even without changing the patch files, a new local package will be created:
tsecer@harry: git diff
diff --git a/ports/curl/portfile.cmake b/ports/curl/portfile.cmake
index d884af05e2..0dce90ab42 100644
--- a/ports/curl/portfile.cmake
+++ b/ports/curl/portfile.cmake
@@ -7,8 +7,8 @@ vcpkg_from_github(
SHA512 ec2fa6c47d52feed943421b00e98370971bcc73b82842a85426ea9e42d36eaab51258a8d00197fdaaf5ec39e19385280fe387765f27e3b3dc1086c46236dc0bf
HEAD_REF master
PATCHES
- dependencies.patch
pkgconfig-curl-config.patch
+ dependencies.patch
)
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
tsecer@harry: ls buildtrees/curl/src/
url-8_14_1-15947c732c.clean url-8_14_1-c688bafef9.clean
tsecer@harry:
outro
I guess the hash is primarily used for the patch mechanism in vcpkg and it does resolve the issue neatly.
浙公网安备 33010602011771号