From d9cbe4a288837f01935e5e05d8e3dfdeefd5d144 Mon Sep 17 00:00:00 2001 From: Alexander Neumann <30894796+Neumann-A@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:17:49 +0200 Subject: [PATCH 01/30] add and link libcurl --- .github/workflows/build.yaml | 10 ++++++ CMakeLists.txt | 7 +++- cmake/FindLibCURL.cmake | 67 ++++++++++++++++++++++++++++++++++++ include/vcpkg/base/curl.h | 11 ++++++ src/vcpkg/base/downloads.cpp | 2 ++ src/vcpkg/metrics.cpp | 2 ++ 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 cmake/FindLibCURL.cmake create mode 100644 include/vcpkg/base/curl.h diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b9d9d9a96a..5f38b71eb8 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -82,3 +82,13 @@ jobs: ${{ github.workspace }}/azure-pipelines/end-to-end-tests.ps1 -RunArtifactsTests env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg-root + - name: Upload CMake logs on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cmake-logs + path: | + out/build/${{ matrix.preset }}/CMakeFiles/CMakeError.log + out/build/${{ matrix.preset }}/CMakeFiles/CMakeOutput.log + out/build/${{ matrix.preset }}/CMakeFiles/CMakeConfigureLog.yaml + diff --git a/CMakeLists.txt b/CMakeLists.txt index 59b49353e2..ad40a546f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,6 +195,7 @@ set(TEST_SCRIPT_ASSET_CACHE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/test-script find_package(fmt REQUIRED) find_package(CMakeRC REQUIRED) +find_package(LibCURL REQUIRED) # === Target: locale-resources === @@ -229,6 +230,8 @@ target_compile_definitions(vcpkglib PUBLIC _FILE_OFFSET_BITS=64 ) +target_link_libraries(vcpkglib PRIVATE CURL::libcurl) + if(VCPKG_STANDALONE_BUNDLE_SHA) target_compile_definitions(vcpkglib PUBLIC "VCPKG_STANDALONE_BUNDLE_SHA=${VCPKG_STANDALONE_BUNDLE_SHA}" @@ -467,6 +470,7 @@ if (BUILD_TESTING) "${CMAKE_CURRENT_SOURCE_DIR}/src/vcpkg.manifest" ) target_link_libraries(vcpkg-test PRIVATE vcpkglib) + set_property(TARGET vcpkg-test PROPERTY PDB_NAME "vcpkg-test${VCPKG_PDB_SUFFIX}") if(ANDROID) target_link_libraries(vcpkg-test PRIVATE log) @@ -476,7 +480,8 @@ if (BUILD_TESTING) if(CMAKE_VERSION GREATER_EQUAL "3.16") target_precompile_headers(vcpkg-test REUSE_FROM vcpkglib) - elseif(NOT MSVC) + target_compile_definitions(vcpkg-test PRIVATE CURL_STATICLIB) + elseif(NOT MSVC) target_compile_options(vcpkg-test PRIVATE -include "${CMAKE_CURRENT_SOURCE_DIR}/include/pch.h") endif() diff --git a/cmake/FindLibCURL.cmake b/cmake/FindLibCURL.cmake new file mode 100644 index 0000000000..123be82c80 --- /dev/null +++ b/cmake/FindLibCURL.cmake @@ -0,0 +1,67 @@ +option(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL "Use an external version of the libcurl library" OFF) + +# This option exists to allow the URI to be replaced with a Microsoft-internal URI in official +# builds which have restricted internet access; see azure-pipelines/signing.yml +# Note that the SHA512 is the same, so vcpkg-tool contributors need not be concerned that we built +# with different content. +if(NOT VCPKG_LIBCURL_URL) + set(VCPKG_LIBCURL_URL "https://github.com/curl/curl/archive/refs/tags/curl-8_8_0.tar.gz") +endif() + +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + +include(FetchContent) +FetchContent_Declare( + LibCURL + URL "${VCPKG_LIBCURL_URL}" + URL_HASH "SHA512=e66cbf9bd3ae7b9b031475210b80b883b6a133042fbbc7cf2413f399d1b38aa54ab7322626abd3c6f1af56e0d540221f618aa903bd6b463ac8324f2c4e92dfa8" +) + +if(NOT LibCURL_FIND_REQUIRED) + message(FATAL_ERROR "LibCURL must be REQUIRED") +endif() + +if(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL) + find_package(CURL REQUIRED) +else() + function(get_libcurl) + set(BUILD_SHARED_LIBS OFF) + set(BUILD_STATIC_LIBS ON) + set(BUILD_CURL_EXE OFF) + set(CURL_DISABLE_INSTALL OFF) + #set(CURL_STATIC_CRT ON) + set(ENABLE_UNICODE ON) + set(CURL_ENABLE_EXPORT_TARGET OFF) + set(BUILD_LIBCURL_DOCS OFF) + set(BUILD_MISC_DOCS OFF) + set(ENABLE_CURL_MANUAL OFF) + set(PICKY_COMPILER OFF) + set(CMAKE_DISABLE_FIND_PACKAGE_Perl ON) + set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON) + set(CMAKE_DISABLE_FIND_PACKAGE_LibPSL ON) + set(CMAKE_DISABLE_FIND_PACKAGE_LibSSH2 ON) + if(MSVC) # This is in function() so no need to backup the variables + string(APPEND CMAKE_C_FLAGS " /wd6101") + string(APPEND CMAKE_C_FLAGS " /wd6011") + string(APPEND CMAKE_C_FLAGS " /wd6054") + string(APPEND CMAKE_C_FLAGS " /wd6240") + string(APPEND CMAKE_C_FLAGS " /wd6239") + string(APPEND CMAKE_C_FLAGS " /wd6323") + string(APPEND CMAKE_C_FLAGS " /wd6387") + string(APPEND CMAKE_C_FLAGS " /wd28182") + string(APPEND CMAKE_C_FLAGS " /wd28183") + string(APPEND CMAKE_C_FLAGS " /wd28251") + else() + string(APPEND CMAKE_C_FLAGS " -Wno-error") + endif() + FetchContent_MakeAvailable(LibCURL) + endfunction() + get_libcurl() + if(NOT TARGET CURL::libcurl) + add_library(CURL::libcurl INTERFACE) + target_link_libraries(CURL::libcurl INTERFACE libcurl_static) + target_compile_options(CURL::libcurl INTERFACE CURL_STATICLIB) + endif() +endif() diff --git a/include/vcpkg/base/curl.h b/include/vcpkg/base/curl.h new file mode 100644 index 0000000000..d160c47b5a --- /dev/null +++ b/include/vcpkg/base/curl.h @@ -0,0 +1,11 @@ + +#ifdef _MSC_VER +#pragma warning(push) // Save current warning state +#pragma warning(disable : 6101) // Disable specific warning (e.g., warning 4996) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif \ No newline at end of file diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 7c3227ba4b..8d60b52bcf 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -680,6 +681,7 @@ namespace vcpkg { #define GUID_MARKER "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c" static constexpr StringLiteral guid_marker = GUID_MARKER; + // TODO: Replace with libcurl code. Command prefix_cmd{"curl"}; if (!prefixArgs.empty()) { diff --git a/src/vcpkg/metrics.cpp b/src/vcpkg/metrics.cpp index de1070718e..ee561ed962 100644 --- a/src/vcpkg/metrics.cpp +++ b/src/vcpkg/metrics.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -618,6 +619,7 @@ namespace vcpkg builder.string_arg(vcpkg_metrics_txt_path); cmd_execute_background(builder); #else + // TODO: replace with libcurl code cmd_execute_background(Command("curl") .string_arg("https://dc.services.visualstudio.com/v2/track") .string_arg("--max-time") From d6aafe48c87e60cbbc8a6fdbe694fb5dc7601c6f Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 22 Apr 2025 23:15:15 +0000 Subject: [PATCH 02/30] Replace curl executable with libcurl API calls --- .github/workflows/build.yaml | 15 +- CMakeLists.txt | 6 +- .../end-to-end-tests-dir/asset-caching.ps1 | 21 +- cmake/FindLibCURL.cmake | 33 +- include/vcpkg/base/contractual-constants.h | 1 + include/vcpkg/base/curl.h | 8 +- include/vcpkg/base/downloads.h | 17 - include/vcpkg/base/files.h | 2 + include/vcpkg/base/message-data.inc.h | 30 +- include/vcpkg/metrics.h | 4 +- locales/messages.json | 19 +- src/vcpkg-test/downloads.cpp | 87 +-- src/vcpkg.cpp | 7 + src/vcpkg/base/curl.cpp | 26 + src/vcpkg/base/downloads.cpp | 607 +++++++++--------- src/vcpkg/base/files.cpp | 29 + src/vcpkg/commands.cpp | 2 +- src/vcpkg/commands.z-check-tools-sha.cpp | 3 +- src/vcpkg/commands.z-upload-metrics.cpp | 32 +- src/vcpkg/metrics.cpp | 207 +++--- 20 files changed, 564 insertions(+), 592 deletions(-) create mode 100644 src/vcpkg/base/curl.cpp diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5f38b71eb8..89cf525f68 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -36,6 +36,11 @@ jobs: uses: github/codeql-action/init@v3 with: languages: javascript-typescript, c-cpp + - name: Install system libcurl + if: matrix.preset == 'linux-arm64-ci' || matrix.preset == 'linux-ci' + run: | + sudo apt update + sudo apt install -y libcurl4-openssl-dev - name: Configure and Build if: matrix.preset != 'windows-ci' run: | @@ -82,13 +87,3 @@ jobs: ${{ github.workspace }}/azure-pipelines/end-to-end-tests.ps1 -RunArtifactsTests env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg-root - - name: Upload CMake logs on failure - if: failure() - uses: actions/upload-artifact@v4 - with: - name: cmake-logs - path: | - out/build/${{ matrix.preset }}/CMakeFiles/CMakeError.log - out/build/${{ matrix.preset }}/CMakeFiles/CMakeOutput.log - out/build/${{ matrix.preset }}/CMakeFiles/CMakeConfigureLog.yaml - diff --git a/CMakeLists.txt b/CMakeLists.txt index ad40a546f6..2694168c71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,7 +230,7 @@ target_compile_definitions(vcpkglib PUBLIC _FILE_OFFSET_BITS=64 ) -target_link_libraries(vcpkglib PRIVATE CURL::libcurl) +target_link_libraries(vcpkglib PUBLIC CURL::libcurl) if(VCPKG_STANDALONE_BUNDLE_SHA) target_compile_definitions(vcpkglib PUBLIC @@ -470,7 +470,6 @@ if (BUILD_TESTING) "${CMAKE_CURRENT_SOURCE_DIR}/src/vcpkg.manifest" ) target_link_libraries(vcpkg-test PRIVATE vcpkglib) - set_property(TARGET vcpkg-test PROPERTY PDB_NAME "vcpkg-test${VCPKG_PDB_SUFFIX}") if(ANDROID) target_link_libraries(vcpkg-test PRIVATE log) @@ -480,8 +479,7 @@ if (BUILD_TESTING) if(CMAKE_VERSION GREATER_EQUAL "3.16") target_precompile_headers(vcpkg-test REUSE_FROM vcpkglib) - target_compile_definitions(vcpkg-test PRIVATE CURL_STATICLIB) - elseif(NOT MSVC) + elseif(NOT MSVC) target_compile_options(vcpkg-test PRIVATE -include "${CMAKE_CURRENT_SOURCE_DIR}/include/pch.h") endif() diff --git a/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 b/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 index c323bb7060..55b3a58eb4 100644 --- a/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 @@ -53,7 +53,7 @@ Throw-IfNotFailed $expected = @( "A suitable version of cmake was not found \(required v[0-9.]+\)\.", "Trying to download cmake-[0-9.]+-[^.]+\.(zip|tar\.gz) using asset cache file://$assetCacheRegex/[0-9a-z]+", -"error: curl: \(37\) Couldn't open file [^\n]+", +"error: curl operation failed with error code 37 \(Couldn't read a file:// file\)\.", "error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://github\.com/Kitware/CMake/releases/download/[^ ]+", "note: If you are using a proxy, please ensure your proxy settings are correct\.", "Possible causes are:", @@ -105,7 +105,7 @@ if (-not ($actual -match $expected)) { Refresh-TestRoot $expected = @( "^Downloading https://localhost:1234/foobar\.html -> example3\.html", -"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"error: curl operation failed with error code 7 \(Couldn't connect to server\)\.", "note: If you are using a proxy, please ensure your proxy settings are correct\.", "Possible causes are:", "1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", @@ -129,8 +129,8 @@ Refresh-TestRoot $expected = @( "^Downloading example3\.html, trying https://localhost:1234/foobar\.html", "Trying https://localhost:1235/baz\.html", -"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", -"error: curl: \(7\) Failed to connect to localhost port 1235( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"error: curl operation failed with error code 7 \(Couldn't connect to server\)\.", +"error: curl operation failed with error code 7 \(Couldn't connect to server\)\.", "note: If you are using a proxy, please ensure your proxy settings are correct\.", "Possible causes are:", "1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", @@ -206,9 +206,6 @@ if ($IsWindows) { Refresh-TestRoot $expected = @( "^Downloading example3\.html, trying https://nonexistent\.example\.com", -"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 1 seconds?\. 3 retries left\.", -"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 2 seconds\. 2 retries left\.", -"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 4 seconds\. 1 (retries|retry) left\.", "Trying https://example\.com", "Successfully downloaded example3\.html", "$" @@ -217,7 +214,7 @@ $expected = @( $actual = Run-VcpkgAndCaptureOutput @commonArgs x-download "$TestDownloadsRoot/example3.html" --sha512 d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a --url https://nonexistent.example.com --url https://example.com --header "Cache-Control: no-cache" Throw-IfFailed if (-not ($actual -match $expected)) { - throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed)" + throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed), headers (cache-control)" } # azurl (no), x-block-origin (yes), asset-cache (n/a), download (n/a) @@ -241,8 +238,8 @@ Refresh-TestRoot $expected = @( "^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", "Asset cache miss; trying authoritative source https://localhost:1234/foobar\.html", -"error: curl: \(37\) Couldn't open file [^\n]+", -"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"error: curl operation failed with error code 37 \(Couldn't read a file:// file\)\.", +"error: curl operation failed with error code 7 \(Couldn't connect to server\)\.", "note: If you are using a proxy, please ensure your proxy settings are correct\.", "Possible causes are:", "1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", @@ -301,7 +298,7 @@ if (-not ($actual -match $expected)) { $expected = @( "^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", "Asset cache miss; trying authoritative source https://example\.com", -"error: curl: \(37\) Couldn't open file [^\n]+", +"error: curl operation failed with error code 37 \(Couldn't read a file:// file\)\.", "note: If you are using a proxy, please ensure your proxy settings are correct\.", "Possible causes are:", "1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", @@ -363,7 +360,7 @@ if (-not ($actual -match $expected)) { Refresh-TestRoot $expected = @( "^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", -"error: curl: \(37\) Couldn't open file [^\n]+", +"error: curl operation failed with error code 37 \(Couldn't read a file:// file\)\.", "error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", "note: or https://alternate\.example\.com", "note: If you are using a proxy, please ensure your proxy settings are correct\.", diff --git a/cmake/FindLibCURL.cmake b/cmake/FindLibCURL.cmake index 123be82c80..c59ab810ba 100644 --- a/cmake/FindLibCURL.cmake +++ b/cmake/FindLibCURL.cmake @@ -1,4 +1,8 @@ -option(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL "Use an external version of the libcurl library" OFF) +if (WIN32) + option(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL "Use an external version of the libcurl library" OFF) +else() + option(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL "Use an external version of the libcurl library" ON) +endif() # This option exists to allow the URI to be replaced with a Microsoft-internal URI in official # builds which have restricted internet access; see azure-pipelines/signing.yml @@ -28,12 +32,9 @@ if(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL) else() function(get_libcurl) set(BUILD_SHARED_LIBS OFF) - set(BUILD_STATIC_LIBS ON) set(BUILD_CURL_EXE OFF) - set(CURL_DISABLE_INSTALL OFF) - #set(CURL_STATIC_CRT ON) - set(ENABLE_UNICODE ON) set(CURL_ENABLE_EXPORT_TARGET OFF) + set(ENABLE_UNICODE ON) set(BUILD_LIBCURL_DOCS OFF) set(BUILD_MISC_DOCS OFF) set(ENABLE_CURL_MANUAL OFF) @@ -53,15 +54,29 @@ else() string(APPEND CMAKE_C_FLAGS " /wd28182") string(APPEND CMAKE_C_FLAGS " /wd28183") string(APPEND CMAKE_C_FLAGS " /wd28251") + string(APPEND CMAKE_C_FLAGS " /wd28301") else() string(APPEND CMAKE_C_FLAGS " -Wno-error") endif() - FetchContent_MakeAvailable(LibCURL) + if (WIN32) + set(CURL_USE_SCHANNEL ON) + endif() + FetchContent_MakeAvailable(LibCURL) endfunction() + get_libcurl() + if(NOT TARGET CURL::libcurl) - add_library(CURL::libcurl INTERFACE) - target_link_libraries(CURL::libcurl INTERFACE libcurl_static) - target_compile_options(CURL::libcurl INTERFACE CURL_STATICLIB) + if(TARGET libcurl_static) + add_library(CURL::libcurl ALIAS libcurl_static) + target_compile_definitions(libcurl_static INTERFACE CURL_STATICLIB) + elseif(TARGET libcurl) + add_library(CURL::libcurl ALIAS libcurl) + if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(libcurl INTERFACE CURL_STATICLIB) + endif() + else() + message(FATAL_ERROR "After FetchContent_MakeAvailable(LibCURL) no suitable curl target (libcurl or libcurl_static) was found.") + endif() endif() endif() diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index 3698bf8301..092c19182a 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -206,6 +206,7 @@ namespace vcpkg inline constexpr StringLiteral SwitchDebug = "debug"; inline constexpr StringLiteral SwitchDebugBin = "debug-bin"; inline constexpr StringLiteral SwitchDebugEnv = "debug-env"; + inline constexpr StringLiteral SwitchDeleteFileAfterUpload = "delete-file-after-upload"; inline constexpr StringLiteral SwitchDgml = "dgml"; inline constexpr StringLiteral SwitchDisableMetrics = "disable-metrics"; inline constexpr StringLiteral SwitchDot = "dot"; diff --git a/include/vcpkg/base/curl.h b/include/vcpkg/base/curl.h index d160c47b5a..fad74ef097 100644 --- a/include/vcpkg/base/curl.h +++ b/include/vcpkg/base/curl.h @@ -5,7 +5,13 @@ #endif #include +#include #ifdef _MSC_VER #pragma warning(pop) -#endif \ No newline at end of file +#endif + +namespace vcpkg +{ + CURLcode curl_global_init_status() noexcept; +} diff --git a/include/vcpkg/base/downloads.h b/include/vcpkg/base/downloads.h index 068ab463b3..66d15818c0 100644 --- a/include/vcpkg/base/downloads.h +++ b/include/vcpkg/base/downloads.h @@ -37,16 +37,6 @@ namespace vcpkg View azure_blob_headers(); - // Parses a curl output line for curl invoked with - // -w "PREFIX%{http_code} %{exitcode} %{errormsg}" - // with specific handling for curl version < 7.75.0 which does not understand %{exitcode} %{errormsg} - // If the line is malformed for any reason, no entry to http_codes is added. - // Returns: true if the new version of curl's output with exitcode and errormsg was parsed; otherwise, false. - bool parse_curl_status_line(DiagnosticContext& context, - std::vector& http_codes, - StringLiteral prefix, - StringView this_line); - std::vector download_files_no_cache(DiagnosticContext& context, View> url_pairs, View headers, @@ -58,13 +48,6 @@ namespace vcpkg const std::string& github_repository, const Json::Object& snapshot); - Optional invoke_http_request(DiagnosticContext& context, - StringLiteral method, - View headers, - StringView url, - View secrets, - StringView data = {}); - std::string format_url_query(StringView base_url, View query_params); std::vector url_heads(DiagnosticContext& context, diff --git a/include/vcpkg/base/files.h b/include/vcpkg/base/files.h index 705bbc401c..136688c6ac 100644 --- a/include/vcpkg/base/files.h +++ b/include/vcpkg/base/files.h @@ -103,6 +103,8 @@ namespace vcpkg // reads any remaining chunks of the file; used to implement read_to_end void read_to_end_suffix( std::string& output, std::error_code& ec, char* buffer, size_t buffer_size, size_t last_read); + uint64_t size(LineInfo li) const; + uint64_t size(std::error_code& ec) const; }; struct WriteFilePointer : FilePointer diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index d19ff233f8..f5a513accc 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -870,6 +870,7 @@ DECLARE_MESSAGE(CmdUpdateRegistryAllOrTargets, (), "", "Update registry requires either a list of artifact registry names or URiIs to update, or --all.") +DECLARE_MESSAGE(CmdUploadMetricsDeleteFileAfterUpload, (), "", "Delete metrics payload file after upload") DECLARE_MESSAGE(CmdUpgradeOptNoDryRun, (), "", "Actually upgrade") DECLARE_MESSAGE(CmdUpgradeOptNoKeepGoing, (), "", "Stop installing packages on failure") DECLARE_MESSAGE(CmdUseExample1, @@ -966,24 +967,25 @@ DECLARE_MESSAGE(CreatingNugetPackage, (), "", "Creating NuGet package...") DECLARE_MESSAGE(CreatingZipArchive, (), "", "Creating zip archive...") DECLARE_MESSAGE(CreationFailed, (msg::path), "", "Creating {path} failed.") DECLARE_MESSAGE(CurlFailedGeneric, + (msg::exit_code, msg::error_msg), + "curl is the name of a program, see curl.se.", + "curl operation failed with error code {exit_code} ({error_msg}).") +DECLARE_MESSAGE(CurlFailedGenericWithRetry, + (msg::exit_code, msg::error_msg, msg::count, msg::value), + "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", + "curl operation failed with error code {exit_code} ({error_msg}) retry {count} of {value}.") +DECLARE_MESSAGE(CurlFailedHttpResponse, (msg::exit_code), "curl is the name of a program, see curl.se.", - "curl operation failed with error code {exit_code}.") -DECLARE_MESSAGE(CurlFailedToPut, - (msg::exit_code, msg::url), - "curl is the name of a program, see curl.se", - "curl failed to put file to {url} with exit code {exit_code}.") + "curl operation failed with HTTP response code {exit_code}.") +DECLARE_MESSAGE(CurlFailedHttpResponseWithRetry, + (msg::exit_code, msg::count, msg::value), + "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", + "curl operation failed with HTTP response code {exit_code} retry {count} of {value}.") DECLARE_MESSAGE(CurlFailedToPutHttp, - (msg::exit_code, msg::url, msg::value), + (msg::exit_code, msg::error_msg, msg::url, msg::value), "curl is the name of a program, see curl.se. {value} is an HTTP status code", - "curl failed to put file to {url} with exit code {exit_code} and http code {value}.") -DECLARE_MESSAGE( - CurlFailedToReturnExpectedNumberOfExitCodes, - (msg::exit_code, msg::command_line), - "", - "curl failed to return the expected number of exit codes; this can happen if something terminates curl " - "before it has finished. curl exited with {exit_code} which is normally the result code for the last operation, " - "but may be the result of a crash. The command line was {command_line}, and all output is below:") + "curl failed to put file to {url} with exit code {exit_code} ({error_msg}) and http code {value}.") DECLARE_MESSAGE(CurrentCommitBaseline, (msg::commit_sha), "", diff --git a/include/vcpkg/metrics.h b/include/vcpkg/metrics.h index 5391cfc2bc..7168d11c27 100644 --- a/include/vcpkg/metrics.h +++ b/include/vcpkg/metrics.h @@ -198,7 +198,5 @@ namespace vcpkg extern std::atomic g_should_send_metrics; void flush_global_metrics(const Filesystem&); -#if defined(_WIN32) - void winhttp_upload_metrics(StringView payload); -#endif // ^^^ _WIN32 + bool curl_upload_metrics(StringView payload); } diff --git a/locales/messages.json b/locales/messages.json index d57aae3fb7..c23af5cbe9 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -506,6 +506,7 @@ "CmdUpdateRegistrySynopsis": "Re-downloads an artifact registry", "CmdUpgradeOptNoDryRun": "Actually upgrade", "CmdUpgradeOptNoKeepGoing": "Stop installing packages on failure", + "CmdUploadMetricsDeleteFileAfterUpload": "Delete metrics payload file after upload", "CmdUseExample1": "vcpkg use ", "_CmdUseExample1.comment": "This is a command line, only the part should be localized.", "CmdUseSynopsis": "Activate a single artifact in this shell", @@ -563,14 +564,16 @@ "CreatingZipArchive": "Creating zip archive...", "CreationFailed": "Creating {path} failed.", "_CreationFailed.comment": "An example of {path} is /foo/bar.", - "CurlFailedGeneric": "curl operation failed with error code {exit_code}.", - "_CurlFailedGeneric.comment": "curl is the name of a program, see curl.se. An example of {exit_code} is 127.", - "CurlFailedToPut": "curl failed to put file to {url} with exit code {exit_code}.", - "_CurlFailedToPut.comment": "curl is the name of a program, see curl.se An example of {exit_code} is 127. An example of {url} is https://github.com/microsoft/vcpkg.", - "CurlFailedToPutHttp": "curl failed to put file to {url} with exit code {exit_code} and http code {value}.", - "_CurlFailedToPutHttp.comment": "curl is the name of a program, see curl.se. {value} is an HTTP status code An example of {exit_code} is 127. An example of {url} is https://github.com/microsoft/vcpkg.", - "CurlFailedToReturnExpectedNumberOfExitCodes": "curl failed to return the expected number of exit codes; this can happen if something terminates curl before it has finished. curl exited with {exit_code} which is normally the result code for the last operation, but may be the result of a crash. The command line was {command_line}, and all output is below:", - "_CurlFailedToReturnExpectedNumberOfExitCodes.comment": "An example of {exit_code} is 127. An example of {command_line} is vcpkg install zlib.", + "CurlFailedGeneric": "curl operation failed with error code {exit_code} ({error_msg}).", + "_CurlFailedGeneric.comment": "curl is the name of a program, see curl.se. An example of {exit_code} is 127. An example of {error_msg} is File Not Found.", + "CurlFailedGenericWithRetry": "curl operation failed with error code {exit_code} ({error_msg}) retry {count} of {value}.", + "_CurlFailedGenericWithRetry.comment": "curl is the name of a program, see curl.se. {value} is the maximum amount of retries. An example of {exit_code} is 127. An example of {error_msg} is File Not Found. An example of {count} is 42.", + "CurlFailedHttpResponse": "curl operation failed with HTTP response code {exit_code}.", + "_CurlFailedHttpResponse.comment": "curl is the name of a program, see curl.se. An example of {exit_code} is 127.", + "CurlFailedHttpResponseWithRetry": "curl operation failed with HTTP response code {exit_code} retry {count} of {value}.", + "_CurlFailedHttpResponseWithRetry.comment": "curl is the name of a program, see curl.se. {value} is the maximum amount of retries. An example of {exit_code} is 127. An example of {count} is 42.", + "CurlFailedToPutHttp": "curl failed to put file to {url} with exit code {exit_code} ({error_msg}) and http code {value}.", + "_CurlFailedToPutHttp.comment": "curl is the name of a program, see curl.se. {value} is an HTTP status code An example of {exit_code} is 127. An example of {error_msg} is File Not Found. An example of {url} is https://github.com/microsoft/vcpkg.", "CurrentCommitBaseline": "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{commit_sha}\"", "_CurrentCommitBaseline.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", "CycleDetectedDuring": "cycle detected during {spec}:", diff --git a/src/vcpkg-test/downloads.cpp b/src/vcpkg-test/downloads.cpp index 4b2c85b388..1953d816d1 100644 --- a/src/vcpkg-test/downloads.cpp +++ b/src/vcpkg-test/downloads.cpp @@ -120,91 +120,24 @@ TEST_CASE ("parse_split_url_view", "[downloads]") } } -TEST_CASE ("parse_curl_status_line", "[downloads]") -{ - std::vector http_codes; - StringLiteral malformed_examples[] = { - "asdfasdf", // wrong prefix - "curl: unknown --write-out variable: 'exitcode'", // wrong prefixes, and also what old curl does - "curl: unknown --write-out variable: 'errormsg'", - "prefix", // missing spaces - "prefix42", // missing spaces - "prefix42 2", // missing space - "prefix42 2a", // non numeric exitcode - }; - - FullyBufferedDiagnosticContext bdc; - for (auto&& malformed : malformed_examples) - { - REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", malformed)); - REQUIRE(http_codes.empty()); - REQUIRE(bdc.empty()); - } - - // old curl output - REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix200 ")); - REQUIRE(http_codes == std::vector{200}); - REQUIRE(bdc.empty()); - http_codes.clear(); - - REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix404 ")); - REQUIRE(http_codes == std::vector{404}); - REQUIRE(bdc.empty()); - http_codes.clear(); - - REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix0 ")); // a failure, but we don't know that yet - REQUIRE(http_codes == std::vector{0}); - REQUIRE(bdc.empty()); - http_codes.clear(); - - // current curl output - REQUIRE(parse_curl_status_line(bdc, http_codes, "prefix", "prefix200 0 ")); - REQUIRE(http_codes == std::vector{200}); - REQUIRE(bdc.empty()); - http_codes.clear(); - - REQUIRE(parse_curl_status_line( - bdc, - http_codes, - "prefix", - "prefix0 60 schannel: SNI or certificate check failed: SEC_E_WRONG_PRINCIPAL (0x80090322) " - "- The target principal name is incorrect.")); - REQUIRE(http_codes == std::vector{0}); - REQUIRE(bdc.to_string() == - "error: curl operation failed with error code 60. schannel: SNI or certificate check failed: " - "SEC_E_WRONG_PRINCIPAL (0x80090322) - The target principal name is incorrect."); -} - TEST_CASE ("download_files", "[downloads]") { auto const dst = Test::base_temporary_directory() / "download_files"; - auto const url = [&](std::string l) -> auto { return std::pair(l, dst); }; + real_filesystem.create_directories(dst, VCPKG_LINE_INFO); + + static const std::vector> test_downloads{ + {"unknown://localhost:9/secret", dst / "test1"}, + {"http://localhost:9/not-exists/secret", dst / "test2"}, + }; FullyBufferedDiagnosticContext bdc; std::vector headers; std::vector secrets; - auto results = download_files_no_cache( - bdc, - std::vector{url("unknown://localhost:9/secret"), url("http://localhost:9/not-exists/secret")}, - headers, - secrets); - REQUIRE(results == std::vector{0, 0}); + auto results = download_files_no_cache(bdc, test_downloads, headers, secrets); + REQUIRE(results == std::vector{-1, -1}); auto all_errors = bdc.to_string(); - if (all_errors == "error: curl operation failed with error code 7.") - { - // old curl, this is OK! - } - else - { - // new curl - REQUIRE_THAT( - all_errors, - Catch::Matches("error: curl operation failed with error code 1\\. Protocol \"unknown\" not supported( or " - "disabled in libcurl)?\n" - "error: curl operation failed with error code 7\\. Failed to connect to localhost port 9 " - "after [0-9]+ ms: ((Could not|Couldn't) connect to server|Connection refused)", - Catch::CaseSensitive::Yes)); - } + REQUIRE(all_errors == "error: curl operation failed with error code 1 (Unsupported protocol).\n" + "error: curl operation failed with error code 7 (Couldn't connect to server)."); } TEST_CASE ("try_parse_curl_max5_size", "[downloads]") diff --git a/src/vcpkg.cpp b/src/vcpkg.cpp index cce2fc75a0..96dcff7ece 100644 --- a/src/vcpkg.cpp +++ b/src/vcpkg.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -135,6 +136,12 @@ namespace void inner(const Filesystem& fs, const VcpkgCmdArguments& args, const BundleSettings& bundle) { + // Ensure that we call curl_global_init only once in the program. + if (CURLE_OK != curl_global_init_status()) + { + Debug::println("Failed to initialize CURL"); + } + // track version on each invocation get_global_metrics_collector().track_string(StringMetric::VcpkgVersion, vcpkg_executable_version); diff --git a/src/vcpkg/base/curl.cpp b/src/vcpkg/base/curl.cpp new file mode 100644 index 0000000000..532a5d3989 --- /dev/null +++ b/src/vcpkg/base/curl.cpp @@ -0,0 +1,26 @@ +#include + +namespace vcpkg +{ + struct CurlGlobalInit + { + CurlGlobalInit() : init_status(curl_global_init(CURL_GLOBAL_DEFAULT)) { } + ~CurlGlobalInit() { curl_global_cleanup(); } + + CurlGlobalInit(const CurlGlobalInit&) = delete; + CurlGlobalInit(CurlGlobalInit&&) = delete; + CurlGlobalInit& operator=(const CurlGlobalInit&) = delete; + CurlGlobalInit& operator=(CurlGlobalInit&&) = delete; + + CURLcode get_init_status() const { return init_status; } + + private: + CURLcode init_status; + }; + + CURLcode curl_global_init_status() noexcept + { + static CurlGlobalInit g_curl_global_init; + return g_curl_global_init.get_init_status(); + } +} diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 8d60b52bcf..1b8afff88d 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -24,16 +24,16 @@ using namespace vcpkg; namespace { - constexpr StringLiteral vcpkg_curl_user_agent_header = - "User-Agent: vcpkg/" VCPKG_BASE_VERSION_AS_STRING "-" VCPKG_VERSION_AS_STRING " (curl)"; + constexpr StringLiteral vcpkg_curl_user_agent = + "vcpkg/" VCPKG_BASE_VERSION_AS_STRING "-" VCPKG_VERSION_AS_STRING " (curl)"; - void add_curl_headers(Command& cmd, View headers) + void set_common_curl_options(CURL* handle, const char* url, curl_slist* request_headers) { - cmd.string_arg("-H").string_arg(vcpkg_curl_user_agent_header); - for (auto&& header : headers) - { - cmd.string_arg("-H").string_arg(header); - } + curl_easy_setopt(handle, CURLOPT_USERAGENT, vcpkg_curl_user_agent.c_str()); + curl_easy_setopt(handle, CURLOPT_URL, url); + curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 2L); // CURLFOLLOW_OBEYCODE + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, request_headers); + curl_easy_setopt(handle, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); // don't send headers to proxy CONNECT } } @@ -673,90 +673,155 @@ namespace vcpkg return true; } - static std::vector curl_bulk_operation(DiagnosticContext& context, - View operation_args, - StringLiteral prefixArgs, - View headers, - View secrets) + struct CurlRequestPrivateData { -#define GUID_MARKER "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c" - static constexpr StringLiteral guid_marker = GUID_MARKER; - // TODO: Replace with libcurl code. - Command prefix_cmd{"curl"}; - if (!prefixArgs.empty()) + size_t request_index = 0; + std::unique_ptr file = nullptr; + }; + static size_t write_file_callback(void* contents, size_t size, size_t nmemb, void* param) + { + auto* file = reinterpret_cast(param); + if (!file) return 0; + return file->write(contents, size, nmemb); + } + + static std::vector libcurl_bulk_operation(DiagnosticContext& context, + View urls, + View outputs, + View headers, + View secrets) + { + // TODO: handle secret replacement when error messages are implemented + (void)secrets; + + if (!outputs.empty() && outputs.size() != urls.size()) return {}; + + if (vcpkg::curl_global_init_status() != CURLE_OK) Checks::unreachable(VCPKG_LINE_INFO); + + CURLM* multi_handle = curl_multi_init(); + if (!multi_handle) Checks::unreachable(VCPKG_LINE_INFO); + + std::vector ret(urls.size(), -1); + std::vector private_data; + private_data.reserve(urls.size()); + + curl_slist* request_headers = nullptr; + for (auto&& header : headers) { - prefix_cmd.raw_arg(prefixArgs); + request_headers = curl_slist_append(request_headers, header.c_str()); } - prefix_cmd.string_arg("--retry").string_arg("3").string_arg("-L").string_arg("-sS").string_arg("-w").string_arg( - GUID_MARKER "%{http_code} %{exitcode} %{errormsg}\\n"); -#undef GUID_MARKER - - std::vector ret; - ret.reserve(operation_args.size()); - add_curl_headers(prefix_cmd, headers); - while (ret.size() != operation_args.size()) + size_t skipped = 0; + for (size_t request_index = 0; request_index < urls.size(); ++request_index) { - // there's an edge case that we aren't handling here where not even one operation fits with the configured - // headers but this seems unlikely + auto& data = private_data.emplace_back(CurlRequestPrivateData{request_index}); + const auto& url = urls[request_index]; - // form a maximum length command line of operations: - auto batch_cmd = prefix_cmd; - size_t last_try_op = ret.size(); - while (last_try_op != operation_args.size() && batch_cmd.try_append(operation_args[last_try_op])) + CURL* curl = curl_easy_init(); + if (!curl) { - ++last_try_op; + context.report_error( + msgCurlFailedGeneric, msg::exit_code = -1, msg::error_msg = "curl_easy_init failed"); + ret[request_index] = CURLE_FAILED_INIT; + skipped++; + continue; } - // actually run curl - bool new_curl_seen = false; - std::vector debug_lines; - auto maybe_this_batch_exit_code = cmd_execute_and_stream_lines(context, batch_cmd, [&](StringView line) { - debug_lines.emplace_back(line.data(), line.size()); - new_curl_seen |= parse_curl_status_line(context, ret, guid_marker, line); - }); - - if (auto this_batch_exit_code = maybe_this_batch_exit_code.get()) + set_common_curl_options(curl, url.c_str(), request_headers); + curl_easy_setopt(curl, CURLOPT_PRIVATE, &data); + if (outputs.size() > request_index) { - if (!new_curl_seen) + const auto& output = outputs[request_index]; + + std::error_code ec; + data.file.reset(new WriteFilePointer(output, Append::NO, ec)); + if (ec) { - // old version of curl, we only have the result code for the last operation - context.report_error(msgCurlFailedGeneric, msg::exit_code = *this_batch_exit_code); + context.report_error(format_filesystem_call_error(ec, "fopen", {output})); } - - if (ret.size() != last_try_op) + else { - // curl didn't process everything we asked of it; this usually means curl crashed - auto command_line = std::move(batch_cmd).extract(); - replace_secrets(command_line, secrets); - context.report_error_with_log(Strings::join("\n", debug_lines), - msgCurlFailedToReturnExpectedNumberOfExitCodes, - msg::exit_code = *this_batch_exit_code, - msg::command_line = command_line); - return ret; + curl_easy_setopt(curl, CURLOPT_WRITEDATA, data.file.get()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_file_callback); } } - else + curl_multi_add_handle(multi_handle, curl); + } + + int still_running = 0; + do + { + CURLMcode mc = curl_multi_perform(multi_handle, &still_running); + if (mc != CURLM_OK) { - // couldn't even launch curl, record this as the last fatal error and give up - return ret; + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(mc), + msg::error_msg = curl_multi_strerror(mc))); } - } + + mc = curl_multi_poll(multi_handle, nullptr, 0, 1000, nullptr); + if (mc != CURLM_OK) + { + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(mc), + msg::error_msg = curl_multi_strerror(mc))); + } + } while (still_running); + + int messages_in_queue = 0; + size_t processed = 0; + do + { + while (auto* msg = curl_multi_info_read(multi_handle, &messages_in_queue)) + { + if (msg->msg == CURLMSG_DONE) + { + ++processed; + CURL* handle = msg->easy_handle; + + if (msg->data.result == CURLE_OK) + { + CurlRequestPrivateData* data = nullptr; + curl_easy_getinfo(handle, CURLINFO_PRIVATE, &data); + if (!data) Checks::unreachable(VCPKG_LINE_INFO); + + auto idx = data->request_index; + long response_code = -1; + curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &response_code); + ret[idx] = static_cast(response_code); + } + else + { + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(msg->data.result), + msg::error_msg = curl_easy_strerror(msg->data.result))); + } + curl_multi_remove_handle(multi_handle, handle); + curl_easy_cleanup(handle); + } + } + } while (processed + skipped < urls.size()); + + curl_slist_free_all(request_headers); + curl_multi_cleanup(multi_handle); return ret; } + static std::vector libcurl_bulk_check(DiagnosticContext& context, + View urls, + View headers, + View secrets) + { + return libcurl_bulk_operation(context, urls, {}, headers, secrets); + } + std::vector url_heads(DiagnosticContext& context, View urls, View headers, View secrets) { - return curl_bulk_operation( - context, - Util::fmap(urls, [](const std::string& url) { return Command{}.string_arg(url_encode_spaces(url)); }), - "--head", - headers, - secrets); + return libcurl_bulk_check(context, urls, headers, secrets); } std::vector download_files_no_cache(DiagnosticContext& context, @@ -764,17 +829,11 @@ namespace vcpkg View headers, View secrets) { - return curl_bulk_operation(context, - Util::fmap(url_pairs, - [](const std::pair& url_pair) { - return Command{} - .string_arg(url_encode_spaces(url_pair.first)) - .string_arg("-o") - .string_arg(url_pair.second); - }), - "--create-dirs", - headers, - secrets); + return libcurl_bulk_operation(context, + Util::fmap(url_pairs, [](auto&& kv) -> std::string { return kv.first; }), + Util::fmap(url_pairs, [](auto&& kv) -> Path { return kv.second; }), + headers, + secrets); } bool submit_github_dependency_graph_snapshot(DiagnosticContext& context, @@ -783,8 +842,6 @@ namespace vcpkg const std::string& github_repository, const Json::Object& snapshot) { - static constexpr StringLiteral guid_marker = "fcfad8a3-bb68-4a54-ad00-dab1ff671ed2"; - std::string uri; if (auto github_server_url = maybe_github_server_url.get()) { @@ -799,37 +856,50 @@ namespace vcpkg fmt::format_to( std::back_inserter(uri), "/repos/{}/dependency-graph/snapshots", url_encode_spaces(github_repository)); - auto cmd = Command{"curl"}; - cmd.string_arg("-w").string_arg("\\n" + guid_marker.to_string() + "%{http_code}"); - cmd.string_arg("-X").string_arg("POST"); + CURL* curl = curl_easy_init(); + if (!curl) { - std::string headers[] = { - "Accept: application/vnd.github+json", - "Authorization: Bearer " + github_token, - "X-GitHub-Api-Version: 2022-11-28", - }; - add_curl_headers(cmd, headers); + context.report_error( + msg::format(msgCurlFailedGeneric, msg::exit_code = -1, msg::error_msg = "curl_easy_init failed")); + return false; } - cmd.string_arg(uri); - cmd.string_arg("-d").string_arg("@-"); + std::string post_data = Json::stringify(snapshot); - RedirectedProcessLaunchSettings settings; - settings.stdin_content = Json::stringify(snapshot); - int code = 0; - auto result = cmd_execute_and_stream_lines(context, cmd, settings, [&code](StringView line) { - if (line.starts_with(guid_marker)) - { - code = std::strtol(line.data() + guid_marker.size(), nullptr, 10); - } - }); + curl_slist* request_headers = nullptr; + request_headers = curl_slist_append(request_headers, "Accept: application/vnd.github+json"); + request_headers = curl_slist_append(request_headers, ("Authorization: Bearer " + github_token).c_str()); + request_headers = curl_slist_append(request_headers, "X-GitHub-Api-Version: 2022-11-28"); + request_headers = curl_slist_append(request_headers, "Content-Type: application/json"); + + set_common_curl_options(curl, uri.c_str(), request_headers); + curl_easy_setopt(curl, CURLOPT_USERAGENT, vcpkg_curl_user_agent.data()); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post_data.length()); + + CURLcode result = curl_easy_perform(curl); + long response_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - auto r = result.get(); - if (r && *r == 0 && code >= 200 && code < 300) + curl_slist_free_all(request_headers); + curl_easy_cleanup(curl); + + if (result != CURLE_OK) { - return true; + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(result), + msg::error_msg = curl_easy_strerror(result))); + return false; } - return false; + + return response_code >= 200 && response_code < 300; + } + + static size_t read_file_callback(char* buffer, size_t size, size_t nitems, void* param) + { + auto* file = static_cast(param); + return file->read(buffer, size, nitems); } bool store_to_asset_cache(DiagnosticContext& context, @@ -839,56 +909,64 @@ namespace vcpkg View headers, const Path& file) { - static constexpr StringLiteral guid_marker = "9a1db05f-a65d-419b-aa72-037fb4d0672e"; + (void)method; - if (raw_url.starts_with("ftp://")) + std::error_code ec; + auto fileptr = std::make_unique(file, ec); + if (ec) { - // HTTP headers are ignored for FTP clients - auto ftp_cmd = Command{"curl"}; - ftp_cmd.string_arg(url_encode_spaces(raw_url)); - ftp_cmd.string_arg("-T").string_arg(file); - auto maybe_res = cmd_execute_and_capture_output(context, ftp_cmd); - if (auto res = maybe_res.get()) - { - if (res->exit_code == 0) - { - return true; - } + context.report_error(format_filesystem_call_error(ec, "fopen", {file})); + return false; + } + auto file_size = fileptr->size(VCPKG_LINE_INFO); - context.report_error_with_log( - res->output, msgCurlFailedToPut, msg::exit_code = res->exit_code, msg::url = sanitized_url); - return false; - } + CURL* curl = curl_easy_init(); + if (!curl) Checks::unreachable(VCPKG_LINE_INFO); - return false; + curl_slist* request_headers = nullptr; + if (!raw_url.starts_with("ftp://")) + { + for (auto&& header : headers) + request_headers = curl_slist_append(request_headers, header.c_str()); } - auto http_cmd = Command{"curl"}.string_arg("-X").string_arg(method); - add_curl_headers(http_cmd, headers); - http_cmd.string_arg("-w").string_arg("\\n" + guid_marker.to_string() + "%{http_code}"); - http_cmd.string_arg(raw_url); - http_cmd.string_arg("-T").string_arg(file); - int code = 0; - auto res = cmd_execute_and_stream_lines(context, http_cmd, [&code](StringView line) { - if (line.starts_with(guid_marker)) - { - code = std::strtol(line.data() + guid_marker.size(), nullptr, 10); - } - }); + auto upload_url = url_encode_spaces(raw_url); + curl_easy_setopt(curl, CURLOPT_USERAGENT, vcpkg_curl_user_agent.data()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, request_headers); + curl_easy_setopt(curl, CURLOPT_URL, upload_url.c_str()); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_READDATA, fileptr.get()); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, &read_file_callback); + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, static_cast(file_size)); - auto pres = res.get(); - if (!pres) + auto result = curl_easy_perform(curl); + if (result != CURLE_OK) { + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(result), + msg::error_msg = curl_easy_strerror(result))); + curl_easy_cleanup(curl); + curl_slist_free_all(request_headers); return false; } - if (*pres != 0 || (code >= 100 && code < 200) || code >= 300) + long response_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + if ((response_code >= 100 && response_code < 200) || response_code >= 300) { - context.report_error(msg::format( - msgCurlFailedToPutHttp, msg::exit_code = *pres, msg::url = sanitized_url, msg::value = code)); + context.report_error(msg::format(msgCurlFailedToPutHttp, + msg::exit_code = static_cast(result), + msg::error_msg = curl_easy_strerror(result), + msg::url = sanitized_url, + msg::value = response_code)); + curl_easy_cleanup(curl); + curl_slist_free_all(request_headers); return false; } + curl_easy_cleanup(curl); + curl_slist_free_all(request_headers); return true; } @@ -939,34 +1017,6 @@ namespace vcpkg return fmt::format(FMT_COMPILE("{}?{}"), base_url, fmt::join(query_params, "&")); } - Optional invoke_http_request(DiagnosticContext& context, - StringLiteral method, - View headers, - StringView raw_url, - View secrets, - StringView data) - { - auto cmd = Command{"curl"}.string_arg("-s").string_arg("-L"); - add_curl_headers(cmd, headers); - - cmd.string_arg("-X").string_arg(method); - - if (!data.empty()) - { - cmd.string_arg("--data-raw").string_arg(data); - } - - cmd.string_arg(url_encode_spaces(raw_url)); - - auto maybe_output = cmd_execute_and_capture_output(context, cmd); - if (auto output = check_zero_exit_code(context, cmd, maybe_output, secrets)) - { - return *output; - } - - return nullopt; - } - #if defined(_WIN32) static WinHttpTrialResult download_winhttp_trial(DiagnosticContext& context, MessageSink& machine_readable_progress, @@ -1213,84 +1263,94 @@ namespace vcpkg fs.create_directories(dir, VCPKG_LINE_INFO); } - auto cmd = Command{"curl"} - .string_arg("--fail") - .string_arg("--retry") - .string_arg("3") - .string_arg("-L") - .string_arg(url_encode_spaces(raw_url)) - .string_arg("--create-dirs") - .string_arg("--output") - .string_arg(download_path_part_path); - add_curl_headers(cmd, headers); - bool seen_any_curl_errors = false; - // if seen_any_curl_errors, contains the curl error lines starting with "curl:" - // otherwise, contains all curl's output unless it is the machine readable output - std::vector likely_curl_errors; - auto maybe_exit_code = cmd_execute_and_stream_lines(context, cmd, [&](StringView line) { - const auto maybe_parsed = try_parse_curl_progress_data(line); - if (const auto parsed = maybe_parsed.get()) - { - machine_readable_progress.println(Color::none, - LocalizedString::from_raw(fmt::format("{}%", parsed->total_percent))); - return; - } - - static constexpr StringLiteral WarningColon = "warning: "; - if (Strings::case_insensitive_ascii_starts_with(line, WarningColon)) - { - context.statusln( - DiagnosticLine{DiagKind::Warning, LocalizedString::from_raw(line.substr(WarningColon.size()))} - .to_message_line()); - return; - } + std::error_code ec; + auto fileptr = std::make_unique(download_path_part_path, Append::NO, ec); + if (ec) + { + context.report_error(format_filesystem_call_error(ec, "fopen", {download_path_part_path})); + return DownloadPrognosis::OtherError; + } - // clang-format off - // example: - // 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: nonexistent.example.com - // clang-format on - static constexpr StringLiteral CurlColon = "curl:"; - auto curl_start = std::search(line.begin(), line.end(), CurlColon.begin(), CurlColon.end()); - if (curl_start == line.end()) - { - if (seen_any_curl_errors) + curl_slist* request_headers = nullptr; + for (auto&& header : headers) + request_headers = curl_slist_append(request_headers, header.c_str()); + + auto curl = curl_easy_init(); + if (!curl) Checks::unreachable(VCPKG_LINE_INFO); + + set_common_curl_options(curl, url_encode_spaces(raw_url).c_str(), request_headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_file_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fileptr.get()); + // TODO: Add progress + (void)machine_readable_progress; + + // Retry on transient errors: + // Transient error means either: a timeout, an FTP 4xx response code or an HTTP 408, 429, 500, 502, 503 or 504 + // response code. + bool curl_success = false; + bool should_retry = true; + size_t retries_count = 0; + + using namespace std::chrono_literals; + static constexpr std::array retry_delay = {0s, 1s, 2s}; + do + { + // blocking transfer + should_retry = false; + std::this_thread::sleep_for(retry_delay[retries_count++]); + auto curl_code = curl_easy_perform(curl); + if (curl_code == CURLE_OK) + { + long response_code = -1; + if (CURLE_OK == curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code)) { - return; + if ((response_code >= 200 && response_code < 300) || response_code == 0) + { + curl_success = true; + break; + } + else if (response_code == 429 || response_code == 408 || response_code == 500 || + response_code == 502 || response_code == 503 || response_code == 504) + { + should_retry = true; + context.report_error(msg::format(msgCurlFailedHttpResponseWithRetry, + msg::exit_code = static_cast(curl_code), + msg::count = retries_count, + msg::value = retry_delay.size())); + } + else + { + context.report_error( + msg::format(msgCurlFailedHttpResponse, msg::exit_code = static_cast(curl_code))); + } } - - curl_start = line.begin(); } else { - if (!seen_any_curl_errors) + if (curl_code == CURLE_OPERATION_TIMEDOUT) { - seen_any_curl_errors = true; - likely_curl_errors.clear(); + should_retry = true; + context.report_error(msg::format(msgCurlFailedGenericWithRetry, + msg::exit_code = static_cast(curl_code), + msg::error_msg = curl_easy_strerror(curl_code), + msg::count = retries_count, + msg::value = retry_delay.size())); } - } - - likely_curl_errors.emplace_back(curl_start, line.end()); - }); - - const auto exit_code = maybe_exit_code.get(); - if (!exit_code) - { - return DownloadPrognosis::OtherError; - } - - if (*exit_code != 0) - { - std::set seen_errors; - for (StringView likely_curl_error : likely_curl_errors) - { - auto seen_position = seen_errors.lower_bound(likely_curl_error); - if (seen_position == seen_errors.end() || *seen_position != likely_curl_error) + else { - seen_errors.emplace_hint(seen_position, likely_curl_error); - context.report(DiagnosticLine{DiagKind::Error, LocalizedString::from_raw(likely_curl_error)}); + context.report_error(msg::format(msgCurlFailedGeneric, + msg::exit_code = static_cast(curl_code), + msg::error_msg = curl_easy_strerror(curl_code))); } } + } while (should_retry && retries_count < retry_delay.size()); + + curl_easy_cleanup(curl); + curl_slist_free_all(request_headers); + fileptr.reset(); + if (!curl_success) + { return DownloadPrognosis::NetworkErrorProxyMightHelp; } @@ -1309,89 +1369,6 @@ namespace vcpkg return s_headers; } - bool parse_curl_status_line(DiagnosticContext& context, - std::vector& http_codes, - StringLiteral prefix, - StringView this_line) - { - if (!this_line.starts_with(prefix)) - { - return false; - } - - auto first = this_line.begin(); - const auto last = this_line.end(); - first += prefix.size(); - const auto first_http_code = first; - - int http_code; - for (;; ++first) - { - if (first == last) - { - // this output is broken, even if we don't know %{exit_code} or ${errormsg}, the spaces in front - // of them should still be printed. - return false; - } - - if (!ParserBase::is_ascii_digit(*first)) - { - http_code = Strings::strto(StringView{first_http_code, first}).value_or_exit(VCPKG_LINE_INFO); - break; - } - } - - if (*first != ' ' || ++first == last) - { - // didn't see the space after the http_code - return false; - } - - if (*first == ' ') - { - // old curl that doesn't understand %{exit_code}, this is the space after it - http_codes.emplace_back(http_code); - return false; - } - - if (!ParserBase::is_ascii_digit(*first)) - { - // not exit_code - return false; - } - - const auto first_exit_code = first; - for (;;) - { - if (++first == last) - { - // didn't see the space after %{exit_code} - return false; - } - - if (*first == ' ') - { - // the space after exit_code, everything after this space is the error message if any - http_codes.emplace_back(http_code); - auto exit_code = Strings::strto(StringView{first_exit_code, first}).value_or_exit(VCPKG_LINE_INFO); - // note that this gets the space out of the output :) - if (exit_code != 0) - { - context.report_error(msg::format(msgCurlFailedGeneric, msg::exit_code = exit_code) - .append_raw(StringView{first, last})); - } - - return true; - } - - if (!ParserBase::is_ascii_digit(*first)) - { - // non numeric exit_code? - return false; - } - } - } - static DownloadPrognosis download_file_azurl_asset_cache(DiagnosticContext& context, MessageSink& machine_readable_progress, const AssetCachingSettings& asset_cache_settings, diff --git a/src/vcpkg/base/files.cpp b/src/vcpkg/base/files.cpp index 9d199ad43a..78e3466266 100644 --- a/src/vcpkg/base/files.cpp +++ b/src/vcpkg/base/files.cpp @@ -1557,6 +1557,35 @@ namespace vcpkg ec.clear(); } + uint64_t ReadFilePointer::size(LineInfo li) const + { + std::error_code ec; + auto result = this->size(ec); + if (ec) + { + exit_filesystem_call_error(li, ec, __func__, {m_path}); + } + + return result; + } + + uint64_t ReadFilePointer::size(std::error_code& ec) const + { + ec.clear(); +#if _WIN32 + return stdfs::file_size(to_stdfs_path(m_path), ec); +#else + struct stat st; + if (::fstat(::fileno(m_fs), &st) != 0) + { + ec.assign(errno, std::generic_category()); + return 0; + } + + return st.st_size; +#endif + } + WriteFilePointer::WriteFilePointer() noexcept = default; WriteFilePointer::WriteFilePointer(WriteFilePointer&&) noexcept = default; diff --git a/src/vcpkg/commands.cpp b/src/vcpkg/commands.cpp index 29430906b1..a90862b4fb 100644 --- a/src/vcpkg/commands.cpp +++ b/src/vcpkg/commands.cpp @@ -70,8 +70,8 @@ namespace vcpkg {CommandCheckToolsShaMetadata, command_check_tools_sha_and_exit}, {CommandInitRegistryMetadata, command_init_registry_and_exit}, {CommandVersionMetadata, command_version_and_exit}, -#if defined(_WIN32) {CommandZUploadMetricsMetadata, command_z_upload_metrics_and_exit}, +#if defined(_WIN32) {CommandZApplocalMetadata, command_z_applocal_and_exit}, #endif // defined(_WIN32) {CommandZGenerateDefaultMessageMapMetadata, command_z_generate_default_message_map_and_exit}, diff --git a/src/vcpkg/commands.z-check-tools-sha.cpp b/src/vcpkg/commands.z-check-tools-sha.cpp index 0356b3615a..309d69069f 100644 --- a/src/vcpkg/commands.z-check-tools-sha.cpp +++ b/src/vcpkg/commands.z-check-tools-sha.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -106,7 +107,7 @@ namespace vcpkg ++http_codes_iter; } - if (!has_sha_error) + if (!has_http_error && !has_sha_error) { msg::println(msgAllShasValid); } diff --git a/src/vcpkg/commands.z-upload-metrics.cpp b/src/vcpkg/commands.z-upload-metrics.cpp index 21dcbd1ab5..c68ae2e33a 100644 --- a/src/vcpkg/commands.z-upload-metrics.cpp +++ b/src/vcpkg/commands.z-upload-metrics.cpp @@ -1,14 +1,17 @@ -#include - -#if defined(_WIN32) #include +#include #include +#include #include #include namespace vcpkg { + constexpr CommandSwitch UPLOAD_SWITCHES[] = { + {SwitchDeleteFileAfterUpload, msgCmdUploadMetricsDeleteFileAfterUpload}, + }; + constexpr CommandMetadata CommandZUploadMetricsMetadata{ "z-upload-metrics", {/*intentionally undocumented*/}, @@ -17,7 +20,7 @@ namespace vcpkg AutocompletePriority::Never, 1, 1, - {}, + {UPLOAD_SWITCHES}, nullptr, }; @@ -26,8 +29,25 @@ namespace vcpkg const auto parsed = args.parse_arguments(CommandZUploadMetricsMetadata); const auto& payload_path = parsed.command_arguments[0]; auto payload = fs.read_contents(payload_path, VCPKG_LINE_INFO); - winhttp_upload_metrics(payload); + auto success = curl_upload_metrics(payload); + if (success) + { + if (parsed.switches.find(SwitchDeleteFileAfterUpload) != parsed.switches.end()) + { + std::error_code ec; + fs.remove(payload_path, ec); +#ifndef NDEBUG + if (ec) fprintf(stderr, "[DEBUG] Failed to remove file after upload: %s\n", ec.message().c_str()); +#endif // NDEBUG + } + } +#ifndef NDEBUG + else + { + fprintf(stderr, "[DEBUG] Failed to upload metrics\n"); + } +#endif // NDEBUG + Checks::exit_success(VCPKG_LINE_INFO); } } -#endif // defined(_WIN32) diff --git a/src/vcpkg/metrics.cpp b/src/vcpkg/metrics.cpp index ee561ed962..b25fd4ae53 100644 --- a/src/vcpkg/metrics.cpp +++ b/src/vcpkg/metrics.cpp @@ -478,99 +478,6 @@ namespace vcpkg std::atomic g_should_print_metrics = false; std::atomic g_metrics_enabled = false; -#if defined(_WIN32) - void winhttp_upload_metrics(StringView payload) - { - HINTERNET connect = nullptr, request = nullptr; - BOOL results = FALSE; - - const HINTERNET session = WinHttpOpen( - L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - - unsigned long secure_protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; - if (session && WinHttpSetOption(session, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(DWORD))) - { - connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); - } - - if (connect) - { - request = WinHttpOpenRequest(connect, - L"POST", - L"/v2/track", - nullptr, - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, - WINHTTP_FLAG_SECURE); - } - - if (request) - { - auto mutable_payload = payload.to_string(); - if (MAXDWORD <= mutable_payload.size()) abort(); - std::wstring hdrs = L"Content-Type: application/json\r\n"; - results = WinHttpSendRequest(request, - hdrs.c_str(), - static_cast(hdrs.size()), - static_cast(mutable_payload.data()), - static_cast(mutable_payload.size()), - static_cast(mutable_payload.size()), - 0); - } - - if (results) - { - results = WinHttpReceiveResponse(request, nullptr); - } - - DWORD http_code = 0, junk = sizeof(DWORD); - - if (results) - { - results = WinHttpQueryHeaders(request, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - nullptr, - &http_code, - &junk, - WINHTTP_NO_HEADER_INDEX); - } - - std::vector response_buffer; - if (results) - { - DWORD available_data = 0, read_data = 0, total_data = 0; - while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) - { - response_buffer.resize(response_buffer.size() + available_data); - - results = WinHttpReadData(request, &response_buffer[total_data], available_data, &read_data); - - if (!results) - { - break; - } - - total_data += read_data; - - response_buffer.resize(total_data); - } - } - - if (!results) - { -#ifndef NDEBUG - __debugbreak(); - auto err = GetLastError(); - fprintf(stderr, "[DEBUG] failed to connect to server: %08lu\n", err); -#endif // NDEBUG - } - - if (request) WinHttpCloseHandle(request); - if (connect) WinHttpCloseHandle(connect); - if (session) WinHttpCloseHandle(session); - } -#endif // ^^^ _WIN32 - void flush_global_metrics(const Filesystem& fs) { if (!g_metrics_enabled.load()) @@ -609,33 +516,105 @@ namespace vcpkg fs.write_contents(vcpkg_metrics_txt_path, payload, ec); if (ec) return; -#if defined(_WIN32) - const Path temp_folder_path_exe = temp_folder_path / "vcpkg-" VCPKG_BASE_VERSION_AS_STRING ".exe"; + const StringLiteral executableExtension = +#if defined(WIN32) + ".exe" +#else + "" +#endif + ; + + const Path temp_folder_path_exe = + temp_folder_path / "vcpkg-" VCPKG_BASE_VERSION_AS_STRING + executableExtension; fs.copy_file(get_exe_path_of_current_process(), temp_folder_path_exe, CopyOptions::skip_existing, ec); if (ec) return; + Command builder; builder.string_arg(temp_folder_path_exe); builder.string_arg("z-upload-metrics"); builder.string_arg(vcpkg_metrics_txt_path); + builder.string_arg("--delete-file-after-upload"); cmd_execute_background(builder); -#else - // TODO: replace with libcurl code - cmd_execute_background(Command("curl") - .string_arg("https://dc.services.visualstudio.com/v2/track") - .string_arg("--max-time") - .string_arg("60") - .string_arg("-H") - .string_arg("Content-Type: application/json") - .string_arg("-X") - .string_arg("POST") - .string_arg("--tlsv1.2") - .string_arg("--data") - .string_arg(Strings::concat("@", vcpkg_metrics_txt_path)) - .raw_arg(">/dev/null") - .raw_arg("2>&1") - .raw_arg(";") - .string_arg("rm") - .string_arg(vcpkg_metrics_txt_path)); -#endif + } + + static size_t string_append_cb(void* buff, size_t size, size_t nmemb, void* param) + { + auto* str = reinterpret_cast(param); + if (!str || !buff) return 0; + if (size != 1) return 0; + str->append(reinterpret_cast(buff), nmemb); + return size * nmemb; + } + + static bool parse_metrics_response(StringView body) + { + auto maybe_json = Json::parse_object(body, "metrics_response"); + auto json = maybe_json.get(); + if (!json) return false; + + auto maybe_received = json->get("itemsReceived"); + auto maybe_accepted = json->get("itemsAccepted"); + auto maybe_errors = json->get("errors"); + + if (maybe_received && maybe_accepted && maybe_errors && maybe_received->is_integer() && + maybe_accepted->is_integer() && maybe_errors->is_array()) + { + auto item_received = maybe_received->integer(VCPKG_LINE_INFO); + auto item_accepted = maybe_accepted->integer(VCPKG_LINE_INFO); + auto errors = maybe_errors->array(VCPKG_LINE_INFO); + return (errors.size() == 0) && (item_received == item_accepted); + } + Debug::println("Metrics response has unexpected format"); + return false; + } + + bool curl_upload_metrics(StringView payload) + { + CURL* curl = curl_easy_init(); + if (!curl) + { + Debug::println("Failed to initialize curl"); + return false; + } + + curl_slist* headers = nullptr; + headers = curl_slist_append(headers, "Content-Type: application/json"); + + auto mutable_payload = payload.to_string(); + + curl_easy_setopt(curl, CURLOPT_URL, "https://dc.services.visualstudio.com/v2/track"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, mutable_payload.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast(mutable_payload.length())); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // CURLFOLLOW_ALL + curl_easy_setopt(curl, CURLOPT_USERAGENT, "vcpkg/1.0"); + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + auto buff = std::make_unique(); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, buff.get()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &string_append_cb); + + long response_code = 0; + CURLcode res = curl_easy_perform(curl); + bool is_success = false; + if (res == CURLE_OK) + { + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + Debug::println(fmt::format("Metrics upload response code: {}", response_code)); + Debug::println("Metrics upload response body: ", *buff); + if (response_code == 200) + { + is_success = parse_metrics_response(*buff); + } + } + else + { + Debug::println("Metrics upload failed: ", curl_easy_strerror(res)); + } + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + return is_success; } } From f5a89c7cf84a898abfb267f74080c4cbee2f6be6 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Tue, 2 Sep 2025 21:04:36 +0000 Subject: [PATCH 03/30] Fix FindLibCURL for builds wihthout network access --- cmake/FindLibCURL.cmake | 108 ++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/cmake/FindLibCURL.cmake b/cmake/FindLibCURL.cmake index c59ab810ba..4614d8fc80 100644 --- a/cmake/FindLibCURL.cmake +++ b/cmake/FindLibCURL.cmake @@ -4,6 +4,15 @@ else() option(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL "Use an external version of the libcurl library" ON) endif() +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + +if (VCPKG_DEPENDENCY_EXTERNAL_LIBCURL) + find_package(CURL REQUIRED) + return() +endif() + # This option exists to allow the URI to be replaced with a Microsoft-internal URI in official # builds which have restricted internet access; see azure-pipelines/signing.yml # Note that the SHA512 is the same, so vcpkg-tool contributors need not be concerned that we built @@ -12,10 +21,6 @@ if(NOT VCPKG_LIBCURL_URL) set(VCPKG_LIBCURL_URL "https://github.com/curl/curl/archive/refs/tags/curl-8_8_0.tar.gz") endif() -if(POLICY CMP0135) - cmake_policy(SET CMP0135 NEW) -endif() - include(FetchContent) FetchContent_Declare( LibCURL @@ -27,56 +32,53 @@ if(NOT LibCURL_FIND_REQUIRED) message(FATAL_ERROR "LibCURL must be REQUIRED") endif() -if(VCPKG_DEPENDENCY_EXTERNAL_LIBCURL) - find_package(CURL REQUIRED) -else() - function(get_libcurl) - set(BUILD_SHARED_LIBS OFF) - set(BUILD_CURL_EXE OFF) - set(CURL_ENABLE_EXPORT_TARGET OFF) - set(ENABLE_UNICODE ON) - set(BUILD_LIBCURL_DOCS OFF) - set(BUILD_MISC_DOCS OFF) - set(ENABLE_CURL_MANUAL OFF) - set(PICKY_COMPILER OFF) - set(CMAKE_DISABLE_FIND_PACKAGE_Perl ON) - set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON) - set(CMAKE_DISABLE_FIND_PACKAGE_LibPSL ON) - set(CMAKE_DISABLE_FIND_PACKAGE_LibSSH2 ON) - if(MSVC) # This is in function() so no need to backup the variables - string(APPEND CMAKE_C_FLAGS " /wd6101") - string(APPEND CMAKE_C_FLAGS " /wd6011") - string(APPEND CMAKE_C_FLAGS " /wd6054") - string(APPEND CMAKE_C_FLAGS " /wd6240") - string(APPEND CMAKE_C_FLAGS " /wd6239") - string(APPEND CMAKE_C_FLAGS " /wd6323") - string(APPEND CMAKE_C_FLAGS " /wd6387") - string(APPEND CMAKE_C_FLAGS " /wd28182") - string(APPEND CMAKE_C_FLAGS " /wd28183") - string(APPEND CMAKE_C_FLAGS " /wd28251") - string(APPEND CMAKE_C_FLAGS " /wd28301") - else() - string(APPEND CMAKE_C_FLAGS " -Wno-error") - endif() - if (WIN32) - set(CURL_USE_SCHANNEL ON) - endif() - FetchContent_MakeAvailable(LibCURL) - endfunction() +# This is in function() so no need to backup the variables +function(get_libcurl) + set(BUILD_SHARED_LIBS OFF) + set(BUILD_CURL_EXE OFF) + set(CURL_ENABLE_EXPORT_TARGET OFF) + set(ENABLE_UNICODE ON) + set(BUILD_LIBCURL_DOCS OFF) + set(BUILD_MISC_DOCS OFF) + set(ENABLE_CURL_MANUAL OFF) + set(PICKY_COMPILER OFF) + set(CMAKE_DISABLE_FIND_PACKAGE_Perl ON) + set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON) + set(CMAKE_DISABLE_FIND_PACKAGE_LibPSL ON) + set(CMAKE_DISABLE_FIND_PACKAGE_LibSSH2 ON) + if(MSVC) + string(APPEND CMAKE_C_FLAGS " /wd6101") + string(APPEND CMAKE_C_FLAGS " /wd6011") + string(APPEND CMAKE_C_FLAGS " /wd6054") + string(APPEND CMAKE_C_FLAGS " /wd6240") + string(APPEND CMAKE_C_FLAGS " /wd6239") + string(APPEND CMAKE_C_FLAGS " /wd6323") + string(APPEND CMAKE_C_FLAGS " /wd6387") + string(APPEND CMAKE_C_FLAGS " /wd28182") + string(APPEND CMAKE_C_FLAGS " /wd28183") + string(APPEND CMAKE_C_FLAGS " /wd28251") + string(APPEND CMAKE_C_FLAGS " /wd28301") + else() + string(APPEND CMAKE_C_FLAGS " -Wno-error") + endif() + if (WIN32) + set(CURL_USE_SCHANNEL ON) + endif() + FetchContent_MakeAvailable(LibCURL) +endfunction() + +get_libcurl() - get_libcurl() - - if(NOT TARGET CURL::libcurl) - if(TARGET libcurl_static) - add_library(CURL::libcurl ALIAS libcurl_static) - target_compile_definitions(libcurl_static INTERFACE CURL_STATICLIB) - elseif(TARGET libcurl) - add_library(CURL::libcurl ALIAS libcurl) - if(NOT BUILD_SHARED_LIBS) - target_compile_definitions(libcurl INTERFACE CURL_STATICLIB) - endif() - else() - message(FATAL_ERROR "After FetchContent_MakeAvailable(LibCURL) no suitable curl target (libcurl or libcurl_static) was found.") +if(NOT TARGET CURL::libcurl) + if(TARGET libcurl_static) + add_library(CURL::libcurl ALIAS libcurl_static) + target_compile_definitions(libcurl_static INTERFACE CURL_STATICLIB) + elseif(TARGET libcurl) + add_library(CURL::libcurl ALIAS libcurl) + if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(libcurl INTERFACE CURL_STATICLIB) endif() + else() + message(FATAL_ERROR "After FetchContent_MakeAvailable(LibCURL) no suitable curl target (libcurl or libcurl_static) was found.") endif() endif() From e7f40e17b55076fa49c3bbd1307ec03264a7dcb3 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Mon, 20 Oct 2025 20:01:26 +0000 Subject: [PATCH 04/30] Remove winHttp --- src/vcpkg/base/downloads.cpp | 182 ----------------------------------- 1 file changed, 182 deletions(-) diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 1b8afff88d..10542bb38d 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -1017,135 +1017,6 @@ namespace vcpkg return fmt::format(FMT_COMPILE("{}?{}"), base_url, fmt::join(query_params, "&")); } -#if defined(_WIN32) - static WinHttpTrialResult download_winhttp_trial(DiagnosticContext& context, - MessageSink& machine_readable_progress, - const Filesystem& fs, - const WinHttpSession& s, - const Path& download_path_part_path, - SplitUrlView split_uri_view, - StringView hostname, - INTERNET_PORT port, - const SanitizedUrl& sanitized_url) - { - WinHttpConnection conn; - if (!conn.connect(context, s, hostname, port, sanitized_url)) - { - return WinHttpTrialResult::retry; - } - - WinHttpRequest req; - if (!req.open( - context, conn, split_uri_view.path_query_fragment, sanitized_url, split_uri_view.scheme == "https")) - { - return WinHttpTrialResult::retry; - } - - auto maybe_status = req.query_status(context, sanitized_url); - const auto status = maybe_status.get(); - if (!status) - { - return WinHttpTrialResult::retry; - } - - if (*status < 200 || *status >= 300) - { - context.report_error(msgDownloadFailedStatusCode, msg::url = sanitized_url, msg::value = *status); - return WinHttpTrialResult::failed; - } - - return req.write_response_body(context, - machine_readable_progress, - sanitized_url, - fs.open_for_write(download_path_part_path, VCPKG_LINE_INFO)); - } - - /// - /// Download a file using WinHTTP -- only supports HTTP and HTTPS - /// - static bool download_winhttp(DiagnosticContext& context, - MessageSink& machine_readable_progress, - const Filesystem& fs, - const Path& download_path_part_path, - SplitUrlView split_url_view, - const SanitizedUrl& sanitized_url) - { - // `download_winhttp` does not support user or port syntax in authorities - auto hostname = split_url_view.authority.value_or_exit(VCPKG_LINE_INFO).substr(2); - INTERNET_PORT port; - if (split_url_view.scheme == "https") - { - port = INTERNET_DEFAULT_HTTPS_PORT; - } - else if (split_url_view.scheme == "http") - { - port = INTERNET_DEFAULT_HTTP_PORT; - } - else - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - // Make sure the directories are present, otherwise fopen_s fails - const auto dir = download_path_part_path.parent_path(); - if (!dir.empty()) - { - fs.create_directories(dir, VCPKG_LINE_INFO); - } - - WinHttpSession s; - if (!s.open(context, sanitized_url)) - { - return false; - } - - AttemptDiagnosticContext adc{context}; - switch (download_winhttp_trial(adc, - machine_readable_progress, - fs, - s, - download_path_part_path, - split_url_view, - hostname, - port, - sanitized_url)) - { - case WinHttpTrialResult::succeeded: adc.commit(); return true; - case WinHttpTrialResult::failed: adc.commit(); return false; - case WinHttpTrialResult::retry: break; - } - - for (size_t trials = 1; trials < 4; ++trials) - { - // 1s, 2s, 4s - const auto trialMs = 500 << trials; - adc.handle(); - context.statusln( - DiagnosticLine(DiagKind::Warning, - msg::format(msgDownloadFailedRetrying, msg::value = trialMs, msg::url = sanitized_url)) - .to_message_line()); - std::this_thread::sleep_for(std::chrono::milliseconds(trialMs)); - switch (download_winhttp_trial(adc, - machine_readable_progress, - fs, - s, - download_path_part_path, - split_url_view, - hostname, - port, - sanitized_url)) - { - case WinHttpTrialResult::succeeded: adc.commit(); return true; - case WinHttpTrialResult::failed: adc.commit(); return false; - case WinHttpTrialResult::retry: break; - } - } - - adc.commit(); - return false; - } -#endif - enum class DownloadPrognosis { Success, @@ -1203,59 +1074,6 @@ namespace vcpkg #endif download_path_part_path += ".part"; -#if defined(_WIN32) - auto maybe_https_proxy_env = get_environment_variable(EnvironmentVariableHttpsProxy); - bool needs_proxy_auth = false; - if (auto proxy_url = maybe_https_proxy_env.get()) - { - needs_proxy_auth = proxy_url->find('@') != std::string::npos; - } - if (headers.size() == 0 && !needs_proxy_auth) - { - auto maybe_split_uri_view = parse_split_url_view(raw_url); - auto split_uri_view = maybe_split_uri_view.get(); - if (!split_uri_view) - { - context.report_error(msgInvalidUri, msg::value = sanitized_url); - return DownloadPrognosis::OtherError; - } - - if (split_uri_view->scheme == "https" || split_uri_view->scheme == "http") - { - auto maybe_authority = split_uri_view->authority.get(); - if (!maybe_authority) - { - context.report_error(msg::format(msgInvalidUri, msg::value = sanitized_url)); - return DownloadPrognosis::OtherError; - } - - auto authority = StringView{*maybe_authority}.substr(2); - // This check causes complex URLs (non-default port, embedded basic auth) to be passed down to - // curl.exe - if (Strings::find_first_of(authority, ":@") == authority.end()) - { - if (!download_winhttp(context, - machine_readable_progress, - fs, - download_path_part_path, - *split_uri_view, - sanitized_url)) - { - return DownloadPrognosis::NetworkErrorProxyMightHelp; - } - - if (!check_downloaded_file_hash( - context, fs, sanitized_url, download_path_part_path, maybe_sha512, out_sha512)) - { - return DownloadPrognosis::OtherError; - } - - fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); - return DownloadPrognosis::Success; - } - } - } -#endif // Create directory in advance, otherwise curl will create it in 750 mode on unix style file systems. const auto dir = download_path_part_path.parent_path(); if (!dir.empty()) From da2529c3619ed22f2d16db2fa458b3cc63f13a23 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Mon, 20 Oct 2025 20:24:09 +0000 Subject: [PATCH 05/30] Restore progress function --- src/vcpkg/base/downloads.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 10542bb38d..b6522ce2bc 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -685,6 +685,21 @@ namespace vcpkg return file->write(contents, size, nmemb); } + static size_t progress_callback(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) + { + (void)ultotal; + (void)ulnow; + auto machine_readable_progress = static_cast(clientp); + + const double percent = (dlnow / dltotal) * 100.0; + machine_readable_progress->println(LocalizedString::from_raw(fmt::format("{:.2f}%", percent))); + return 0; + } + static std::vector libcurl_bulk_operation(DiagnosticContext& context, View urls, View outputs, @@ -1099,8 +1114,9 @@ namespace vcpkg set_common_curl_options(curl, url_encode_spaces(raw_url).c_str(), request_headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_file_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fileptr.get()); - // TODO: Add progress - (void)machine_readable_progress; + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); // enable progress reporting + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &progress_callback); + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &machine_readable_progress); // Retry on transient errors: // Transient error means either: a timeout, an FTP 4xx response code or an HTTP 408, 429, 500, 502, 503 or 504 From 286502244e6d384b96dbff5b0b45c53a3a89e87b Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Mon, 20 Oct 2025 20:34:47 +0000 Subject: [PATCH 06/30] Handle non-dl transfer progress --- src/vcpkg/base/downloads.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index b6522ce2bc..7b8d59b896 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -685,18 +685,17 @@ namespace vcpkg return file->write(contents, size, nmemb); } - static size_t progress_callback(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow) + static size_t progress_callback(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow) { (void)ultotal; (void)ulnow; auto machine_readable_progress = static_cast(clientp); - const double percent = (dlnow / dltotal) * 100.0; - machine_readable_progress->println(LocalizedString::from_raw(fmt::format("{:.2f}%", percent))); + if (dltotal > 0) + { + const double percent = (dlnow / dltotal) * 100.0; + machine_readable_progress->println(LocalizedString::from_raw(fmt::format("{:.2f}%", percent))); + } return 0; } @@ -1114,7 +1113,7 @@ namespace vcpkg set_common_curl_options(curl, url_encode_spaces(raw_url).c_str(), request_headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_file_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fileptr.get()); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); // enable progress reporting + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); // enable progress curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &progress_callback); curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &machine_readable_progress); From dfe1d47269dbfa95310e9c8ffcdc7cb63cb35734 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Thu, 23 Oct 2025 00:14:50 -0700 Subject: [PATCH 07/30] Remove unused WinHttp code --- include/vcpkg/base/message-data.inc.h | 4467 ++++++++++++------------- locales/messages.json | 6 - src/vcpkg/base/downloads.cpp | 541 --- src/vcpkg/binarycaching.cpp | 2 +- 4 files changed, 2230 insertions(+), 2786 deletions(-) diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 88bb3cbca4..acf1612d20 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -8,9 +8,9 @@ DECLARE_MESSAGE(ACpuArchitecture, (), "", "a CPU architecture") DECLARE_MESSAGE(ADependency, (), "", "a dependency") DECLARE_MESSAGE(ADependencyFeature, (), "", "a feature of a dependency") DECLARE_MESSAGE(ADemandObject, - (), - "'demands' are a concept in the schema of a JSON file the user can edit", - "a demand object") + (), + "'demands' are a concept in the schema of a JSON file the user can edit", + "a demand object") DECLARE_MESSAGE(AString, (), "", "a string") DECLARE_MESSAGE(ASha512, (), "", "a SHA-512 hash") DECLARE_MESSAGE(ADateVersionString, (), "", "a date version string") @@ -18,99 +18,99 @@ DECLARE_MESSAGE(AddArtifactOnlyOne, (msg::command_line), "", "'{command_line}' c DECLARE_MESSAGE(AddCommandFirstArg, (), "", "The first parameter to add must be 'artifact' or 'port'.") DECLARE_MESSAGE(AddingCompletionEntry, (msg::path), "", "Adding vcpkg completion entry to {path}.") DECLARE_MESSAGE(AdditionalPackagesToExport, - (), - "", - "Additional packages (*) need to be exported to complete this operation.") + (), + "", + "Additional packages (*) need to be exported to complete this operation.") DECLARE_MESSAGE(AdditionalPackagesToRemove, - (), - "", - "Additional packages (*) need to be removed to complete this operation.") + (), + "", + "Additional packages (*) need to be removed to complete this operation.") DECLARE_MESSAGE(APlatformExpression, (), "", "a platform expression") DECLARE_MESSAGE(AddPortRequiresManifest, (msg::command_line), "", "'{command_line}' requires an active manifest file.") DECLARE_MESSAGE(AddPortSucceeded, (), "", "Succeeded in adding ports to vcpkg.json file.") DECLARE_MESSAGE(AddRecurseOption, - (), - "", - "If you are sure you want to remove them, run the command with the --recurse option.") + (), + "", + "If you are sure you want to remove them, run the command with the --recurse option.") DECLARE_MESSAGE(AddTripletExpressionNotAllowed, - (msg::package_name, msg::triplet), - "", - "triplet expressions are not allowed here. You may want to change " - "`{package_name}:{triplet}` to `{package_name}` instead.") + (msg::package_name, msg::triplet), + "", + "triplet expressions are not allowed here. You may want to change " + "`{package_name}:{triplet}` to `{package_name}` instead.") DECLARE_MESSAGE(AddVersionArtifactsOnly, - (), - "'--version', and 'vcpkg add port' are command lines that must not be localized", - "--version is artifacts only and can't be used with vcpkg add port") + (), + "'--version', and 'vcpkg add port' are command lines that must not be localized", + "--version is artifacts only and can't be used with vcpkg add port") DECLARE_MESSAGE(AddVersionAddedVersionToFile, (msg::version, msg::path), "", "added version {version} to {path}") DECLARE_MESSAGE(AddVersionCommitChangesReminder, (), "", "Did you remember to commit your changes?") DECLARE_MESSAGE(AddVersionFileNotFound, (msg::path), "", "couldn't find required file {path}") DECLARE_MESSAGE(AddVersionFormatPortSuggestion, (msg::command_line), "", "Run `{command_line}` to format the file") DECLARE_MESSAGE(AddVersionIgnoringOptionAll, - (msg::option), - "The -- before {option} must be preserved as they're part of the help message for the user.", - "ignoring --{option} since a port name argument was provided") + (msg::option), + "The -- before {option} must be preserved as they're part of the help message for the user.", + "ignoring --{option} since a port name argument was provided") DECLARE_MESSAGE(AddVersionInstructions, - (msg::package_name), - "", - "you can run the following commands to add the current version of {package_name} automatically:") + (msg::package_name), + "", + "you can run the following commands to add the current version of {package_name} automatically:") DECLARE_MESSAGE(AddVersionNewFile, (), "", "(new file)") DECLARE_MESSAGE(AddVersionNewShaIs, (msg::commit_sha), "", "new SHA: {commit_sha}") DECLARE_MESSAGE(AddVersionNoFilesUpdated, (), "", "No files were updated") DECLARE_MESSAGE(AddVersionNoFilesUpdatedForPort, (msg::package_name), "", "No files were updated for {package_name}") DECLARE_MESSAGE(AddVersionOldShaIs, (msg::commit_sha), "", "old SHA: {commit_sha}") DECLARE_MESSAGE(AddVersionOverwriteOptionSuggestion, - (msg::option), - "The -- before {option} must be preserved as they're a part of the help message for the user.", - "Use --{option} to bypass this check") + (msg::option), + "The -- before {option} must be preserved as they're a part of the help message for the user.", + "Use --{option} to bypass this check") DECLARE_MESSAGE(AddVersionPortFilesShaChanged, - (msg::package_name), - "", - "checked-in files for {package_name} have changed but the version was not updated") + (msg::package_name), + "", + "checked-in files for {package_name} have changed but the version was not updated") DECLARE_MESSAGE(AddVersionPortFilesShaUnchanged, - (msg::package_name, msg::version), - "", - "checked-in files for {package_name} are unchanged from version {version}") + (msg::package_name, msg::version), + "", + "checked-in files for {package_name} are unchanged from version {version}") DECLARE_MESSAGE(AddVersionPortHasImproperFormat, (msg::package_name), "", "{package_name} is not properly formatted") DECLARE_MESSAGE(AddVersionPortVersionShouldBeGone, - (msg::package_name, msg::version), - "", - "In {package_name}, {version} is a completely new version, so there should be no \"port-version\". " - "Remove \"port-version\" and try again. To skip this check, rerun with --skip-version-format-check .") -DECLARE_MESSAGE( - AddVersionPortVersionShouldBeOneMore, - (msg::package_name, msg::version, msg::count, msg::expected_version, msg::actual_version), - "", - "In {package_name}, the current \"port-version\" for {version} is {count}, so the expected new \"port-version\" is " - "{expected_version}, but the port declares \"port-version\" {actual_version}. Change \"port-version\" to " - "{expected_version} and try again. To skip this check, rerun with --skip-version-format-check .") + (msg::package_name, msg::version), + "", + "In {package_name}, {version} is a completely new version, so there should be no \"port-version\". " + "Remove \"port-version\" and try again. To skip this check, rerun with --skip-version-format-check .") +DECLARE_MESSAGE( + AddVersionPortVersionShouldBeOneMore, + (msg::package_name, msg::version, msg::count, msg::expected_version, msg::actual_version), + "", + "In {package_name}, the current \"port-version\" for {version} is {count}, so the expected new \"port-version\" is " + "{expected_version}, but the port declares \"port-version\" {actual_version}. Change \"port-version\" to " + "{expected_version} and try again. To skip this check, rerun with --skip-version-format-check .") DECLARE_MESSAGE(AddVersionSuggestVersionDate, - (msg::package_name), - "\"version-string\" and \"version-date\" are JSON keys, and --skip-version-format-check is a command " - "line switch. They should not be translated", - "The version format of \"{package_name}\" uses \"version-string\", but the format is acceptable as a " - "\"version-date\". If this format is actually intended to be an ISO 8601 date, change the format to " - "\"version-date\", and rerun this command. Otherwise, disable this check by rerunning this command and " - "adding --skip-version-format-check .") -DECLARE_MESSAGE( - AddVersionSuggestVersionRelaxed, - (msg::package_name), - "\"version-string\" and \"version\" are JSON keys, and --skip-version-format-check is a command line switch. They " - "should not be translated", - "The version format of \"{package_name}\" uses \"version-string\", but the format is acceptable as a \"version\". " - "If the versions for this port are orderable using relaxed-version rules, change the format to \"version\", and " - "rerun this command. Relaxed-version rules order versions by each numeric component. Then, versions with dash " - "suffixes are sorted lexicographically before. Plus'd build tags are ignored. Examples:\n" - "1.0 < 1.1-alpha < 1.1-b < 1.1 < 1.1.1 < 1.2+build = 1.2 < 2.0\n" - "Note in particular that dashed suffixes sort *before*, not after. 1.0-anything < 1.0\n" - "Note that this sort order is the same as chosen in Semantic Versioning (see https://semver.org), even though the " - "actually semantic parts do not apply.\n" - "If versions for this port are not ordered by these rules, disable this check by rerunning this command and adding " - "--skip-version-format-check .") + (msg::package_name), + "\"version-string\" and \"version-date\" are JSON keys, and --skip-version-format-check is a command " + "line switch. They should not be translated", + "The version format of \"{package_name}\" uses \"version-string\", but the format is acceptable as a " + "\"version-date\". If this format is actually intended to be an ISO 8601 date, change the format to " + "\"version-date\", and rerun this command. Otherwise, disable this check by rerunning this command and " + "adding --skip-version-format-check .") +DECLARE_MESSAGE( + AddVersionSuggestVersionRelaxed, + (msg::package_name), + "\"version-string\" and \"version\" are JSON keys, and --skip-version-format-check is a command line switch. They " + "should not be translated", + "The version format of \"{package_name}\" uses \"version-string\", but the format is acceptable as a \"version\". " + "If the versions for this port are orderable using relaxed-version rules, change the format to \"version\", and " + "rerun this command. Relaxed-version rules order versions by each numeric component. Then, versions with dash " + "suffixes are sorted lexicographically before. Plus'd build tags are ignored. Examples:\n" + "1.0 < 1.1-alpha < 1.1-b < 1.1 < 1.1.1 < 1.2+build = 1.2 < 2.0\n" + "Note in particular that dashed suffixes sort *before*, not after. 1.0-anything < 1.0\n" + "Note that this sort order is the same as chosen in Semantic Versioning (see https://semver.org), even though the " + "actually semantic parts do not apply.\n" + "If versions for this port are not ordered by these rules, disable this check by rerunning this command and adding " + "--skip-version-format-check .") DECLARE_MESSAGE(AddVersionUpdateVersionReminder, (), "", "Did you remember to update the version or port version?") DECLARE_MESSAGE(AddVersionUseOptionAll, - (msg::command_name, msg::option), - "The -- before {option} must be preserved as they're part of the help message for the user.", - "{command_name} with no arguments requires passing --{option} to update all port versions at once") + (msg::command_name, msg::option), + "The -- before {option} must be preserved as they're part of the help message for the user.", + "{command_name} with no arguments requires passing --{option} to update all port versions at once") DECLARE_MESSAGE(AddVersionVersionAlreadyInFile, (msg::version, msg::path), "", "version {version} is already in {path}") DECLARE_MESSAGE(AddVersionVersionIs, (msg::version), "", "version: {version}") DECLARE_MESSAGE(ADictionaryOfContacts, (), "", "a dictionary of contacts") @@ -123,13 +123,13 @@ DECLARE_MESSAGE(AGitRegistry, (), "", "a git registry") DECLARE_MESSAGE(AGitRepositoryUrl, (), "", "a git repository URL") DECLARE_MESSAGE(AllFeatureTestsPassed, (), "", "All feature tests passed.") DECLARE_MESSAGE(AllFormatArgsRawArgument, - (msg::value), - "example of {value} is 'foo {} bar'", - "format string \"{value}\" contains a raw format argument") + (msg::value), + "example of {value} is 'foo {} bar'", + "format string \"{value}\" contains a raw format argument") DECLARE_MESSAGE(AllFormatArgsUnbalancedBraces, - (msg::value), - "example of {value} is 'foo bar {'", - "unbalanced brace in format string \"{value}\"") + (msg::value), + "example of {value} is 'foo bar {'", + "unbalanced brace in format string \"{value}\"") DECLARE_MESSAGE(AllPackagesAreUpdated, (), "", "No action taken because all installed packages are up-to-date.") DECLARE_MESSAGE(AllShasValid, (), "sha = sha512 of url", "All checked sha's are valid.") DECLARE_MESSAGE(AlreadyInstalled, (msg::spec), "", "{spec} is already installed") @@ -137,10 +137,10 @@ DECLARE_MESSAGE(AManifest, (), "", "a manifest") DECLARE_MESSAGE(AMaximumOfOneAssetReadUrlCanBeSpecified, (), "", "a maximum of one asset read url can be specified.") DECLARE_MESSAGE(AMaximumOfOneAssetWriteUrlCanBeSpecified, (), "", "a maximum of one asset write url can be specified.") DECLARE_MESSAGE(AmbiguousConfig, - (msg::json_field), - "", - "Ambiguous vcpkg configuration provided by both manifest and configuration file. Choose one by " - "deleting this file or deleting \"{json_field}\" from the manifest file.") + (msg::json_field), + "", + "Ambiguous vcpkg configuration provided by both manifest and configuration file. Choose one by " + "deleting this file or deleting \"{json_field}\" from the manifest file.") DECLARE_MESSAGE(AnArtifactsGitRegistryUrl, (), "", "an artifacts git registry URL") DECLARE_MESSAGE(AnArtifactsRegistry, (), "", "an artifacts registry") DECLARE_MESSAGE(AnArrayOfDefaultFeatures, (), "", "an array of default features") @@ -155,17 +155,17 @@ DECLARE_MESSAGE(AnArrayOfVersions, (), "", "an array of versions") DECLARE_MESSAGE(AnExactVersionString, (), "", "an exact version string") DECLARE_MESSAGE(AnIdentifer, (), "", "an identifier") DECLARE_MESSAGE(AnObjectContainingVcpkgArtifactsMetadata, - (), - "'vcpkg-artifacts' is the name of the product feature and should not be localized", - "an object containing vcpkg-artifacts metadata") + (), + "'vcpkg-artifacts' is the name of the product feature and should not be localized", + "an object containing vcpkg-artifacts metadata") DECLARE_MESSAGE(AnOverlayPath, (), "", "an overlay path") DECLARE_MESSAGE(AnOverlayTripletsPath, (), "", "a triplet path") DECLARE_MESSAGE(AnOverride, (), "", "an override") DECLARE_MESSAGE(ANonNegativeInteger, (), "", "a nonnegative integer") DECLARE_MESSAGE(AnotherInstallationInProgress, - (), - "", - "Another installation is in progress on the machine, sleeping 6s before retrying.") + (), + "", + "Another installation is in progress on the machine, sleeping 6s before retrying.") DECLARE_MESSAGE(AnSpdxLicenseExpression, (), "", "an SPDX license expression") DECLARE_MESSAGE(APackageName, (), "", "a package name") DECLARE_MESSAGE(APackagePattern, (), "", "a package pattern") @@ -177,30 +177,30 @@ DECLARE_MESSAGE(ARegistry, (), "", "a registry") DECLARE_MESSAGE(ARegistryImplementationKind, (), "", "a registry implementation kind") DECLARE_MESSAGE(ARegistryPath, (), "", "a registry path") DECLARE_MESSAGE(ARegistryPathMustBeDelimitedWithForwardSlashes, - (), - "", - "A registry path must use single forward slashes as path separators.") + (), + "", + "A registry path must use single forward slashes as path separators.") DECLARE_MESSAGE(ARegistryPathMustNotHaveDots, (), "", "A registry path must not have 'dot' or 'dot dot' path elements.") DECLARE_MESSAGE(ARegistryPathMustStartWithDollar, - (), - "", - "A registry path must start with `$` to mean the registry root; for example, `$/foo/bar`.") + (), + "", + "A registry path must start with `$` to mean the registry root; for example, `$/foo/bar`.") DECLARE_MESSAGE(ARelaxedVersionString, (), "", "a relaxed version string") DECLARE_MESSAGE(ArtifactsBootstrapFailed, (), "", "vcpkg-artifacts is not installed and could not be bootstrapped.") DECLARE_MESSAGE(ArtifactsOptionIncompatibility, (msg::option), "", "--{option} has no effect on find artifact.") DECLARE_MESSAGE(ArtifactsOptionJson, - (), - "", - "Full path to JSON file where environment variables and other properties are recorded") + (), + "", + "Full path to JSON file where environment variables and other properties are recorded") DECLARE_MESSAGE(ArtifactsOptionMSBuildProps, - (), - "", - "Full path to the file in which MSBuild properties will be written") + (), + "", + "Full path to the file in which MSBuild properties will be written") DECLARE_MESSAGE(ArtifactsOptionVersion, (), "", "A version or version range to match; only valid for artifacts") DECLARE_MESSAGE(ArtifactsOptionVersionMismatch, - (), - "--version is a command line switch and must not be localized", - "The number of --version switches must match the number of named artifacts") + (), + "--version is a command line switch and must not be localized", + "The number of --version switches must match the number of named artifacts") DECLARE_MESSAGE(ArtifactsSwitchAllLanguages, (), "", "Acquires all language files when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchARM, (), "", "Forces host detection to ARM when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchARM64, (), "", "Forces host detection to ARM64 when acquiring artifacts") @@ -212,17 +212,17 @@ DECLARE_MESSAGE(ArtifactsSwitchTargetARM64, (), "", "Sets target detection to AR DECLARE_MESSAGE(ArtifactsSwitchTargetX64, (), "", "Sets target detection to x64 when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchTargetX86, (), "", "Sets target to x86 when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchOnlyOneOperatingSystem, - (), - "The words after -- are command line switches and must not be localized.", - "Only one operating system (--windows, --osx, --linux, --freebsd) may be set.") + (), + "The words after -- are command line switches and must not be localized.", + "Only one operating system (--windows, --osx, --linux, --freebsd) may be set.") DECLARE_MESSAGE(ArtifactsSwitchOnlyOneHostPlatform, - (), - "The words after -- are command line switches and must not be localized.", - "Only one host platform (--x64, --x86, --arm, --arm64) may be set.") + (), + "The words after -- are command line switches and must not be localized.", + "Only one host platform (--x64, --x86, --arm, --arm64) may be set.") DECLARE_MESSAGE(ArtifactsSwitchOnlyOneTargetPlatform, - (), - "The words after -- are command line switches and must not be localized.", - "Only one target platform (--target:x64, --target:x86, --target:arm, --target:arm64) may be set.") + (), + "The words after -- are command line switches and must not be localized.", + "Only one target platform (--target:x64, --target:x86, --target:arm, --target:arm64) may be set.") DECLARE_MESSAGE(ArtifactsSwitchOsx, (), "", "Forces host detection to MacOS when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchX64, (), "", "Forces host detection to x64 when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchX86, (), "", "Forces host detection to x86 when acquiring artifacts") @@ -231,51 +231,51 @@ DECLARE_MESSAGE(AssetCacheConsult, (msg::path, msg::url), "", "Trying to downloa DECLARE_MESSAGE(AssetCacheConsultScript, (msg::path), "", "Trying to download {path} using asset cache script") DECLARE_MESSAGE(AssetCacheHit, (), "", "Download successful! Asset cache hit.") DECLARE_MESSAGE(AssetCacheHitUrl, - (msg::url), - "", - "Download successful! Asset cache hit, did not try authoritative source {url}") + (msg::url), + "", + "Download successful! Asset cache hit, did not try authoritative source {url}") DECLARE_MESSAGE(AssetCacheMiss, (msg::url), "", "Asset cache miss; trying authoritative source {url}") DECLARE_MESSAGE(AssetCacheMissBlockOrigin, - (msg::url), - "x-block-origin is a vcpkg term. Do not translate", - "there were no asset cache hits, and x-block-origin blocks trying the authoritative source {url}") + (msg::url), + "x-block-origin is a vcpkg term. Do not translate", + "there were no asset cache hits, and x-block-origin blocks trying the authoritative source {url}") DECLARE_MESSAGE(AssetCacheMissNoUrls, - (msg::sha), - "", - "Asset cache missed looking for {sha} and no authoritative URL is known") + (msg::sha), + "", + "Asset cache missed looking for {sha} and no authoritative URL is known") DECLARE_MESSAGE(AssetCacheProviderAcceptsNoArguments, - (msg::value), - "{value} is a asset caching provider name such as azurl, clear, or x-block-origin", - "unexpected arguments: '{value}' does not accept arguments") + (msg::value), + "{value} is a asset caching provider name such as azurl, clear, or x-block-origin", + "unexpected arguments: '{value}' does not accept arguments") DECLARE_MESSAGE(AssetCacheScriptBadVariable, - (msg::value, msg::list), - "{value} is the script template passed to x-script, {list} is the name of the unknown replacement", - "the script template {value} contains unknown replacement {list}") + (msg::value, msg::list), + "{value} is the script template passed to x-script, {list} is the name of the unknown replacement", + "the script template {value} contains unknown replacement {list}") DECLARE_MESSAGE(AssetCacheScriptBadVariableHint, - (msg::list), - "{list} is the name of the unknown replacement", - "if you want this on the literal command line, use {{{{{list}}}}}") + (msg::list), + "{list} is the name of the unknown replacement", + "if you want this on the literal command line, use {{{{{list}}}}}") DECLARE_MESSAGE(AssetCacheScriptCommandLine, (), "", "the full script command line was") DECLARE_MESSAGE(AssetCacheScriptNeedsSha, - (msg::value, msg::url), - "{value} is the script template the user supplied to x-script", - "the script template {value} requires a SHA, but no SHA is known for attempted download of {url}") + (msg::value, msg::url), + "{value} is the script template the user supplied to x-script", + "the script template {value} requires a SHA, but no SHA is known for attempted download of {url}") DECLARE_MESSAGE(AssetCacheScriptNeedsUrl, - (msg::value, msg::sha), - "{value} is the script template the user supplied to x-script", - "the script template {value} requires a URL, but no URL is known for attempted download of {sha}") + (msg::value, msg::sha), + "{value} is the script template the user supplied to x-script", + "the script template {value} requires a URL, but no URL is known for attempted download of {sha}") DECLARE_MESSAGE(AssetCacheScriptFailed, - (msg::exit_code), - "", - "the asset cache script returned nonzero exit code {exit_code}") + (msg::exit_code), + "", + "the asset cache script returned nonzero exit code {exit_code}") DECLARE_MESSAGE(AssetCacheScriptFailedToWriteFile, - (), - "", - "the asset cache script returned success but did not create expected result file") + (), + "", + "the asset cache script returned success but did not create expected result file") DECLARE_MESSAGE(AssetCacheScriptFailedToWriteCorrectHash, - (), - "", - "the asset cache script returned success but the resulting file has an unexpected hash") + (), + "", + "the asset cache script returned success but the resulting file has an unexpected hash") DECLARE_MESSAGE(AssetSourcesArg, (), "", "Asset caching sources. See 'vcpkg help assetcaching'") DECLARE_MESSAGE(ASemanticVersionString, (), "", "a semantic version string") DECLARE_MESSAGE(ASetOfFeatures, (), "", "a set of features") @@ -287,29 +287,29 @@ DECLARE_MESSAGE(AToolDataFile, (), "", "a tool data file") DECLARE_MESSAGE(AToolDataOS, (), "", "a tool data operating system") DECLARE_MESSAGE(AToolDataVersion, (), "", "a tool data version") DECLARE_MESSAGE(ToolDataFileSchemaVersionNotSupported, - (msg::version), - "", - "document schema version {version} is not supported by this version of vcpkg") + (msg::version), + "", + "document schema version {version} is not supported by this version of vcpkg") DECLARE_MESSAGE(AttemptingToSetBuiltInBaseline, - (), - "", - "attempting to set builtin-baseline in vcpkg.json while overriding the default-registry in " - "vcpkg-configuration.json.\nthe default-registry from vcpkg-configuration.json will be used.") + (), + "", + "attempting to set builtin-baseline in vcpkg.json while overriding the default-registry in " + "vcpkg-configuration.json.\nthe default-registry from vcpkg-configuration.json will be used.") DECLARE_MESSAGE(AutomaticLinkingForMSBuildProjects, - (), - "", - "All MSBuild C++ projects can now #include any installed libraries. Linking will be handled " - "automatically. Installing new libraries will make them instantly available.") + (), + "", + "All MSBuild C++ projects can now #include any installed libraries. Linking will be handled " + "automatically. Installing new libraries will make them instantly available.") DECLARE_MESSAGE(AutomaticLinkingForVS2017AndLater, - (), - "", - "Visual Studio 2017 and later can now #include any installed libraries. Linking will be handled " - "automatically. Installing new libraries will make them instantly available.") + (), + "", + "Visual Studio 2017 and later can now #include any installed libraries. Linking will be handled " + "automatically. Installing new libraries will make them instantly available.") DECLARE_MESSAGE(AutoSettingEnvVar, - (msg::env_var, msg::url), - "An example of env_var is \"HTTP(S)_PROXY\"" - "'--' at the beginning must be preserved", - "-- Automatically setting {env_var} environment variables to \"{url}\".") + (msg::env_var, msg::url), + "An example of env_var is \"HTTP(S)_PROXY\"" + "'--' at the beginning must be preserved", + "-- Automatically setting {env_var} environment variables to \"{url}\".") DECLARE_MESSAGE(AUrl, (), "", "a url") DECLARE_MESSAGE(AvailableHelpTopics, (), "", "Available help topics:") DECLARE_MESSAGE(AVcpkgRepositoryCommit, (), "", "a vcpkg repository commit") @@ -318,234 +318,234 @@ DECLARE_MESSAGE(AVersionObject, (), "", "a version object") DECLARE_MESSAGE(AVersionOfAnyType, (), "", "a version of any type") DECLARE_MESSAGE(AVersionConstraint, (), "", "a version constraint") DECLARE_MESSAGE(AzcopyFailedToPutBlob, - (msg::exit_code, msg::url, msg::value), - "azcopy is the name of a program. {value} is an HTTP status code.", - "azcopy failed to upload a file to {url} with exit code {exit_code} and http code {value}.") + (msg::exit_code, msg::url, msg::value), + "azcopy is the name of a program. {value} is an HTTP status code.", + "azcopy failed to upload a file to {url} with exit code {exit_code} and http code {value}.") DECLARE_MESSAGE(AzUrlAssetCacheRequiresBaseUrl, - (), - "", - "unexpected arguments: asset config 'azurl' requires a base url") + (), + "", + "unexpected arguments: asset config 'azurl' requires a base url") DECLARE_MESSAGE(AzUrlAssetCacheRequiresLessThanFour, - (), - "", - "unexpected arguments: asset config 'azurl' requires fewer than 4 arguments") + (), + "", + "unexpected arguments: asset config 'azurl' requires fewer than 4 arguments") DECLARE_MESSAGE(BaselineConflict, - (), - "", - "Specifying vcpkg-configuration.default-registry in a manifest file conflicts with built-in " - "baseline.\nPlease remove one of these conflicting settings.") + (), + "", + "Specifying vcpkg-configuration.default-registry in a manifest file conflicts with built-in " + "baseline.\nPlease remove one of these conflicting settings.") DECLARE_MESSAGE(BaselineGitShowFailed, - (msg::commit_sha), - "", - "while checking out baseline from commit '{commit_sha}', failed to `git show` " - "versions/baseline.json. This may be fixed by fetching commits with `git fetch`.") + (msg::commit_sha), + "", + "while checking out baseline from commit '{commit_sha}', failed to `git show` " + "versions/baseline.json. This may be fixed by fetching commits with `git fetch`.") DECLARE_MESSAGE(BaselineMissing, (msg::package_name), "", "{package_name} is not assigned a version") DECLARE_MESSAGE(BinariesRelativeToThePackageDirectoryHere, - (), - "", - "the binaries are relative to ${{CURRENT_PACKAGES_DIR}} here") + (), + "", + "the binaries are relative to ${{CURRENT_PACKAGES_DIR}} here") DECLARE_MESSAGE(BaselineOnlyPlatformExpressionOrTriplet, - (), - "", - "You can not specify a platform expression and a triplet") + (), + "", + "You can not specify a platform expression and a triplet") DECLARE_MESSAGE(BinarySourcesArg, - (), - "'vcpkg help binarycaching' is a command line and should not be localized", - "Binary caching sources. See 'vcpkg help binarycaching'") + (), + "'vcpkg help binarycaching' is a command line and should not be localized", + "Binary caching sources. See 'vcpkg help binarycaching'") DECLARE_MESSAGE(BinaryWithInvalidArchitecture, (msg::path, msg::arch), "", "{path} is built for {arch}") DECLARE_MESSAGE(BuildAlreadyInstalled, - (msg::spec), - "", - "{spec} is already installed; please remove {spec} before attempting to build it.") + (msg::spec), + "", + "{spec} is already installed; please remove {spec} before attempting to build it.") DECLARE_MESSAGE(BuildDependenciesMissing, - (), - "", - "The build command requires all dependencies to be already installed.\nThe following " - "dependencies are missing:") + (), + "", + "The build command requires all dependencies to be already installed.\nThe following " + "dependencies are missing:") DECLARE_MESSAGE(BuildingFromHead, - (msg::spec), - "'HEAD' means the most recent version of source code", - "Building {spec} from HEAD...") + (msg::spec), + "'HEAD' means the most recent version of source code", + "Building {spec} from HEAD...") DECLARE_MESSAGE(BuildingPackage, (msg::spec), "", "Building {spec}...") DECLARE_MESSAGE(BuildingPackageFailed, - (msg::spec, msg::build_result), - "", - "building {spec} failed with: {build_result}") + (msg::spec, msg::build_result), + "", + "building {spec} failed with: {build_result}") DECLARE_MESSAGE(BuildingPackageFailedDueToMissingDeps, - (), - "Printed after BuildingPackageFailed, and followed by a list of dependencies that were missing.", - "due to the following missing dependencies:") + (), + "Printed after BuildingPackageFailed, and followed by a list of dependencies that were missing.", + "due to the following missing dependencies:") DECLARE_MESSAGE(BuildResultBuildFailed, - (), - "Printed after the name of an installed entity to indicate that it failed to build.", - "BUILD_FAILED") -DECLARE_MESSAGE( - BuildResultCacheMissing, - (), - "Printed after the name of an installed entity to indicate that it was not present in the binary cache when " - "the user has requested that things may only be installed from the cache rather than built.", - "CACHE_MISSING") + (), + "Printed after the name of an installed entity to indicate that it failed to build.", + "BUILD_FAILED") +DECLARE_MESSAGE( + BuildResultCacheMissing, + (), + "Printed after the name of an installed entity to indicate that it was not present in the binary cache when " + "the user has requested that things may only be installed from the cache rather than built.", + "CACHE_MISSING") DECLARE_MESSAGE(BuildResultCascadeDueToMissingDependencies, - (), - "Printed after the name of an installed entity to indicate that it could not attempt " - "to be installed because one of its transitive dependencies failed to install.", - "CASCADED_DUE_TO_MISSING_DEPENDENCIES") + (), + "Printed after the name of an installed entity to indicate that it could not attempt " + "to be installed because one of its transitive dependencies failed to install.", + "CASCADED_DUE_TO_MISSING_DEPENDENCIES") DECLARE_MESSAGE(BuildResultDownloaded, - (), - "Printed after the name of an installed entity to indicate that it was successfully " - "downloaded but no build or install was requested.", - "DOWNLOADED") + (), + "Printed after the name of an installed entity to indicate that it was successfully " + "downloaded but no build or install was requested.", + "DOWNLOADED") DECLARE_MESSAGE(BuildResultExcluded, - (), - "Printed after the name of an installed entity to indicate that the user explicitly " - "requested it not be installed.", - "EXCLUDED") -DECLARE_MESSAGE( - BuildResultFileConflicts, - (), - "Printed after the name of an installed entity to indicate that it conflicts with something already installed", - "FILE_CONFLICTS") + (), + "Printed after the name of an installed entity to indicate that the user explicitly " + "requested it not be installed.", + "EXCLUDED") +DECLARE_MESSAGE( + BuildResultFileConflicts, + (), + "Printed after the name of an installed entity to indicate that it conflicts with something already installed", + "FILE_CONFLICTS") DECLARE_MESSAGE(BuildResultPostBuildChecksFailed, - (), - "Printed after the name of an installed entity to indicate that it built " - "successfully, but that it failed post build checks.", - "POST_BUILD_CHECKS_FAILED") + (), + "Printed after the name of an installed entity to indicate that it built " + "successfully, but that it failed post build checks.", + "POST_BUILD_CHECKS_FAILED") DECLARE_MESSAGE(BuildResultRemoved, - (), - "Printed after the name of an uninstalled entity to indicate that it was successfully uninstalled.", - "REMOVED") -DECLARE_MESSAGE( - BuildResultSucceeded, - (), - "Printed after the name of an installed entity to indicate that it was built and installed successfully.", - "SUCCEEDED") + (), + "Printed after the name of an uninstalled entity to indicate that it was successfully uninstalled.", + "REMOVED") +DECLARE_MESSAGE( + BuildResultSucceeded, + (), + "Printed after the name of an installed entity to indicate that it was built and installed successfully.", + "SUCCEEDED") DECLARE_MESSAGE(BuildResultSummaryHeader, - (msg::triplet), - "Displayed before a list of a summary installation results.", - "SUMMARY FOR {triplet}") + (msg::triplet), + "Displayed before a list of a summary installation results.", + "SUMMARY FOR {triplet}") DECLARE_MESSAGE(BuildResultSummaryLine, - (msg::build_result, msg::count), - "Displayed to show a count of results of a build_result in a summary.", - "{build_result}: {count}") + (msg::build_result, msg::count), + "Displayed to show a count of results of a build_result in a summary.", + "{build_result}: {count}") DECLARE_MESSAGE(BuildTreesRootDir, (), "", "Buildtrees directory (experimental)") DECLARE_MESSAGE(BuildTroubleshootingMessage1, - (), - "First part of build troubleshooting message, printed before the URI to look for existing bugs.", - "Please ensure you're using the latest port files with `git pull` and `vcpkg " - "update`.\nThen check for known issues at:") + (), + "First part of build troubleshooting message, printed before the URI to look for existing bugs.", + "Please ensure you're using the latest port files with `git pull` and `vcpkg " + "update`.\nThen check for known issues at:") DECLARE_MESSAGE(BuildTroubleshootingMessage2, - (), - "Second part of build troubleshooting message, printed after the URI to look for " - "existing bugs but before the URI to file one.", - "You can submit a new issue at:") + (), + "Second part of build troubleshooting message, printed after the URI to look for " + "existing bugs but before the URI to file one.", + "You can submit a new issue at:") DECLARE_MESSAGE(BuildTroubleshootingMessageGH, - (), - "Another part of build troubleshooting message, printed after the URI. An alternative version to " - "create an issue in some cases.", - "You can also submit an issue by running (GitHub CLI must be installed):") -DECLARE_MESSAGE( - BuildTroubleshootingMessage3, - (msg::package_name), - "Third part of build troubleshooting message, printed after the URI to file a bug but " - "before version information about vcpkg itself.", - "Include '[{package_name}] Build error' in your bug report title, the following version information in your " - "bug description, and attach any relevant failure logs from above.") + (), + "Another part of build troubleshooting message, printed after the URI. An alternative version to " + "create an issue in some cases.", + "You can also submit an issue by running (GitHub CLI must be installed):") +DECLARE_MESSAGE( + BuildTroubleshootingMessage3, + (msg::package_name), + "Third part of build troubleshooting message, printed after the URI to file a bug but " + "before version information about vcpkg itself.", + "Include '[{package_name}] Build error' in your bug report title, the following version information in your " + "bug description, and attach any relevant failure logs from above.") DECLARE_MESSAGE(BuiltInTriplets, (), "", "Built-in Triplets:") DECLARE_MESSAGE( - BuiltWithIncorrectArchitecture, - (msg::arch), - "", - "The triplet requests that binaries are built for {arch}, but the following binaries were built for a " - "different architecture. This usually means toolchain information is incorrectly conveyed to the binaries' " - "build system. To suppress this message, add set(VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK enabled)") + BuiltWithIncorrectArchitecture, + (msg::arch), + "", + "The triplet requests that binaries are built for {arch}, but the following binaries were built for a " + "different architecture. This usually means toolchain information is incorrectly conveyed to the binaries' " + "build system. To suppress this message, add set(VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK enabled)") DECLARE_MESSAGE(ChecksFailedCheck, (), "", "vcpkg has crashed; no additional details are available.") DECLARE_MESSAGE(ChecksUnreachableCode, (), "", "unreachable code was reached") DECLARE_MESSAGE(ChecksUpdateVcpkg, (), "", "updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.") DECLARE_MESSAGE(CiBaselineAllowUnexpectedPassingRequiresBaseline, - (), - "", - "--allow-unexpected-passing can only be used if a baseline is provided via --ci-baseline.") + (), + "", + "--allow-unexpected-passing can only be used if a baseline is provided via --ci-baseline.") DECLARE_MESSAGE(CiBaselineDisallowedCascade, - (msg::spec, msg::path), - "", - "REGRESSION: {spec} cascaded, but it is required to pass. ({path}).") + (msg::spec, msg::path), + "", + "REGRESSION: {spec} cascaded, but it is required to pass. ({path}).") DECLARE_MESSAGE(CiBaselineIndependentRegression, - (msg::spec, msg::build_result), - "", - "REGRESSION: Independent {spec} failed with {build_result}.") + (msg::spec, msg::build_result), + "", + "REGRESSION: Independent {spec} failed with {build_result}.") DECLARE_MESSAGE(CiBaselineRegression, - (msg::spec, msg::build_result, msg::path), - "", - "REGRESSION: {spec} failed with {build_result}. If expected, add {spec}=fail to {path}.") + (msg::spec, msg::build_result, msg::path), + "", + "REGRESSION: {spec} failed with {build_result}. If expected, add {spec}=fail to {path}.") DECLARE_MESSAGE(CiBaselineRegressionNoPath, - (msg::spec, msg::build_result), - "", - "REGRESSION: {spec} failed with {build_result}.") + (msg::spec, msg::build_result), + "", + "REGRESSION: {spec} failed with {build_result}.") DECLARE_MESSAGE(CiBaselineRegressionHeader, - (), - "Printed before a series of CiBaselineRegression and/or CiBaselineUnexpectedPass messages.", - "REGRESSIONS:") + (), + "Printed before a series of CiBaselineRegression and/or CiBaselineUnexpectedPass messages.", + "REGRESSIONS:") DECLARE_MESSAGE(CiBaselineUnexpectedFail, - (msg::spec, msg::triplet), - "", - "REGRESSION: {spec} is marked as fail but not supported for {triplet}.") + (msg::spec, msg::triplet), + "", + "REGRESSION: {spec} is marked as fail but not supported for {triplet}.") DECLARE_MESSAGE(CiBaselineUnexpectedFailCascade, - (msg::spec, msg::triplet), - "", - "REGRESSION: {spec} is marked as fail but one dependency is not supported for {triplet}.") + (msg::spec, msg::triplet), + "", + "REGRESSION: {spec} is marked as fail but one dependency is not supported for {triplet}.") DECLARE_MESSAGE(CiBaselineUnexpectedPass, - (msg::spec, msg::path), - "", - "PASSING, REMOVE FROM FAIL LIST: {spec} ({path}).") + (msg::spec, msg::path), + "", + "PASSING, REMOVE FROM FAIL LIST: {spec} ({path}).") DECLARE_MESSAGE(CISettingsOptCIBase, - (), - "", - "Path to the ci.baseline.txt file. Used to skip ports and detect regressions.") + (), + "", + "Path to the ci.baseline.txt file. Used to skip ports and detect regressions.") DECLARE_MESSAGE(CISettingsOptExclude, (), "", "Comma separated list of ports to skip") DECLARE_MESSAGE(CISettingsOptFailureLogs, (), "", "Directory to which failure logs will be copied") DECLARE_MESSAGE(CISettingsOptHostExclude, (), "", "Comma separated list of ports to skip for the host triplet") DECLARE_MESSAGE(CISettingsOptKnownFailuresFrom, (), "", "Path to the file of known package build failures") DECLARE_MESSAGE(CISettingsOptOutputHashes, (), "", "File to output all determined package hashes") DECLARE_MESSAGE(CISettingsOptParentHashes, - (), - "", - "File to read package hashes for a parent CI state, to reduce the set of changed packages") + (), + "", + "File to read package hashes for a parent CI state, to reduce the set of changed packages") DECLARE_MESSAGE(CISettingsOptXUnit, (), "", "File to output results in XUnit format") DECLARE_MESSAGE(CISettingsVerifyGitTree, - (), - "", - "Verifies that each git tree object matches its declared version (this is very slow)") + (), + "", + "Verifies that each git tree object matches its declared version (this is very slow)") DECLARE_MESSAGE(CISettingsVerifyVersion, (), "", "Prints result for each port rather than only just errors") DECLARE_MESSAGE(CISkipInstallation, (), "", "The following packages are already installed and won't be built again:") DECLARE_MESSAGE(CISwitchOptAllowUnexpectedPassing, (), "", "Suppresses 'Passing, remove from fail list' results") DECLARE_MESSAGE(CISwitchOptDryRun, (), "", "Prints out plan without execution") DECLARE_MESSAGE(CISwitchOptRandomize, (), "", "Randomizes the install order") DECLARE_MESSAGE(CISwitchOptSkipFailures, - (), - "=fail is an on-disk format and should not be localized", - "Skips ports marked `=fail` in ci.baseline.txt") + (), + "=fail is an on-disk format and should not be localized", + "Skips ports marked `=fail` in ci.baseline.txt") DECLARE_MESSAGE(CISwitchOptXUnitAll, (), "", "Reports unchanged ports in the XUnit output") DECLARE_MESSAGE(ClearingContents, (msg::path), "", "Clearing contents of {path}") DECLARE_MESSAGE(CMakePkgConfigTargetsUsage, (msg::package_name), "", "{package_name} provides pkg-config modules:") DECLARE_MESSAGE(CmakeTargetsExcluded, (msg::count), "", "{count} additional targets are not displayed.") DECLARE_MESSAGE(CMakeTargetsUsage, - (msg::package_name), - "'targets' are a CMake and Makefile concept", - "{package_name} provides CMake targets:") -DECLARE_MESSAGE( - CMakeTargetsUsageHeuristicMessage, - (), - "Displayed after CMakeTargetsUsage; the # must be kept at the beginning so that the message remains a comment.", - "# this is heuristically generated, and may not be correct") + (msg::package_name), + "'targets' are a CMake and Makefile concept", + "{package_name} provides CMake targets:") +DECLARE_MESSAGE( + CMakeTargetsUsageHeuristicMessage, + (), + "Displayed after CMakeTargetsUsage; the # must be kept at the beginning so that the message remains a comment.", + "# this is heuristically generated, and may not be correct") DECLARE_MESSAGE(CMakeToolChainFile, (msg::path), "", "CMake projects should use: \"-DCMAKE_TOOLCHAIN_FILE={path}\"") DECLARE_MESSAGE(CMakeUsingExportedLibs, - (msg::value), - "{value} is a CMake command line switch of the form -DFOO=BAR", - "To use exported libraries in CMake projects, add {value} to your CMake command line.") + (msg::value), + "{value} is a CMake command line switch of the form -DFOO=BAR", + "To use exported libraries in CMake projects, add {value} to your CMake command line.") DECLARE_MESSAGE(CmdAcquireExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg acquire ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg acquire ") DECLARE_MESSAGE(CmdAcquireProjectSynopsis, (), "", "Acquires all artifacts referenced by a manifest") DECLARE_MESSAGE(CmdAcquireSynopsis, (), "", "Acquires the named artifact") DECLARE_MESSAGE(CmdActivateSynopsis, (), "", "Activates artifacts from a manifest") @@ -554,9 +554,9 @@ DECLARE_MESSAGE(CmdAddExample2, (), "", "vcpkg add artifact ") DECLARE_MESSAGE(CmdAddSynopsis, (), "", "Adds dependency to manifest") DECLARE_MESSAGE(CmdAddVersionSynopsis, (), "", "Adds a version to the version database") DECLARE_MESSAGE(CmdAddVersionExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg x-add-version ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg x-add-version ") DECLARE_MESSAGE(CmdAddVersionOptAll, (), "", "Processes versions for all ports") DECLARE_MESSAGE(CmdAddVersionOptOverwriteVersion, (), "", "Overwrites git-tree of an existing version") DECLARE_MESSAGE(CmdAddVersionOptSkipFormatChk, (), "", "Skips the formatting check of vcpkg.json files") @@ -564,119 +564,119 @@ DECLARE_MESSAGE(CmdAddVersionOptSkipVersionFormatChk, (), "", "Skips the version DECLARE_MESSAGE(CmdAddVersionOptVerbose, (), "", "Prints success messages rather than only errors") DECLARE_MESSAGE(CmdBootstrapStandaloneSynopsis, (), "", "Bootstraps a vcpkg root from only a vcpkg binary") DECLARE_MESSAGE(CmdBuildExternalExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg build-external ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg build-external ") DECLARE_MESSAGE(CmdBuildExternalExample2, - (), - "This is a command line, only the path part should be changed to a path conveying the same idea", - "vcpkg build-external zlib2 C:\\path\\to\\dir\\with\\vcpkg.json") + (), + "This is a command line, only the path part should be changed to a path conveying the same idea", + "vcpkg build-external zlib2 C:\\path\\to\\dir\\with\\vcpkg.json") DECLARE_MESSAGE(CmdBuildExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg build ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg build ") DECLARE_MESSAGE(CmdBuildExternalSynopsis, (), "", "Builds port from a path") DECLARE_MESSAGE(CmdBuildSynopsis, (), "", "Builds a port") DECLARE_MESSAGE(CmdCiCleanSynopsis, - (), - "CI is continuous integration (building everything together)", - "Clears all files to prepare for a CI run") + (), + "CI is continuous integration (building everything together)", + "Clears all files to prepare for a CI run") DECLARE_MESSAGE(CmdCiSynopsis, - (), - "CI is continuous integration (building everything together)", - "Tries building all ports for CI testing") + (), + "CI is continuous integration (building everything together)", + "Tries building all ports for CI testing") DECLARE_MESSAGE(CmdCiVerifyVersionsSynopsis, (), "", "Checks integrity of the version database") DECLARE_MESSAGE(CmdCheckSupportExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg x-check-support ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg x-check-support ") DECLARE_MESSAGE(CmdCheckSupportSynopsis, (), "", "Tests whether a port is supported without building it") DECLARE_MESSAGE(CmdCheckToolsShaSynopsis, - (), - "", - "Checks the sha512 entries in a tools data file by downloading all entries and computing the hashes") + (), + "", + "Checks the sha512 entries in a tools data file by downloading all entries and computing the hashes") DECLARE_MESSAGE(CmdCheckToolsShaSwitchFix, (), "", "Fixes the sha entry in the given file") DECLARE_MESSAGE(CmdCheckToolsShaSwitchOnlyWithName, (), "", "Only check entries with the given name") DECLARE_MESSAGE(CmdCreateExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg create ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg create ") DECLARE_MESSAGE(CmdCreateExample2, - (), - "This is a command line, 'my-fancy-port' and 'sources.zip' should probably be localized", - "vcpkg create my-fancy-port https://example.com/sources.zip") + (), + "This is a command line, 'my-fancy-port' and 'sources.zip' should probably be localized", + "vcpkg create my-fancy-port https://example.com/sources.zip") DECLARE_MESSAGE(CmdCreateExample3, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg create ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg create ") DECLARE_MESSAGE(CmdDeactivateSynopsis, (), "", "Removes all artifact activations from the current shell") DECLARE_MESSAGE(CmdDependInfoExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg depend-info ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg depend-info ") DECLARE_MESSAGE(CmdDependInfoFormatConflict, - (), - "", - "Conflicting formats specified. Only one of --format, --dgml, or --dot are accepted.") + (), + "", + "Conflicting formats specified. Only one of --format, --dgml, or --dot are accepted.") DECLARE_MESSAGE(CmdDependInfoFormatHelp, - (), - "The alternatives in ``s must not be localized.", - "Chooses output format, one of `list`, `tree`, `mermaid`, `dot`, or `dgml`") -DECLARE_MESSAGE( - CmdDependInfoFormatInvalid, - (msg::value), - "The alternatives in ``s must not be localized. {value} is what the user specified.", - "--format={value} is not a recognized format. --format must be one of `list`, `tree`, `mermaid`, `dot`, or `dgml`.") + (), + "The alternatives in ``s must not be localized.", + "Chooses output format, one of `list`, `tree`, `mermaid`, `dot`, or `dgml`") +DECLARE_MESSAGE( + CmdDependInfoFormatInvalid, + (msg::value), + "The alternatives in ``s must not be localized. {value} is what the user specified.", + "--format={value} is not a recognized format. --format must be one of `list`, `tree`, `mermaid`, `dot`, or `dgml`.") DECLARE_MESSAGE(CmdDependInfoShowDepthFormatMismatch, - (), - "", - "--show-depth can only be used with `list` and `tree` formats.") + (), + "", + "--show-depth can only be used with `list` and `tree` formats.") DECLARE_MESSAGE(CmdDependInfoXtreeTree, (), "", "--sort=x-tree cannot be used with formats other than tree") DECLARE_MESSAGE(CmdDependInfoOptDepth, (), "", "Shows recursion depth in `list` output") DECLARE_MESSAGE(CmdDependInfoOptMaxRecurse, (), "", "Sets max recursion depth. Default is no limit") DECLARE_MESSAGE( - CmdDependInfoOptSort, - (), - "The alternatives in ``s must not be localized, but the localized text can explain what each value " - "means. The value `reverse` means 'reverse-topological'.", - "Chooses sort order for the `list` format, one of `lexicographical`, `topological` (default), `reverse`") + CmdDependInfoOptSort, + (), + "The alternatives in ``s must not be localized, but the localized text can explain what each value " + "means. The value `reverse` means 'reverse-topological'.", + "Chooses sort order for the `list` format, one of `lexicographical`, `topological` (default), `reverse`") DECLARE_MESSAGE(CmdDownloadExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg x-download --url=https://...") + (), + "This is a command line, only the part should be localized", + "vcpkg x-download --url=https://...") DECLARE_MESSAGE(CmdDownloadExample2, - (), - "This is a command line, only the part should be localized", - "vcpkg x-download --sha512= --url=https://...") + (), + "This is a command line, only the part should be localized", + "vcpkg x-download --sha512= --url=https://...") DECLARE_MESSAGE(CmdDownloadExample3, - (), - "This is a command line, only the part should be localized", - "vcpkg x-download --skip-sha512 --url=https://...") + (), + "This is a command line, only the part should be localized", + "vcpkg x-download --skip-sha512 --url=https://...") DECLARE_MESSAGE(CmdDownloadSynopsis, (), "", "Downloads a file") DECLARE_MESSAGE(CmdEditExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg edit ") + (), + "This is a command line, only the part should be localized", + "vcpkg edit ") DECLARE_MESSAGE(CmdEditOptAll, (), "", "Opens editor into the port as well as the port-specific buildtree subfolder") DECLARE_MESSAGE(CmdEditOptBuildTrees, (), "", "Opens editor into the port-specific buildtree subfolder") DECLARE_MESSAGE(CommandEnvExample2, - (), - "This is a command line, only the part should be localized", - "vcpkg env \"ninja -C \" --triplet x64-windows") + (), + "This is a command line, only the part should be localized", + "vcpkg env \"ninja -C \" --triplet x64-windows") DECLARE_MESSAGE(CmdEnvOptions, (msg::path, msg::env_var), "", "Adds installed {path} to {env_var}") DECLARE_MESSAGE(CmdExportEmptyPlan, - (), - "", - "Refusing to create an export of zero packages. Install packages before exporting.") + (), + "", + "Refusing to create an export of zero packages. Install packages before exporting.") DECLARE_MESSAGE(CmdExportExample1, - (), - "This is a command line, only and the out_dir part should be localized", - "vcpkg export [--nuget] [--output-dir=out_dir]") + (), + "This is a command line, only and the out_dir part should be localized", + "vcpkg export [--nuget] [--output-dir=out_dir]") DECLARE_MESSAGE(CmdExportOpt7Zip, (), "", "Exports to a 7zip (.7z) file") DECLARE_MESSAGE(CmdExportOptDereferenceSymlinks, - (), - "", - "Copies symlinks as regular files and directories in the exported results") + (), + "", + "Copies symlinks as regular files and directories in the exported results") DECLARE_MESSAGE(CmdExportOptDryRun, (), "", "Does not actually export") DECLARE_MESSAGE(CmdExportOptInstalled, (), "", "Exports all installed packages") DECLARE_MESSAGE(CmdExportOptNuGet, (), "", "Exports a NuGet package") @@ -689,57 +689,57 @@ DECLARE_MESSAGE(CmdExportSettingOutput, (), "", "The output name (used to constr DECLARE_MESSAGE(CmdExportSettingOutputDir, (), "", "The output directory for produced artifacts") DECLARE_MESSAGE(CmdExportSynopsis, (), "", "Creates a standalone deployment of installed ports") DECLARE_MESSAGE(CmdFetchOptXStderrStatus, - (), - "", - "Prints status/downloading messages to stderr rather than stdout (Errors/failures still go to stdout)") + (), + "", + "Prints status/downloading messages to stderr rather than stdout (Errors/failures still go to stdout)") DECLARE_MESSAGE(CmdFetchSynopsis, (), "", "Fetches something from the system or the internet") DECLARE_MESSAGE(CmdFindExample1, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg find port ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg find port ") DECLARE_MESSAGE(CmdFindExample2, - (), - "This is a command line, only the <>s part should be localized", - "vcpkg find artifact ") + (), + "This is a command line, only the <>s part should be localized", + "vcpkg find artifact ") DECLARE_MESSAGE(CmdFindSynopsis, (), "", "Finds a port or artifact that may be installed or activated") DECLARE_MESSAGE(CmdFormatFeatureBaselineSynopsis, (), "", "Formats a feature baseline file") DECLARE_MESSAGE(CmdFormatFeatureBaselineExample, - (), - "This is a command line, only the s part should be localized", - "vcpkg format-feature-baseline ") + (), + "This is a command line, only the s part should be localized", + "vcpkg format-feature-baseline ") DECLARE_MESSAGE(CmdFormatManifestExample1, - (), - "This is a command line, only the s part should be localized", - "vcpkg format-manifest ") + (), + "This is a command line, only the s part should be localized", + "vcpkg format-manifest ") DECLARE_MESSAGE(CmdFormatManifestOptAll, (), "", "Formats all ports' manifest files") DECLARE_MESSAGE(CmdFormatManifestOptConvertControl, (), "", "Converts CONTROL files to manifest files") DECLARE_MESSAGE( - CmdGenerateMessageMapOptNoOutputComments, - (), - "", - "Excludes comments when generating the message map (useful for generating the English localization file)") + CmdGenerateMessageMapOptNoOutputComments, + (), + "", + "Excludes comments when generating the message map (useful for generating the English localization file)") DECLARE_MESSAGE(CmdFormatManifestSynopsis, (), "", "Prettyfies vcpkg.json") DECLARE_MESSAGE(CmdGenerateMSBuildPropsExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg generate-msbuild-props --msbuild-props ") + (), + "This is a command line, only the part should be localized", + "vcpkg generate-msbuild-props --msbuild-props ") DECLARE_MESSAGE(CmdGenerateMSBuildPropsExample2, - (), - "This is a command line, only the word 'out' should be localized", - "vcpkg generate-msbuild-props --msbuild-props out.props") -DECLARE_MESSAGE( - CmdGenerateMSBuildPropsSynopsis, - (), - "", - "Generates msbuild .props files as if activating a manifest's artifact dependencies, without acquiring them") + (), + "This is a command line, only the word 'out' should be localized", + "vcpkg generate-msbuild-props --msbuild-props out.props") +DECLARE_MESSAGE( + CmdGenerateMSBuildPropsSynopsis, + (), + "", + "Generates msbuild .props files as if activating a manifest's artifact dependencies, without acquiring them") DECLARE_MESSAGE(CmdHashExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg hash ") + (), + "This is a command line, only the part should be localized", + "vcpkg hash ") DECLARE_MESSAGE(CmdHashExample2, - (), - "This is a command line, only the part should be localized", - "vcpkg hash SHA256") + (), + "This is a command line, only the part should be localized", + "vcpkg hash SHA256") DECLARE_MESSAGE(CmdHashSynopsis, (), "", "Gets a file's SHA256 or SHA512") DECLARE_MESSAGE(CmdHelpCommands, (), "This is a command line, only should be localized.", "help ") DECLARE_MESSAGE(CmdHelpCommandSynopsis, (), "", "Displays help detail for ") @@ -748,95 +748,95 @@ DECLARE_MESSAGE(CmdHelpTopic, (), "This is a command line, only should b DECLARE_MESSAGE(CmdInfoOptInstalled, (), "", "(experimental) Reports installed packages rather than available") DECLARE_MESSAGE(CmdInfoOptTransitive, (), "", "(experimental) Also reports dependencies of installed packages") DECLARE_MESSAGE(CmdInitRegistryExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg x-init-registry ") + (), + "This is a command line, only the part should be localized", + "vcpkg x-init-registry ") DECLARE_MESSAGE(CmdInitRegistrySynopsis, (), "", "Creates a blank git registry") DECLARE_MESSAGE(CmdInstallExample1, - (), - "This is a command line, only the <> parts should be localized", - "vcpkg install ...") + (), + "This is a command line, only the <> parts should be localized", + "vcpkg install ...") DECLARE_MESSAGE(CmdIntegrateSynopsis, (), "", "Integrates vcpkg with machines, projects, or shells") DECLARE_MESSAGE(CmdLicenseReportSynopsis, (), "", "Displays the declared licenses of all ports in the installed tree") DECLARE_MESSAGE(CmdListExample2, - (), - "This is a command line, only the part should be localized", - "vcpkg list ") + (), + "This is a command line, only the part should be localized", + "vcpkg list ") DECLARE_MESSAGE(CmdNewExample1, - (), - "This is a command line, only the word example should be localized", - "vcpkg new --name=example --version=1.0") + (), + "This is a command line, only the word example should be localized", + "vcpkg new --name=example --version=1.0") DECLARE_MESSAGE(CmdNewOptApplication, (), "", "Creates an application manifest (don't require name or version)") DECLARE_MESSAGE(CmdNewOptSingleFile, (), "", "Embeds vcpkg-configuration.json into vcpkg.json") DECLARE_MESSAGE(CmdNewOptVersionDate, (), "", "Interprets --version as an ISO 8601 date. (YYYY-MM-DD)") DECLARE_MESSAGE(CmdNewOptVersionRelaxed, - (), - "", - "Interprets --version as a relaxed-numeric version (Nonnegative numbers separated by dots)") + (), + "", + "Interprets --version as a relaxed-numeric version (Nonnegative numbers separated by dots)") DECLARE_MESSAGE(CmdNewOptVersionString, (), "", "Interprets --version as a string with no ordering behavior") DECLARE_MESSAGE(CmdNewSettingName, (), "", "Name for the new manifest") DECLARE_MESSAGE(CmdNewSettingVersion, (), "", "Version for the new manifest") DECLARE_MESSAGE(CmdNewSynposis, (), "", "Creates a new manifest") DECLARE_MESSAGE(CmdOwnsExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg owns ") + (), + "This is a command line, only the part should be localized.", + "vcpkg owns ") DECLARE_MESSAGE(CmdOptForMergeWith, (), "", "test ports intended to merge with this git ref") DECLARE_MESSAGE(CmdPackageInfoExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg x-package-info ...") + (), + "This is a command line, only the part should be localized.", + "vcpkg x-package-info ...") DECLARE_MESSAGE(CmdPortsdiffExample1, - (), - "This is a command line, only the part should be localized", - "vcpkg portsdiff ") + (), + "This is a command line, only the part should be localized", + "vcpkg portsdiff ") DECLARE_MESSAGE(CmdPortsdiffExample2, - (), - "This is a command line, only the parts in <>s should be localized", - "vcpkg portsdiff ") + (), + "This is a command line, only the parts in <>s should be localized", + "vcpkg portsdiff ") DECLARE_MESSAGE(CmdPortsdiffSynopsis, (), "", "Diffs changes in port versions between commits") DECLARE_MESSAGE(CmdRegenerateOptDryRun, (), "", "Does not actually perform the action, shows only what would be done") DECLARE_MESSAGE(CmdRegenerateOptForce, (), "", "Proceeds with the (potentially dangerous) action without confirmation") DECLARE_MESSAGE(CmdRegenerateOptNormalize, (), "", "Applies any deprecation fixes") DECLARE_MESSAGE(CmdRemoveExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg remove ...") + (), + "This is a command line, only the part should be localized.", + "vcpkg remove ...") DECLARE_MESSAGE(CmdRemoveOptDryRun, (), "", "Prints the packages to be removed, but does not remove them") DECLARE_MESSAGE(CmdRemoveOptOutdated, - (), - "", - "Removes all packages with versions that do not match the built-in registry") + (), + "", + "Removes all packages with versions that do not match the built-in registry") DECLARE_MESSAGE(CmdRemoveOptRecurse, (), "", "Allows removal of dependent packages not explicitly specified") DECLARE_MESSAGE(CmdSearchExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg search ") + (), + "This is a command line, only the part should be localized.", + "vcpkg search ") DECLARE_MESSAGE(CmdSettingCopiedFilesLog, (), "", "Path to the copied files log to create") DECLARE_MESSAGE(CmdSettingInstalledDir, (), "", "Path to the installed tree to use") DECLARE_MESSAGE(CmdSettingTargetBin, (), "", "Path to the binary to analyze") DECLARE_MESSAGE(CmdSettingTLogFile, (), "", "Path to the tlog file to create") DECLARE_MESSAGE(CmdSetInstalledExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg x-set-installed ...") + (), + "This is a command line, only the part should be localized.", + "vcpkg x-set-installed ...") DECLARE_MESSAGE(CmdSetInstalledOptDryRun, (), "", "Does not actually build or install") DECLARE_MESSAGE(CmdSetInstalledOptNoUsage, (), "", "Does not print CMake usage information after install") DECLARE_MESSAGE(CmdSetInstalledOptWritePkgConfig, - (), - "'vcpkg help binarycaching' is a command line and should not be localized.", - "Writes a NuGet packages.config-formatted file for use with external binary caching. " - "See `vcpkg help binarycaching` for more information") + (), + "'vcpkg help binarycaching' is a command line and should not be localized.", + "Writes a NuGet packages.config-formatted file for use with external binary caching. " + "See `vcpkg help binarycaching` for more information") DECLARE_MESSAGE(CmdSetInstalledSynopsis, - (), - "", - "Installs, upgrades, or removes packages such that that installed matches exactly those supplied") + (), + "", + "Installs, upgrades, or removes packages such that that installed matches exactly those supplied") DECLARE_MESSAGE(CmdTestFeaturesAll, (), "", "Runs tests for all ports") DECLARE_MESSAGE( - CmdTestCIFeatureBaseline, - (), - "", - "Path to the ci.feature.baseline.txt file. Used to skip known failing tests ports and detect regressions") + CmdTestCIFeatureBaseline, + (), + "", + "Path to the ci.feature.baseline.txt file. Used to skip known failing tests ports and detect regressions") DECLARE_MESSAGE(CmdTestFeaturesFailingAbis, (), "", "Path to file to which all failing ABI hashes will be written") DECLARE_MESSAGE(CmdTestFeaturesNoCombined, (), "", "Skips testing every feature turned on") DECLARE_MESSAGE(CmdTestFeaturesNoCore, (), "", "Skips testing only the 'core' feature turned on") @@ -844,34 +844,34 @@ DECLARE_MESSAGE(CmdTestFeaturesNoSeparated, (), "", "Skips testing every feature DECLARE_MESSAGE(CmdTestFeaturesSynopsis, (), "", "Tests the features of a port") DECLARE_MESSAGE(CmdUpdateBaselineOptDryRun, (), "", "Prints out plan without execution") DECLARE_MESSAGE(CmdUpdateBaselineOptInitial, - (), - "", - "Adds a `builtin-baseline` to a vcpkg.json that doesn't already have it") + (), + "", + "Adds a `builtin-baseline` to a vcpkg.json that doesn't already have it") DECLARE_MESSAGE(CmdUpdateBaselineSynopsis, - (), - "", - "Updates baselines of git registries in a manifest to those registries' HEAD commit") + (), + "", + "Updates baselines of git registries in a manifest to those registries' HEAD commit") DECLARE_MESSAGE(CmdUpdateRegistryAll, (), "", "Updates all known artifact registries") DECLARE_MESSAGE(CmdUpdateRegistryAllExcludesTargets, - (), - "", - "Update registry --all cannot be used with a list of artifact registries") + (), + "", + "Update registry --all cannot be used with a list of artifact registries") DECLARE_MESSAGE(CmdUpdateRegistryExample3, - (), - "This is a command line, only the part should be localized.", - "vcpkg x-update-registry ") + (), + "This is a command line, only the part should be localized.", + "vcpkg x-update-registry ") DECLARE_MESSAGE(CmdUpdateRegistrySynopsis, (), "", "Re-downloads an artifact registry") DECLARE_MESSAGE(CmdUpdateRegistryAllOrTargets, - (), - "", - "Update registry requires either a list of artifact registry names or URiIs to update, or --all.") + (), + "", + "Update registry requires either a list of artifact registry names or URiIs to update, or --all.") DECLARE_MESSAGE(CmdUploadMetricsDeleteFileAfterUpload, (), "", "Delete metrics payload file after upload") DECLARE_MESSAGE(CmdUpgradeOptNoDryRun, (), "", "Actually upgrade") DECLARE_MESSAGE(CmdUpgradeOptNoKeepGoing, (), "", "Stop installing packages on failure") DECLARE_MESSAGE(CmdUseExample1, - (), - "This is a command line, only the part should be localized.", - "vcpkg use ") + (), + "This is a command line, only the part should be localized.", + "vcpkg use ") DECLARE_MESSAGE(CmdUseSynopsis, (), "", "Activate a single artifact in this shell") DECLARE_MESSAGE(CmdVSInstancesSynopsis, (), "", "Lists detected Visual Studio instances") DECLARE_MESSAGE(CmdXDownloadOptHeader, (), "", "Additional header to use when fetching from URLs") @@ -880,84 +880,84 @@ DECLARE_MESSAGE(CmdXDownloadOptSkipSha, (), "", "Skips check of SHA512 of the do DECLARE_MESSAGE(CmdXDownloadOptStore, (), "", "Stores the the file should father than fetching it") DECLARE_MESSAGE(CmdXDownloadOptUrl, (), "", "URL to download and store if missing from cache") DECLARE_MESSAGE( - CmdZApplocalSynopsis, - (), - "", - "Copies a binary's dependencies from the installed tree to where that binary's location for app-local deployment") + CmdZApplocalSynopsis, + (), + "", + "Copies a binary's dependencies from the installed tree to where that binary's location for app-local deployment") DECLARE_MESSAGE(CmdZExtractExample1, - (), - "This is a command line, only the parts in <>s should be localized", - "vcpkg z-extract ") + (), + "This is a command line, only the parts in <>s should be localized", + "vcpkg z-extract ") DECLARE_MESSAGE(CmdZExtractExample2, - (), - "This is a command line, the example archive 'source.zip' and the example output directory " - "'source_dir' should be localized", - "vcpkg z-extract source.zip source_dir --strip 2") + (), + "This is a command line, the example archive 'source.zip' and the example output directory " + "'source_dir' should be localized", + "vcpkg z-extract source.zip source_dir --strip 2") DECLARE_MESSAGE(CmdZExtractOptStrip, (), "", "The number of leading directories to strip from all paths") DECLARE_MESSAGE(CommandFailed, - (msg::command_line), - "", - "command:\n" - "{command_line}\n" - "failed with the following output:") + (msg::command_line), + "", + "command:\n" + "{command_line}\n" + "failed with the following output:") DECLARE_MESSAGE(CommunityTriplets, (), "", "Community Triplets:") DECLARE_MESSAGE(CompilerPath, (msg::path), "", "Compiler found: {path}") DECLARE_MESSAGE(ComputeAllAbis, (), "", "Computing all ABI hashes...") DECLARE_MESSAGE(ComputeInstallPlans, (msg::count), "", "Computing {count} install plans...") DECLARE_MESSAGE(ComputingInstallPlan, (), "", "Computing installation plan...") DECLARE_MESSAGE(ConfigurationErrorRegistriesWithoutBaseline, - (msg::path, msg::url), - "", - "The configuration defined in {path} is invalid.\n\n" - "Using registries requires that a baseline is set for the default registry or that the default " - "registry is null.\n\n" - "See {url} for more details.") + (msg::path, msg::url), + "", + "The configuration defined in {path} is invalid.\n\n" + "Using registries requires that a baseline is set for the default registry or that the default " + "registry is null.\n\n" + "See {url} for more details.") DECLARE_MESSAGE(ConfigurationNestedDemands, - (msg::json_field), - "", - "[\"{json_field}\"] contains a nested `demands` object (nested `demands` have no effect)") + (msg::json_field), + "", + "[\"{json_field}\"] contains a nested `demands` object (nested `demands` have no effect)") DECLARE_MESSAGE(ConflictingEmbeddedConfiguration, - (), - "", - "only one of {{\"configuration\", \"vcpkg-configuration\"}} may be used") + (), + "", + "only one of {{\"configuration\", \"vcpkg-configuration\"}} may be used") DECLARE_MESSAGE(ConflictingFiles, - (msg::path, msg::spec), - "", - "The following files are already installed in {path} and are in conflict with {spec}") + (msg::path, msg::spec), + "", + "The following files are already installed in {path} and are in conflict with {spec}") DECLARE_MESSAGE(ConsideredVersions, - (msg::version), - "", - "The following executables were considered but discarded because of the version " - "requirement of {version}:") + (msg::version), + "", + "The following executables were considered but discarded because of the version " + "requirement of {version}:") DECLARE_MESSAGE(ConstraintViolation, (), "", "Found a constraint violation:") DECLARE_MESSAGE(ContinueCodeUnitInStart, (), "", "found continue code unit in start position") DECLARE_MESSAGE(ControlCharacterInString, (), "", "Control character in string") DECLARE_MESSAGE(ControlSupportsMustBeAPlatformExpression, (), "", "\"Supports\" must be a platform expression") DECLARE_MESSAGE(CopyrightIsDir, - (), - "", - "this port sets ${{CURRENT_PACKAGES_DIR}}/share/${{PORT}}/copyright to a directory, but it should be a " - "file. Consider combining separate copyright files into one using vcpkg_install_copyright. To suppress " - "this message, add set(VCPKG_POLICY_SKIP_COPYRIGHT_CHECK enabled)") + (), + "", + "this port sets ${{CURRENT_PACKAGES_DIR}}/share/${{PORT}}/copyright to a directory, but it should be a " + "file. Consider combining separate copyright files into one using vcpkg_install_copyright. To suppress " + "this message, add set(VCPKG_POLICY_SKIP_COPYRIGHT_CHECK enabled)") DECLARE_MESSAGE(CorruptedDatabase, - (), - "", - "vcpkg's installation database corrupted. This is either a bug in vcpkg or something else has modified " - "the contents of the 'installed' directory in an unexpected way. You may be able to fix this by " - "deleting the 'installed' directory and reinstalling what you want to use. If this problem happens " - "consistently, please file a bug at https://github.com/microsoft/vcpkg .") + (), + "", + "vcpkg's installation database corrupted. This is either a bug in vcpkg or something else has modified " + "the contents of the 'installed' directory in an unexpected way. You may be able to fix this by " + "deleting the 'installed' directory and reinstalling what you want to use. If this problem happens " + "consistently, please file a bug at https://github.com/microsoft/vcpkg .") DECLARE_MESSAGE(CouldNotDeduceNuGetIdAndVersion, - (msg::path), - "", - "Could not deduce NuGet id and version from filename: {path}") + (msg::path), + "", + "Could not deduce NuGet id and version from filename: {path}") DECLARE_MESSAGE(CouldNotFindBaselineInCommit, - (msg::url, msg::commit_sha, msg::package_name), - "", - "Couldn't find baseline in {url} at {commit_sha} for {package_name}.") + (msg::url, msg::commit_sha, msg::package_name), + "", + "Couldn't find baseline in {url} at {commit_sha} for {package_name}.") DECLARE_MESSAGE(CouldNotFindGitTreeAtCommit, - (msg::package_name, msg::commit_sha), - "", - "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}") + (msg::package_name, msg::commit_sha), + "", + "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}") DECLARE_MESSAGE(CouldNotFindVersionDatabaseFile, (msg::path), "", "Couldn't find the versions database file: {path}") DECLARE_MESSAGE(CreatedNuGetPackage, (msg::path), "", "Created nupkg: {path}") DECLARE_MESSAGE(CreateFailureLogsDir, (msg::path), "", "Creating failure logs output directory {path}.") @@ -966,139 +966,135 @@ DECLARE_MESSAGE(CreatingNuGetPackage, (), "", "Creating NuGet package...") DECLARE_MESSAGE(CreatingZipArchive, (), "", "Creating zip archive...") DECLARE_MESSAGE(CreationFailed, (msg::path), "", "Creating {path} failed.") DECLARE_MESSAGE(CurlFailedGeneric, - (msg::exit_code, msg::error_msg), - "curl is the name of a program, see curl.se.", - "curl operation failed with error code {exit_code} ({error_msg}).") + (msg::exit_code, msg::error_msg), + "curl is the name of a program, see curl.se.", + "curl operation failed with error code {exit_code} ({error_msg}).") DECLARE_MESSAGE(CurlFailedGenericWithRetry, - (msg::exit_code, msg::error_msg, msg::count, msg::value), - "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", - "curl operation failed with error code {exit_code} ({error_msg}) retry {count} of {value}.") + (msg::exit_code, msg::error_msg, msg::count, msg::value), + "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", + "curl operation failed with error code {exit_code} ({error_msg}) retry {count} of {value}.") DECLARE_MESSAGE(CurlFailedHttpResponse, - (msg::exit_code), - "curl is the name of a program, see curl.se.", - "curl operation failed with HTTP response code {exit_code}.") + (msg::exit_code), + "curl is the name of a program, see curl.se.", + "curl operation failed with HTTP response code {exit_code}.") DECLARE_MESSAGE(CurlFailedHttpResponseWithRetry, - (msg::exit_code, msg::count, msg::value), - "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", - "curl operation failed with HTTP response code {exit_code} retry {count} of {value}.") + (msg::exit_code, msg::count, msg::value), + "curl is the name of a program, see curl.se. {value} is the maximum amount of retries.", + "curl operation failed with HTTP response code {exit_code} retry {count} of {value}.") DECLARE_MESSAGE(CurlFailedToPutHttp, - (msg::exit_code, msg::error_msg, msg::url, msg::value), - "curl is the name of a program, see curl.se. {value} is an HTTP status code", - "curl failed to put file to {url} with exit code {exit_code} ({error_msg}) and http code {value}.") + (msg::exit_code, msg::error_msg, msg::url, msg::value), + "curl is the name of a program, see curl.se. {value} is an HTTP status code", + "curl failed to put file to {url} with exit code {exit_code} ({error_msg}) and http code {value}.") DECLARE_MESSAGE(CurrentCommitBaseline, - (msg::commit_sha), - "", - "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{commit_sha}\"") + (msg::commit_sha), + "", + "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{commit_sha}\"") DECLARE_MESSAGE(CycleDetectedDuring, (msg::spec), "", "cycle detected during {spec}:") DECLARE_MESSAGE(DefaultBinaryCachePlatformCacheRequiresAbsolutePath, - (msg::path), - "", - "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be a directory (was: {path})") + (msg::path), + "", + "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be a directory (was: {path})") DECLARE_MESSAGE(DefaultBinaryCacheRequiresAbsolutePath, - (msg::path), - "", - "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be absolute (was: {path})") + (msg::path), + "", + "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be absolute (was: {path})") DECLARE_MESSAGE(DefaultBinaryCacheRequiresDirectory, - (msg::path), - "", - "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be a directory (was: {path})") + (msg::path), + "", + "Environment variable VCPKG_DEFAULT_BINARY_CACHE must be a directory (was: {path})") DECLARE_MESSAGE(DefaultFeatureCore, - (), - "The word \"core\" is an on-disk name that must not be localized.", - "the feature \"core\" turns off default features and thus can't be in the default features list") -DECLARE_MESSAGE( - DefaultFeatureDefault, - (), - "The word \"default\" is an on-disk name that must not be localized.", - "the feature \"default\" refers to the set of default features and thus can't be in the default features list") + (), + "The word \"core\" is an on-disk name that must not be localized.", + "the feature \"core\" turns off default features and thus can't be in the default features list") +DECLARE_MESSAGE( + DefaultFeatureDefault, + (), + "The word \"default\" is an on-disk name that must not be localized.", + "the feature \"default\" refers to the set of default features and thus can't be in the default features list") DECLARE_MESSAGE(DefaultFeatureIdentifier, (), "", "the names of default features must be identifiers") DECLARE_MESSAGE(DefaultFlag, (msg::option), "", "Defaulting to --{option} being on.") DECLARE_MESSAGE(DefaultRegistryIsArtifact, (), "", "The default registry cannot be an artifact registry.") DECLARE_MESSAGE( - DependencyFeatureCore, - (), - "The word \"core\" is an on-disk name that must not be localized. The \"default-features\" part is JSON " - "syntax that must be copied verbatim into the user's file.", - "the feature \"core\" cannot be in a dependency's feature list. To turn off default features, add " - "\"default-features\": false instead.") -DECLARE_MESSAGE( - DependencyFeatureDefault, - (), - "The word \"default\" is an on-disk name that must not be localized. The \"default-features\" part is JSON " - "syntax that must be copied verbatim into the user's file.", - "the feature \"default\" cannot be in a dependency's feature list. To turn on default features, add " - "\"default-features\": true instead.") + DependencyFeatureCore, + (), + "The word \"core\" is an on-disk name that must not be localized. The \"default-features\" part is JSON " + "syntax that must be copied verbatim into the user's file.", + "the feature \"core\" cannot be in a dependency's feature list. To turn off default features, add " + "\"default-features\": false instead.") +DECLARE_MESSAGE( + DependencyFeatureDefault, + (), + "The word \"default\" is an on-disk name that must not be localized. The \"default-features\" part is JSON " + "syntax that must be copied verbatim into the user's file.", + "the feature \"default\" cannot be in a dependency's feature list. To turn on default features, add " + "\"default-features\": true instead.") DECLARE_MESSAGE(DependencyGraphCalculation, (), "", "Dependency graph submission enabled.") DECLARE_MESSAGE(DependencyGraphFailure, (), "", "Dependency graph submission failed.") DECLARE_MESSAGE(DependencyGraphSuccess, (), "", "Dependency graph submission successful.") DECLARE_MESSAGE(DependencyInFeature, (msg::feature), "", "the dependency is in the feature named {feature}") DECLARE_MESSAGE(DependencyNotInVersionDatabase, - (msg::package_name), - "", - "the dependency {package_name} does not exist in the version database; does that port exist?") + (msg::package_name), + "", + "the dependency {package_name} does not exist in the version database; does that port exist?") DECLARE_MESSAGE(DependencyWillFail, - (msg::feature_spec), - "'cascade' is a keyword and should not be translated", - "Dependency {feature_spec} will not build => cascade") + (msg::feature_spec), + "'cascade' is a keyword and should not be translated", + "Dependency {feature_spec} will not build => cascade") DECLARE_MESSAGE(DetectCompilerHash, (msg::triplet), "", "Detecting compiler hash for triplet {triplet}...") DECLARE_MESSAGE(DirectoriesRelativeToThePackageDirectoryHere, - (), - "", - "the directories are relative to ${{CURRENT_PACKAGES_DIR}} here") + (), + "", + "the directories are relative to ${{CURRENT_PACKAGES_DIR}} here") DECLARE_MESSAGE(DllsRelativeToThePackageDirectoryHere, - (), - "", - "the DLLs are relative to ${{CURRENT_PACKAGES_DIR}} here") + (), + "", + "the DLLs are relative to ${{CURRENT_PACKAGES_DIR}} here") DECLARE_MESSAGE(DocumentedFieldsSuggestUpdate, - (), - "", - "If these are documented fields that should be recognized try updating the vcpkg tool.") + (), + "", + "If these are documented fields that should be recognized try updating the vcpkg tool.") DECLARE_MESSAGE(DownloadAvailable, - (msg::env_var), - "", - "A downloadable copy of this tool is available and can be used by unsetting {env_var}.") + (msg::env_var), + "", + "A downloadable copy of this tool is available and can be used by unsetting {env_var}.") DECLARE_MESSAGE(DownloadedSources, (msg::spec), "", "Downloaded sources for {spec}") DECLARE_MESSAGE(DownloadFailedHashMismatch, (msg::url), "", "download from {url} had an unexpected hash") DECLARE_MESSAGE(DownloadFailedHashMismatchActualHash, (msg::sha), "", "Actual : {sha}") DECLARE_MESSAGE(DownloadFailedHashMismatchExpectedHash, (msg::sha), "", "Expected: {sha}") DECLARE_MESSAGE( - DownloadFailedHashMismatchZero, - (msg::sha), - "", - "failing download because the expected SHA512 was all zeros, please change the expected SHA512 to: {sha}") -DECLARE_MESSAGE(DownloadFailedRetrying, - (msg::value, msg::url), - "{value} is a number of milliseconds", - "Download {url} failed -- retrying after {value}ms") + DownloadFailedHashMismatchZero, + (msg::sha), + "", + "failing download because the expected SHA512 was all zeros, please change the expected SHA512 to: {sha}") DECLARE_MESSAGE(DownloadFailedStatusCode, - (msg::url, msg::value), - "{value} is an HTTP status code", - "{url}: failed: status code {value}") -DECLARE_MESSAGE( - DownloadFailedProxySettings, - (), - "", - "If you are using a proxy, please ensure your proxy settings are correct.\n" - "Possible causes are:\n" - "1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to " - "`https//address:port`.\nThis is not correct, because `https://` prefix claims the proxy is an HTTPS " - "proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\n" - "Try setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n" - "2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your " - "proxy software. See: https://github.com/microsoft/vcpkg-tool/pull/77\n" - "The value set by your proxy might be wrong, or have same `https://` prefix issue.\n" - "3. Your proxy's remote server is out of service.\n" - "If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this " - "file from a different location, please submit an issue to https://github.com/Microsoft/vcpkg/issues") + (msg::url, msg::value), + "{value} is an HTTP status code", + "{url}: failed: status code {value}") +DECLARE_MESSAGE( + DownloadFailedProxySettings, + (), + "", + "If you are using a proxy, please ensure your proxy settings are correct.\n" + "Possible causes are:\n" + "1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to " + "`https//address:port`.\nThis is not correct, because `https://` prefix claims the proxy is an HTTPS " + "proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\n" + "Try setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n" + "2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your " + "proxy software. See: https://github.com/microsoft/vcpkg-tool/pull/77\n" + "The value set by your proxy might be wrong, or have same `https://` prefix issue.\n" + "3. Your proxy's remote server is out of service.\n" + "If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this " + "file from a different location, please submit an issue to https://github.com/Microsoft/vcpkg/issues") DECLARE_MESSAGE(DownloadingPortableToolVersionX, - (msg::tool_name, msg::version), - "", - "A suitable version of {tool_name} was not found (required v{version}).") + (msg::tool_name, msg::version), + "", + "A suitable version of {tool_name} was not found (required v{version}).") DECLARE_MESSAGE(DownloadingAssetShaToFile, (msg::sha, msg::path), "", "Downloading asset cache entry {sha} -> {path}") DECLARE_MESSAGE(DownloadingAssetShaWithoutAssetCache, - (msg::sha, msg::path), - "", - "requested download of asset cache entry {sha} -> {path}, but no asset caches are configured") + (msg::sha, msg::path), + "", + "requested download of asset cache entry {sha} -> {path}, but no asset caches are configured") DECLARE_MESSAGE(DownloadingFile, (msg::path), "", "Downloading {path}") DECLARE_MESSAGE(DownloadingFileFirstAuthoritativeSource, (msg::path, msg::url), "", "Downloading {path}, trying {url}") DECLARE_MESSAGE(DownloadingUrlToFile, (msg::url, msg::path), "", "Downloading {url} -> {path}") @@ -1110,18 +1106,14 @@ DECLARE_MESSAGE(DownloadTryingAuthoritativeSource, (msg::url), "", "Trying {url} DECLARE_MESSAGE(DownloadRootsDir, (msg::env_var), "", "Downloads directory (default: {env_var})") DECLARE_MESSAGE(DownloadSuccesful, (msg::path), "", "Successfully downloaded {path}") DECLARE_MESSAGE(DownloadSuccesfulUploading, - (msg::path, msg::url), - "", - "Successfully downloaded {path}, storing to {url}") -DECLARE_MESSAGE(DownloadWinHttpError, - (msg::system_api, msg::exit_code, msg::url), - "", - "{url}: {system_api} failed with exit code {exit_code}.") + (msg::path, msg::url), + "", + "Successfully downloaded {path}, storing to {url}") DECLARE_MESSAGE(DuplicateDependencyOverride, (msg::package_name), "", "{package_name} already has an override") DECLARE_MESSAGE(DuplicatedKeyInObj, - (msg::value), - "{value} is a json property/object", - "Duplicated key \"{value}\" in an object") + (msg::value), + "{value} is a json property/object", + "Duplicated key \"{value}\" in an object") DECLARE_MESSAGE(DuplicatePackagePattern, (msg::package_name), "", "Package \"{package_name}\" is duplicated.") DECLARE_MESSAGE(DuplicatePackagePatternFirstOcurrence, (), "", "First declared in:") DECLARE_MESSAGE(DuplicatePackagePatternIgnoredLocations, (), "", "The following redeclarations will be ignored:") @@ -1133,85 +1125,85 @@ DECLARE_MESSAGE(EmailVcpkgTeam, (msg::url), "", "Send an email to {url} with any DECLARE_MESSAGE(EmptyLicenseExpression, (), "", "SPDX license expression was empty.") DECLARE_MESSAGE(EndOfStringInCodeUnit, (), "", "found end of string in middle of code point") DECLARE_MESSAGE(EnvInvalidMaxConcurrency, - (msg::env_var, msg::value), - "{value} is the invalid value of an environment variable", - "{env_var} is {value}, must be > 0") + (msg::env_var, msg::value), + "{value} is the invalid value of an environment variable", + "{env_var} is {value}, must be > 0") DECLARE_MESSAGE(EnvStrFailedToExtract, (), "", "could not expand the environment string:") DECLARE_MESSAGE(EnvPlatformNotSupported, (), "", "Build environment commands are not supported on this platform") DECLARE_MESSAGE(EnvVarMustBeAbsolutePath, (msg::path, msg::env_var), "", "{env_var} ({path}) was not an absolute path") DECLARE_MESSAGE(ErrorDetectingCompilerInfo, - (msg::path), - "", - "while detecting compiler information:\nThe log file content at \"{path}\" is:") + (msg::path), + "", + "while detecting compiler information:\nThe log file content at \"{path}\" is:") DECLARE_MESSAGE(ErrorIndividualPackagesUnsupported, - (), - "", - "In manifest mode, `vcpkg install` does not support individual package arguments.\nTo install " - "additional packages, edit vcpkg.json and then run `vcpkg install` without any package arguments.") + (), + "", + "In manifest mode, `vcpkg install` does not support individual package arguments.\nTo install " + "additional packages, edit vcpkg.json and then run `vcpkg install` without any package arguments.") DECLARE_MESSAGE(ErrorInvalidClassicModeOption, - (msg::option), - "", - "The option --{option} is not supported in classic mode and no manifest was found.") + (msg::option), + "", + "The option --{option} is not supported in classic mode and no manifest was found.") DECLARE_MESSAGE(ErrorInvalidManifestModeOption, - (msg::option), - "", - "The option --{option} is not supported in manifest mode.") + (msg::option), + "", + "The option --{option} is not supported in manifest mode.") DECLARE_MESSAGE(ErrorManifestMustDifferFromOverlay, - (msg::path), - "", - "The manifest directory ({path}) cannot be the same as a directory configured in overlay-ports.") + (msg::path), + "", + "The manifest directory ({path}) cannot be the same as a directory configured in overlay-ports.") DECLARE_MESSAGE(ErrorManifestMustDifferFromOverlayDot, - (), - "", - "The manifest directory cannot be the same as a directory configured in overlay-ports, so " - "\"overlay-ports\" values cannot be \".\".") -DECLARE_MESSAGE( - ErrorMissingVcpkgRoot, - (), - "", - "Could not detect vcpkg-root. If you are trying to use a copy of vcpkg that you've built, you must " - "define the VCPKG_ROOT environment variable to point to a cloned copy of https://github.com/Microsoft/vcpkg.") + (), + "", + "The manifest directory cannot be the same as a directory configured in overlay-ports, so " + "\"overlay-ports\" values cannot be \".\".") +DECLARE_MESSAGE( + ErrorMissingVcpkgRoot, + (), + "", + "Could not detect vcpkg-root. If you are trying to use a copy of vcpkg that you've built, you must " + "define the VCPKG_ROOT environment variable to point to a cloned copy of https://github.com/Microsoft/vcpkg.") DECLARE_MESSAGE(ErrorNoVSInstance, - (msg::triplet), - "", - "in triplet {triplet}: Unable to find a valid Visual Studio instance") + (msg::triplet), + "", + "in triplet {triplet}: Unable to find a valid Visual Studio instance") DECLARE_MESSAGE(ErrorNoVSInstanceAt, (msg::path), "", "at \"{path}\"") DECLARE_MESSAGE(ErrorNoVSInstanceFullVersion, (msg::version), "", "with toolset version prefix {version}") DECLARE_MESSAGE(ErrorNoVSInstanceVersion, (msg::version), "", "with toolset version {version}") DECLARE_MESSAGE(ErrorParsingBinaryParagraph, (msg::spec), "", "while parsing the Binary Paragraph for {spec}") DECLARE_MESSAGE(ErrorRequireBaseline, - (), - "", - "this vcpkg instance requires a manifest with a specified baseline in order to " - "interact with ports. Please add 'builtin-baseline' to the manifest or add a " - "'vcpkg-configuration.json' that redefines the default registry.") + (), + "", + "this vcpkg instance requires a manifest with a specified baseline in order to " + "interact with ports. Please add 'builtin-baseline' to the manifest or add a " + "'vcpkg-configuration.json' that redefines the default registry.") DECLARE_MESSAGE(ErrorRequirePackagesList, - (), - "", - "`vcpkg install` requires a list of packages to install in classic mode.") + (), + "", + "`vcpkg install` requires a list of packages to install in classic mode.") DECLARE_MESSAGE(ErrorInvalidExtractOption, - (msg::option, msg::value), - "The keyword 'AUTO' should not be localized", - "--{option} must be set to a nonnegative integer or 'AUTO'.") + (msg::option, msg::value), + "The keyword 'AUTO' should not be localized", + "--{option} must be set to a nonnegative integer or 'AUTO'.") DECLARE_MESSAGE(ErrorUnableToDetectCompilerInfo, - (), - "failure output will be displayed at the top of this", - "vcpkg was unable to detect the active compiler's information. See above for the CMake failure output.") + (), + "failure output will be displayed at the top of this", + "vcpkg was unable to detect the active compiler's information. See above for the CMake failure output.") DECLARE_MESSAGE(ErrorVcvarsUnsupported, - (msg::triplet), - "", - "in triplet {triplet}: Use of Visual Studio's Developer Prompt is unsupported " - "on non-Windows hosts.\nDefine 'VCPKG_CMAKE_SYSTEM_NAME' or " - "'VCPKG_CHAINLOAD_TOOLCHAIN_FILE' in the triplet file.") + (msg::triplet), + "", + "in triplet {triplet}: Use of Visual Studio's Developer Prompt is unsupported " + "on non-Windows hosts.\nDefine 'VCPKG_CMAKE_SYSTEM_NAME' or " + "'VCPKG_CHAINLOAD_TOOLCHAIN_FILE' in the triplet file.") DECLARE_MESSAGE(ErrorVsCodeNotFound, - (msg::env_var), - "", - "Visual Studio Code was not found and the environment variable {env_var} is not set or invalid.") + (msg::env_var), + "", + "Visual Studio Code was not found and the environment variable {env_var} is not set or invalid.") DECLARE_MESSAGE(ErrorVsCodeNotFoundPathExamined, (), "", "The following paths were examined:") DECLARE_MESSAGE(ErrorWhileFetchingBaseline, - (msg::value, msg::package_name), - "{value} is a commit sha.", - "while fetching baseline `\"{value}\"` from repo {package_name}:") + (msg::value, msg::package_name), + "{value} is a commit sha.", + "while fetching baseline `\"{value}\"` from repo {package_name}:") DECLARE_MESSAGE(ErrorWhileParsing, (msg::path), "", "Errors occurred while parsing {path}.") DECLARE_MESSAGE(ErrorWhileWriting, (msg::path), "", "Error occurred while writing {path}.") DECLARE_MESSAGE(ExamplesHeader, (), "Printed before a list of example command lines", "Examples:") @@ -1219,52 +1211,52 @@ DECLARE_MESSAGE(ExceededRecursionDepth, (), "", "Recursion depth exceeded.") DECLARE_MESSAGE(ExcludedPackage, (msg::spec), "", "Excluded {spec}") DECLARE_MESSAGE(ExcludedPackages, (), "", "The following packages are excluded:") DECLARE_MESSAGE(ExecutablesRelativeToThePackageDirectoryHere, - (), - "", - "the executables are relative to ${{CURRENT_PACKAGES_DIR}} here") + (), + "", + "the executables are relative to ${{CURRENT_PACKAGES_DIR}} here") DECLARE_MESSAGE(ExpectedAnObject, (), "", "expected an object") DECLARE_MESSAGE(ExpectedAtMostOneSetOfTags, - (msg::count, msg::old_value, msg::new_value, msg::value), - "{old_value} is a left tag and {new_value} is the right tag. {value} is the input.", - "Found {count} sets of {old_value}.*{new_value} but expected at most 1, in block:\n{value}") + (msg::count, msg::old_value, msg::new_value, msg::value), + "{old_value} is a left tag and {new_value} is the right tag. {value} is the input.", + "Found {count} sets of {old_value}.*{new_value} but expected at most 1, in block:\n{value}") DECLARE_MESSAGE(ExpectedCharacterHere, - (msg::expected), - "{expected} is a locale-invariant delimiter; for example, the ':' or '=' in 'zlib:x64-windows=skip'", - "expected '{expected}' here") + (msg::expected), + "{expected} is a locale-invariant delimiter; for example, the ':' or '=' in 'zlib:x64-windows=skip'", + "expected '{expected}' here") DECLARE_MESSAGE(ExpectedDefaultFeaturesList, (), "", "expected ',' or end of text in default features list") DECLARE_MESSAGE(ExpectedDependenciesList, (), "", "expected ',' or end of text in dependencies list") DECLARE_MESSAGE(ExpectedDigitsAfterDecimal, (), "", "Expected digits after the decimal point") DECLARE_MESSAGE(ExpectedFailSkipOrPass, (), "", "expected 'fail', 'skip', or 'pass' here") DECLARE_MESSAGE(ExpectedFeatureBaselineState, - (), - "", - "expected 'fail', 'skip', 'pass', 'cascade', 'no-separate-feature-test', 'options', 'feature-fails', " - "or 'combination-fails' here") + (), + "", + "expected 'fail', 'skip', 'pass', 'cascade', 'no-separate-feature-test', 'options', 'feature-fails', " + "or 'combination-fails' here") DECLARE_MESSAGE(ExpectedFeatureListTerminal, (), "", "expected ',' or ']' in feature list") DECLARE_MESSAGE(ExpectedFeatureName, (), "", "expected feature name (must be lowercase, digits, '-')") DECLARE_MESSAGE(ExpectedExplicitTriplet, (), "", "expected an explicit triplet") DECLARE_MESSAGE(ExpectedInstallStateField, - (), - "The values in ''s are locale-invariant", - "expected one of 'not-installed', 'half-installed', or 'installed'") + (), + "The values in ''s are locale-invariant", + "expected one of 'not-installed', 'half-installed', or 'installed'") DECLARE_MESSAGE(ExpectedOneSetOfTags, - (msg::count, msg::old_value, msg::new_value, msg::value), - "{old_value} is a left tag and {new_value} is the right tag. {value} is the input.", - "Found {count} sets of {old_value}.*{new_value} but expected exactly 1, in block:\n{value}") + (msg::count, msg::old_value, msg::new_value, msg::value), + "{old_value} is a left tag and {new_value} is the right tag. {value} is the input.", + "Found {count} sets of {old_value}.*{new_value} but expected exactly 1, in block:\n{value}") DECLARE_MESSAGE(ExpectedOneVersioningField, (), "", "expected only one versioning field") DECLARE_MESSAGE(ExpectedPathToExist, (msg::path), "", "Expected {path} to exist after fetching") DECLARE_MESSAGE(ExpectedPortName, (), "", "expected a port name here (must be lowercase, digits, '-')") DECLARE_MESSAGE(ExpectedReadWriteReadWrite, (), "", "unexpected argument: expected 'read', readwrite', or 'write'") DECLARE_MESSAGE(ExpectedStatusField, (), "", "Expected 'status' field in status paragraph") DECLARE_MESSAGE(ExpectedTextHere, - (msg::expected), - "{expected} is a locale-invariant string a parser was searching for", - "expected '{expected}' here") + (msg::expected), + "{expected} is a locale-invariant string a parser was searching for", + "expected '{expected}' here") DECLARE_MESSAGE(ExpectedTripletName, (), "", "expected a triplet name here (must be lowercase, digits, '-')") DECLARE_MESSAGE(ExpectedWantField, - (), - "The values in ''s are locale-invariant", - "expected one of 'install', 'hold', 'deinstall', or 'purge' here") + (), + "The values in ''s are locale-invariant", + "expected one of 'install', 'hold', 'deinstall', or 'purge' here") DECLARE_MESSAGE(Exported7zipArchive, (msg::path), "", "7zip archive exported at: {path}") DECLARE_MESSAGE(ExportedZipArchive, (msg::path), "", "Zip archive exported at: {path}") DECLARE_MESSAGE(ExportingAlreadyBuiltPackages, (), "", "The following packages are already built and will be exported:") @@ -1274,91 +1266,91 @@ DECLARE_MESSAGE(ExtractedInto, (msg::path), "", "extracted into {path}") DECLARE_MESSAGE(ExtractHelp, (), "", "Extracts an archive.") DECLARE_MESSAGE(ExtractingTool, (msg::tool_name), "", "Extracting {tool_name}...") DECLARE_MESSAGE(FailedPostBuildChecks, - (msg::count), - "", - "Found {count} post-build check problem(s). These are usually caused by bugs in portfile.cmake or the " - "upstream build system. Please correct these before submitting this port to the curated registry.") + (msg::count), + "", + "Found {count} post-build check problem(s). These are usually caused by bugs in portfile.cmake or the " + "upstream build system. Please correct these before submitting this port to the curated registry.") DECLARE_MESSAGE(FailedToAcquireMutant, - (msg::path), - "'mutant' is the Windows kernel object returned by CreateMutexW", - "failed to acquire mutant {path}") + (msg::path), + "'mutant' is the Windows kernel object returned by CreateMutexW", + "failed to acquire mutant {path}") DECLARE_MESSAGE(FailedToCheckoutRepo, - (msg::package_name), - "", - "failed to check out `versions` from repo {package_name}") + (msg::package_name), + "", + "failed to check out `versions` from repo {package_name}") DECLARE_MESSAGE(FailedToDeleteDueToFile, - (msg::value, msg::path), - "{value} is the parent path of {path} we tried to delete; the underlying Windows error message is " - "printed after this", - "failed to remove_all({value}) due to {path}: ") + (msg::value, msg::path), + "{value} is the parent path of {path} we tried to delete; the underlying Windows error message is " + "printed after this", + "failed to remove_all({value}) due to {path}: ") DECLARE_MESSAGE(FailedToDeleteDueToFile2, (msg::path), "", "failed to remove due to {path}") DECLARE_MESSAGE(FailedToDeleteInsideDueToFile, - (msg::value, msg::path), - "{value} is the parent path of {path} we tried to delete; the underlying Windows error message is " - "printed after this", - "failed to remove_all_inside({value}) due to {path}: ") + (msg::value, msg::path), + "{value} is the parent path of {path} we tried to delete; the underlying Windows error message is " + "printed after this", + "failed to remove_all_inside({value}) due to {path}: ") DECLARE_MESSAGE(FailedToDetermineCurrentCommit, (), "", "Failed to determine the current commit:") DECLARE_MESSAGE(MissingShaVariable, - (), - "{{sha}} should not be translated", - "The {{sha}} variable must be used in the template if other variables are used.") + (), + "{{sha}} should not be translated", + "The {{sha}} variable must be used in the template if other variables are used.") DECLARE_MESSAGE(FailedToExtract, (msg::path), "", "Failed to extract \"{path}\":") DECLARE_MESSAGE(FailedToFetchRepo, (msg::url), "", "Failed to fetch {url}.") DECLARE_MESSAGE(FailedToFindPortFeature, - (msg::feature, msg::package_name), - "", - "{package_name} has no feature named {feature}.") + (msg::feature, msg::package_name), + "", + "{package_name} has no feature named {feature}.") DECLARE_MESSAGE(FailedToFormatMissingFile, - (), - "", - "No files to format.\nPlease pass either --all, or the explicit files to format or convert.") -DECLARE_MESSAGE( - FailedToLoadInstalledManifest, - (msg::package_name), - "", - "The control or manifest file for {package_name} could not be loaded due to the following error. Please " - "remove {package_name} and try again.") + (), + "", + "No files to format.\nPlease pass either --all, or the explicit files to format or convert.") +DECLARE_MESSAGE( + FailedToLoadInstalledManifest, + (msg::package_name), + "", + "The control or manifest file for {package_name} could not be loaded due to the following error. Please " + "remove {package_name} and try again.") DECLARE_MESSAGE(FailedToLoadManifest, (msg::path), "", "Failed to load manifest from directory {path}") DECLARE_MESSAGE(FailedToLocateSpec, (msg::spec), "", "Failed to locate spec in graph: {spec}") DECLARE_MESSAGE(FailedToOpenAlgorithm, - (msg::value), - "{value} is a crypto algorithm like SHA-1 or SHA-512", - "failed to open {value}") + (msg::value), + "{value} is a crypto algorithm like SHA-1 or SHA-512", + "failed to open {value}") DECLARE_MESSAGE(FailedToParseCMakeConsoleOut, - (), - "", - "Failed to parse CMake console output to locate block start/end markers.") + (), + "", + "Failed to parse CMake console output to locate block start/end markers.") DECLARE_MESSAGE(FailedToParseBaseline, (msg::path), "", "Failed to parse baseline: {path}") DECLARE_MESSAGE(FailedToParseConfig, (), "", "failed to parse configuration") DECLARE_MESSAGE(FailedToParseNoTopLevelObj, (msg::path), "", "Failed to parse {path}, expected a top-level object.") DECLARE_MESSAGE(FailedToParseNoVersionsArray, (msg::path), "", "Failed to parse {path}, expected a 'versions' array.") DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, - (msg::error_msg), - "'{error_msg}' is the error message for failing to parse the Binary Paragraph.", - "[sanity check] Failed to parse a serialized binary paragraph.\nPlease open an issue at " - "https://github.com/microsoft/vcpkg, " - "with the following output:\n{error_msg}\nSerialized Binary Paragraph:") + (msg::error_msg), + "'{error_msg}' is the error message for failing to parse the Binary Paragraph.", + "[sanity check] Failed to parse a serialized binary paragraph.\nPlease open an issue at " + "https://github.com/microsoft/vcpkg, " + "with the following output:\n{error_msg}\nSerialized Binary Paragraph:") DECLARE_MESSAGE(FailedToRunToolToDetermineVersion, - (msg::tool_name, msg::path), - "Additional information, such as the command line output, if any, will be appended on " - "the line after this message", - "Failed to run \"{path}\" to determine the {tool_name} version.") + (msg::tool_name, msg::path), + "Additional information, such as the command line output, if any, will be appended on " + "the line after this message", + "Failed to run \"{path}\" to determine the {tool_name} version.") DECLARE_MESSAGE(FailedToStoreBackToMirror, (msg::path, msg::url), "", "Failed to store {path} to {url}.") DECLARE_MESSAGE(FailedToStoreBinaryCache, (msg::path), "", "Failed to store binary cache {path}") DECLARE_MESSAGE(FailedToTakeFileSystemLock, (), "", "Failed to take the filesystem lock") DECLARE_MESSAGE(FailedVendorAuthentication, - (msg::vendor, msg::url), - "", - "One or more {vendor} credential providers failed to authenticate. See '{url}' for more details " - "on how to provide credentials.") + (msg::vendor, msg::url), + "", + "One or more {vendor} credential providers failed to authenticate. See '{url}' for more details " + "on how to provide credentials.") DECLARE_MESSAGE(FeatureBaselineEntryAlreadySpecified, - (msg::feature, msg::value), - "{value} is a keyword", - "'{feature}' was already declared as '{value}'") + (msg::feature, msg::value), + "{value} is a keyword", + "'{feature}' was already declared as '{value}'") DECLARE_MESSAGE(FeatureBaselineExpectedFeatures, - (msg::value), - "{value} is a keyword", - "When using '{value}' a list of features must be specified.") + (msg::value), + "{value} is a keyword", + "When using '{value}' a list of features must be specified.") DECLARE_MESSAGE(FeatureBaselineFormatted, (), "", "Succeeded in formatting the feature baseline file.") DECLARE_MESSAGE(FeatureBaselineNoFeaturesForFail, (), "", "When using '= fail' no list of features is allowed.") DECLARE_MESSAGE(FeatureBaselineNoFeaturesForPass, (), "", "When using '= pass' no list of features is allowed.") @@ -1366,937 +1358,937 @@ DECLARE_MESSAGE(FeatureTestProblems, (), "", "There are some feature test proble DECLARE_MESSAGE(FileIsNotExecutable, (), "", "this file does not appear to be executable") DECLARE_MESSAGE(FilesRelativeToTheBuildDirectoryHere, (), "", "the files are relative to the build directory here") DECLARE_MESSAGE(FilesRelativeToThePackageDirectoryHere, - (), - "", - "the files are relative to ${{CURRENT_PACKAGES_DIR}} here") + (), + "", + "the files are relative to ${{CURRENT_PACKAGES_DIR}} here") DECLARE_MESSAGE(FilesContainAbsolutePath1, - (), - "This message is printed before a list of found absolute paths, followed by FilesContainAbsolutePath2, " - "followed by a list of found files.", - "There should be no absolute paths, such as the following, in an installed package. To suppress this " - "message, add set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)") + (), + "This message is printed before a list of found absolute paths, followed by FilesContainAbsolutePath2, " + "followed by a list of found files.", + "There should be no absolute paths, such as the following, in an installed package. To suppress this " + "message, add set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)") DECLARE_MESSAGE(FilesContainAbsolutePath2, (), "", "absolute paths found here") DECLARE_MESSAGE(FilesContainAbsolutePathPkgconfigNote, - (), - "", - "Adding a call to `vcpkg_fixup_pkgconfig()` may fix absolute paths in .pc files") + (), + "", + "Adding a call to `vcpkg_fixup_pkgconfig()` may fix absolute paths in .pc files") DECLARE_MESSAGE(FindVersionArtifactsOnly, - (), - "'--version', 'vcpkg search', and 'vcpkg find port' are command lines that must not be localized", - "--version can't be used with vcpkg search or vcpkg find port") + (), + "'--version', 'vcpkg search', and 'vcpkg find port' are command lines that must not be localized", + "--version can't be used with vcpkg search or vcpkg find port") DECLARE_MESSAGE(FieldKindDidNotHaveExpectedValue, - (msg::expected, msg::actual), - "{expected} is a list of literal kinds the user must type, separated by commas, {actual} is what " - "the user supplied", - "\"kind\" did not have an expected value: (expected one of: {expected}; found {actual})") + (msg::expected, msg::actual), + "{expected} is a list of literal kinds the user must type, separated by commas, {actual} is what " + "the user supplied", + "\"kind\" did not have an expected value: (expected one of: {expected}; found {actual})") DECLARE_MESSAGE(FetchingBaselineInfo, (msg::package_name), "", "Fetching baseline information from {package_name}...") DECLARE_MESSAGE(FetchingRegistryInfo, - (msg::url, msg::value), - "{value} is a reference", - "Fetching registry information from {url} ({value})...") + (msg::url, msg::value), + "{value} is a reference", + "Fetching registry information from {url} ({value})...") DECLARE_MESSAGE(FileNotFound, (), "", "file not found") DECLARE_MESSAGE(FileReadFailed, - (msg::path, msg::byte_offset, msg::count), - "", - "Failed to read {count} bytes from {path} at offset {byte_offset}.") + (msg::path, msg::byte_offset, msg::count), + "", + "Failed to read {count} bytes from {path} at offset {byte_offset}.") DECLARE_MESSAGE(FileSeekFailed, - (msg::path, msg::byte_offset), - "", - "Failed to seek to position {byte_offset} in {path}.") + (msg::path, msg::byte_offset), + "", + "Failed to seek to position {byte_offset} in {path}.") DECLARE_MESSAGE(FilesExported, (msg::path), "", "Files exported at: {path}") DECLARE_MESSAGE(FindCommandFirstArg, - (), - "'find', 'artifact', and 'port' are vcpkg specific terms and should not be translated.", - "The first argument to 'find' must be 'artifact' or 'port' .") + (), + "'find', 'artifact', and 'port' are vcpkg specific terms and should not be translated.", + "The first argument to 'find' must be 'artifact' or 'port' .") DECLARE_MESSAGE(FishCompletion, (msg::path), "", "vcpkg fish completion is already added at \"{path}\".") DECLARE_MESSAGE(FixedEntriesInFile, (msg::count, msg::path), "", "Fixed {count} entries in {path}.") DECLARE_MESSAGE(FloatingPointConstTooBig, (msg::count), "", "Floating point constant too big: {count}") DECLARE_MESSAGE(FollowingPackagesMissingControl, - (), - "", - "The following packages do not have a valid CONTROL or vcpkg.json:") + (), + "", + "The following packages do not have a valid CONTROL or vcpkg.json:") DECLARE_MESSAGE(FollowingPackagesNotInstalled, (), "", "The following packages are not installed:") DECLARE_MESSAGE(FollowingPackagesUpgraded, (), "", "The following packages are up-to-date:") DECLARE_MESSAGE( - ForceSystemBinariesOnWeirdPlatforms, - (), - "", - "Environment variable VCPKG_FORCE_SYSTEM_BINARIES must be set on arm, s390x, ppc64le and riscv platforms.") + ForceSystemBinariesOnWeirdPlatforms, + (), + "", + "Environment variable VCPKG_FORCE_SYSTEM_BINARIES must be set on arm, s390x, ppc64le and riscv platforms.") DECLARE_MESSAGE(ForceClassicMode, (), "", "Force classic mode, even if a manifest could be found.") DECLARE_MESSAGE(FormattedParseMessageExpressionPrefix, (), "", "on expression:") DECLARE_MESSAGE(ForMergeWithTestingTheFollowing, - (msg::value), - "{value} is what the user entered as the target git ref", - "--for-merge-with {value} is testing:") + (msg::value), + "{value} is what the user entered as the target git ref", + "--for-merge-with {value} is testing:") DECLARE_MESSAGE(ForMoreHelp, - (), - "Printed before a suggestion for the user to run `vcpkg help `", - "For More Help") + (), + "Printed before a suggestion for the user to run `vcpkg help `", + "For More Help") DECLARE_MESSAGE(GetParseFailureInfo, (), "", "Use '--debug' to get more information about the parse failures.") DECLARE_MESSAGE(GhaBinaryCacheDeprecated, - (msg::url), - "The term 'x-gha' is a vcpkg configuration option", - "The 'x-gha' binary caching backend has been removed. Consider using a NuGet-based binary caching " - "provider instead, see extended documentation at {url}.") + (msg::url), + "The term 'x-gha' is a vcpkg configuration option", + "The 'x-gha' binary caching backend has been removed. Consider using a NuGet-based binary caching " + "provider instead, see extended documentation at {url}.") DECLARE_MESSAGE(GitCommandFailed, (msg::command_line), "", "failed to execute: {command_line}") DECLARE_MESSAGE(GitCommitUpdateVersionDatabase, - (), - "This is a command line; only the 'update version database' part should be localized", - "git commit -m \"Update version database\"") + (), + "This is a command line; only the 'update version database' part should be localized", + "git commit -m \"Update version database\"") DECLARE_MESSAGE(GitFailedToFetch, - (msg::value, msg::url), - "{value} is a git ref like 'origin/main'", - "failed to fetch ref {value} from repository {url}") + (msg::value, msg::url), + "{value} is a git ref like 'origin/main'", + "failed to fetch ref {value} from repository {url}") DECLARE_MESSAGE(GitFailedToInitializeLocalRepository, (msg::path), "", "failed to initialize local repository {path}") DECLARE_MESSAGE( - GitRegistryMustHaveBaseline, - (msg::url, msg::commit_sha), - "", - "The git registry \"{url}\" must have a \"baseline\" field that is a valid git commit SHA (40 hexadecimal " - "characters).\nTo use the current latest versions, set baseline to that repo's HEAD, \"{commit_sha}\".") + GitRegistryMustHaveBaseline, + (msg::url, msg::commit_sha), + "", + "The git registry \"{url}\" must have a \"baseline\" field that is a valid git commit SHA (40 hexadecimal " + "characters).\nTo use the current latest versions, set baseline to that repo's HEAD, \"{commit_sha}\".") DECLARE_MESSAGE(GitUnexpectedCommandOutputCmd, - (msg::command_line), - "", - "git produced unexpected output when running {command_line}") + (msg::command_line), + "", + "git produced unexpected output when running {command_line}") DECLARE_MESSAGE(GraphCycleDetected, - (msg::package_name), - "A list of package names comprising the cycle will be printed after this message.", - "Cycle detected within graph at {package_name}:") + (msg::package_name), + "A list of package names comprising the cycle will be printed after this message.", + "Cycle detected within graph at {package_name}:") DECLARE_MESSAGE(HashPortManyFiles, - (msg::package_name, msg::count), - "", - "{package_name} contains {count} files. Hashing these contents may take a long time when " - "determining the ABI hash for binary caching. Consider reducing the number of files. Common causes of " - "this are accidentally checking out source or build files into a port's directory.") + (msg::package_name, msg::count), + "", + "{package_name} contains {count} files. Hashing these contents may take a long time when " + "determining the ABI hash for binary caching. Consider reducing the number of files. Common causes of " + "this are accidentally checking out source or build files into a port's directory.") DECLARE_MESSAGE(HeaderOnlyUsage, - (msg::package_name), - "'header' refers to C/C++ .h files", - "{package_name} is header-only and can be used from CMake via:") -DECLARE_MESSAGE( - HelpAssetCaching, - (), - "The '' part references code in the following table and should not be localized. The matching values " - "\"read\" \"write\" and \"readwrite\" are also fixed. After this block a table with each possible asset " - "caching source is printed.", - "**Experimental feature: this may change or be removed at any time**\n" - "\n" - "vcpkg can use mirrors to cache downloaded assets, ensuring continued operation even if the " - "original source changes or disappears.\n" - "\n" - "Asset caching can be configured either by setting the environment variable X_VCPKG_ASSET_SOURCES " - "to a semicolon-delimited list of sources or by passing a sequence of " - "--x-asset-sources= command line options. Command line sources are interpreted after " - "environment sources. Commas, semicolons, and backticks can be escaped using backtick (`).\n" - "\n" - "The optional parameter for certain strings controls how they will be accessed. It can be specified as " - "\"read\", \"write\", or \"readwrite\" and defaults to \"read\".\n" - "\n" - "Valid sources:") -DECLARE_MESSAGE( - HelpAssetCachingAzUrl, - (), - "This is printed as the 'definition' in a table for 'x-azurl,[,[,]]', so , , and " - "should not be localized.", - "Adds an Azure Blob Storage source, optionally using Shared Access Signature validation. URL should include " - "the container path and be terminated with a trailing \"/\". , if defined, should be prefixed with a " - "\"?\". " - "Non-Azure servers will also work if they respond to GET and PUT requests of the form: " - "\"\".") + (msg::package_name), + "'header' refers to C/C++ .h files", + "{package_name} is header-only and can be used from CMake via:") +DECLARE_MESSAGE( + HelpAssetCaching, + (), + "The '' part references code in the following table and should not be localized. The matching values " + "\"read\" \"write\" and \"readwrite\" are also fixed. After this block a table with each possible asset " + "caching source is printed.", + "**Experimental feature: this may change or be removed at any time**\n" + "\n" + "vcpkg can use mirrors to cache downloaded assets, ensuring continued operation even if the " + "original source changes or disappears.\n" + "\n" + "Asset caching can be configured either by setting the environment variable X_VCPKG_ASSET_SOURCES " + "to a semicolon-delimited list of sources or by passing a sequence of " + "--x-asset-sources= command line options. Command line sources are interpreted after " + "environment sources. Commas, semicolons, and backticks can be escaped using backtick (`).\n" + "\n" + "The optional parameter for certain strings controls how they will be accessed. It can be specified as " + "\"read\", \"write\", or \"readwrite\" and defaults to \"read\".\n" + "\n" + "Valid sources:") +DECLARE_MESSAGE( + HelpAssetCachingAzUrl, + (), + "This is printed as the 'definition' in a table for 'x-azurl,[,[,]]', so , , and " + "should not be localized.", + "Adds an Azure Blob Storage source, optionally using Shared Access Signature validation. URL should include " + "the container path and be terminated with a trailing \"/\". , if defined, should be prefixed with a " + "\"?\". " + "Non-Azure servers will also work if they respond to GET and PUT requests of the form: " + "\"\".") DECLARE_MESSAGE(HelpAssetCachingBlockOrigin, - (), - "This is printed as the 'definition' in a table for 'x-block-origin'", - "Disables fallback to the original URLs in case the mirror does not have the file available.") -DECLARE_MESSAGE( - HelpAssetCachingScript, - (), - "This is printed as the 'definition' in a table for 'x-script,