diff --git a/.gitignore b/.gitignore index 65b0ddb81b..bd67c20615 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ toolsrc/out* toolsrc/CMakeSettings.json +# fuzzing +sync_dir* # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs @@ -331,4 +333,4 @@ __pycache__/ ############################################################ archives .DS_Store -prefab/ \ No newline at end of file +prefab/ diff --git a/docs/about/privacy.md b/docs/about/privacy.md index 76661a2c82..15ef69d763 100644 --- a/docs/about/privacy.md +++ b/docs/about/privacy.md @@ -41,7 +41,8 @@ We collect various telemetry events such as the command line used, the time of i You can see the telemetry events any command by appending `--printmetrics` after the vcpkg command line. -In the source code (included in `toolsrc\`), you can search for calls to the functions `track_property()` and `track_metric()` to see every specific data point we collect. +In the source code (included in `toolsrc\`), you can search for calls to the functions `track_property()`, `track_feature()`, `track_metric()`, and `track_buildtime()` +to see every specific data point we collect. ## Avoid inadvertent disclosure information diff --git a/docs/specifications/manifests.md b/docs/specifications/manifests.md index 4691261587..350cfd0c7d 100644 --- a/docs/specifications/manifests.md +++ b/docs/specifications/manifests.md @@ -34,12 +34,6 @@ rather than JSON5 or JSON with comments because JSON is the everywhere-supported standard. That is not necessarily true of JSON with comments. Additionally, if one needs to write a comment, they can do so via `"$reason"` or `"$comment"` fields. -### Why are ``s so verbose? - -In the initial implementation, we didn't want to do more parsing than is strictly necessary, -especially parsing languages which aren't defined anywhere. We may add a shorter way of -defining platform specifications in the future (more similar to those in control files). - ## Specification A manifest file shall have the name `vcpkg.json`, and shall be in the root directory of a package. @@ -54,26 +48,28 @@ to specify the shape of a value. Note that any object may contain any directives a field key that starts with a `$`; these directive shall be ignored by `vcpkg`. Common directives may include `"$schema"`, `"$comment"`, `"$reason"`. -A manifest must be a top-level object, and must have at least the following properties: +A manifest must be a top-level object, and must have at least: * `"name"`: a `` -* `"version"`: A `string`. This will be defined further later. - * [Semver](https://semver.org) is recommended but not required. +* One (and only one) of the following version fields: + * `"version-string"`: A `string`. Has no semantic meaning. + Equivalent to `CONTROL`'s `Version:` field. + * Other version fields will be defined by the Versions RFC The simplest vcpkg.json looks like this: ```json { "name": "mypackage", - "version": "0.1.0-dev" + "version-string": "0.1.0-dev" } ``` Additionally, it may contain the following properties: * `"port-version"`: A non-negative integer. If this field doesn't exist, it's assumed to be `0`. * Note that this is a change from existing CONTROL files, where versions were a part of the version string -* `"authors"`: An array of `string`s which contain the authors of a package - * `"authors": [ "Nicole Mazzuca ", "שלום עליכם " ]` +* `"maintainers"`: An array of `string`s which contain the authors of a package + * `"maintainers": [ "Nicole Mazzuca ", "שלום עליכם " ]` * `"description"`: A string or array of strings containing the description of a package * `"description": "mypackage is a package of mine"` * `"homepage"`: A url which points to the homepage of a package @@ -86,8 +82,8 @@ Additionally, it may contain the following properties: * `"dev-dependencies"`: An array of ``s which are required only for developers (testing and the like) * `"features"`: An array of ``s that the package supports * `"default-features"`: An array of ``s that correspond to features, which will be used by default. -* `"supports"`: A `` - * `"supports": { "and": [ "win", { "not": "arm" } ] }` +* `"supports"`: A `` + * `"supports": "windows & !arm"` Any properties which are not listed, and which do not start with a `$`, will be warned against and are reserved for future use. @@ -105,7 +101,7 @@ Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!(win ```json { "name": "pango", - "version": "1.40.11", + "version-string": "1.40.11", "port-version": 6, "homepage": "https://ftp.gnome.org/pub/GNOME/sources/pango/", "description": "Text and font handling library.", @@ -118,22 +114,15 @@ Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!(win { "name": "harfbuzz", "features": [ "glib" ], - "platform": { - "and": [ - { "not": { "and": [ "windows", "static" ] } }, - { "not": "osx" } - ] - } + "platform": "!(windows & static) & !osx" } ] } ``` -You may notice that the platform specification is fairly wordy. See [reasoning](#why-are-platform-specifications-so-verbose) for why. - ## Behavior of the Tool -There will be two "modes" for vcpkg from this point forward: "classic", and "modern". +There will be two "modes" for vcpkg from this point forward: "classic", and "manifest". The former will act exactly like the existing vcpkg workflow, so as to avoid breaking anyone. The latter will be the mode only when the user either: @@ -146,11 +135,10 @@ anyone. The latter will be the mode only when the user either: * The environment variable `VCPKG_FEATURE_FLAGS` * The option `--feature-flags` * (e.g., `--feature-flags=binarycaching,manifests`) + * If someone wants to use classic mode and silence the warning, they can add the + `-manifests` feature flag to disable the mode. -Additionally, we'll add the `--x-classic-mode` flag to allow someone to force classic -mode. - -When in "modern" mode, the `installed` directory will be changed to +When in "manifest" mode, the `installed` directory will be changed to `/vcpkg_installed` (name up for bikeshedding). The following commands will change behavior: @@ -158,49 +146,38 @@ The following commands will change behavior: the manifest file, and will remove any dependencies which are no longer in the dependency tree implied by the manifest file. * `vcpkg install` with port arguments will give an error. -* `vcpkg x-clean` will be added, and will delete your `vcpkg_installed` directory. -The following commands will not work in modern mode, at least initially: +The following commands will not work in manifest mode, at least initially: * `vcpkg x-set-installed`: `vcpkg install` serves the same function * `vcpkg remove` * `vcpkg export` -* `vcpkg import` -* `vcpkg create` -We may add these features back for modern mode once we understand how best to +We may add these features back for manifest mode once we understand how best to implement them. ### Behavior of the Toolchain -Mostly, the toolchain file stays the same; however, we shall add one public cache variable: +Mostly, the toolchain file stays the same; however, we shall add +two public options: ```cmake -VCPKG_MANIFEST_ROOT:PATH= +VCPKG_MANIFEST_MODE:BOOL= +VCPKG_MANIFEST_INSTALL:BOOL=ON ``` -and one function: +The first option either explicitly turns on, or off, manifest mode; +otherwise, we default to looking for a manifest file in the directory +tree upwards from the source directory. -```cmake -vcpkg_acquire_dependencies( - [TRIPLET ] - [MANIFEST ] - [INSTALL_DIRECTORY ]) -``` +The `VCPKG_MANIFEST_INSTALL` option tells the toolchain whether to +install the packages or not -- if you wish to install the manifest +dependencies manually, you can set this to off, and we also turn it +off for packages installed by vcpkg. -which installs the dependencies required by the manifest file. - -The default for `TRIPLET` is `VCPKG_TARGET_TRIPLET` -(which is the default triplet for the configured system). -For example, on x64 Windows, it defaults to `x64-windows`. - -The default for `INSTALL_DIRECTORY` is `${CMAKE_BINARY_DIR}/vcpkg_installed`. - -Additionally, in the course of implementation, we would like to -look at adding the following function, but may not be able to: - -It is almost certain that one should guard any use of this function -by `if(EXISTS CACHE{VCPKG_MANIFEST_FILE})`. +Additionally, if `-manifests` is set in the feature flags environment +variable, we turn off manifest mode in the toolchain, and we act like +the classic toolchain. ### Example - CMake Integration @@ -232,7 +209,7 @@ Therefore, in `vcpkg.json`, we'll need to depend on `fmt`: ```json { "name": "example", - "version": "0.0.1", + "version-string": "0.0.1", "dependencies": [ "fmt" ] @@ -246,11 +223,6 @@ cmake_minimum_required(VERSION 3.14) project(example CXX) -if(EXISTS CACHE{VCPKG_MANIFEST_FILE}) - vcpkg_acquire_dependencies() -endif() - - add_executable(example src/main.cxx) find_package(fmt REQUIRED) @@ -285,7 +257,9 @@ Hello, world! * Does not have multiple consecutive hyphens * Does not begin nor end with a hyphen * Is not a Windows filesystem reserved name - * Is not a vcpkg reserved name: "default". + * Is not a vcpkg reserved name: "default" or "core". + * In other words, it must follow the regex `[a-z0-9]+(-[a-z0-9]+)*`, and must not be any of: + * `{ prn, aux, nul, con, lpt[1-9], com[1-9], core, default }` * ``: A `string` consisting of a non-zero number of ``s, separated by `.`. * `a.b.c` is valid * `a` is valid @@ -296,15 +270,29 @@ Hello, world! * `"name"`: A `` * Optionally, `"features"`: an array of ``s corresponding to features in the package. * Optionally, `"default-features"`: a `boolean`. If this is false, then don't use the default features of the package; equivalent to core in existing CONTROL files. If this is true, do the default thing of including the default features. - * Optionally, `"platform"`: a `` + * Optionally, `"platform"`: a `` * ``: No extra fields are required. -* ``: An SPDX license expression at version 3.8. -* ``: A specification of a set of platforms; used in platform-specific dependencies and supports fields. One of: - * ``: A string denoting a triplet tag like “windows”, “osx”, etc. - * ``: An object containing a member with key "not" and value ``. - * ``: An object containing a member with key "and" and value array of ``s. - * ``: An object containing a member with key "or" and value array of ``s. +* ``: An SPDX license expression at version 3.9. +* ``: A specification of a set of platforms; used in platform-specific dependencies and supports fields. A string that is parsed as follows: + * ``: + * `` + * `` + * `` + * ``: + * `( )` + * `` + * ``: + * regex: `/^[a-z0-9]+$/` + * ``: + * `` + * `! ` + * `` + * `` + * ` & ` + * `` + * `` + * ` | ` * ``: An object containing the following: * `"name"`: An ``, the name of the feature - * `"description"`: A `string`, the description of the feature + * `"description"`: A `string` or array of `string`s, the description of the feature * Optionally, `"dependencies"`: An array of ``s, the dependencies used by this feature diff --git a/docs/users/config-environment.md b/docs/users/config-environment.md index bffa072780..ffa988cbc3 100644 --- a/docs/users/config-environment.md +++ b/docs/users/config-environment.md @@ -15,6 +15,7 @@ subject to change without notice and should be considered highly unstable. Non-exhaustive list of off-by-default features: - `binarycaching` +- `manifest` #### EDITOR diff --git a/ports/3fd/CONTROL b/ports/3fd/CONTROL deleted file mode 100644 index 75eecaa31f..0000000000 --- a/ports/3fd/CONTROL +++ /dev/null @@ -1,4 +0,0 @@ -Source: 3fd -Version: 2.6.2-3 -Description: C++ Framework For Fast Development -Build-Depends: boost-lockfree (windows), boost-regex (windows), poco (windows), sqlite3, rapidxml diff --git a/ports/3fd/vcpkg.json b/ports/3fd/vcpkg.json new file mode 100644 index 0000000000..f183916e66 --- /dev/null +++ b/ports/3fd/vcpkg.json @@ -0,0 +1,22 @@ +{ + "name": "3fd", + "version-string": "2.6.2", + "port-version": 3, + "description": "C++ Framework For Fast Development", + "dependencies": [ + { + "name": "boost-lockfree", + "platform": "windows" + }, + { + "name": "boost-regex", + "platform": "windows" + }, + { + "name": "poco", + "platform": "windows" + }, + "sqlite3", + "rapidxml" + ] +} diff --git a/ports/abseil/CONTROL b/ports/abseil/CONTROL deleted file mode 100644 index e0ea57d1cc..0000000000 --- a/ports/abseil/CONTROL +++ /dev/null @@ -1,10 +0,0 @@ -Source: abseil -Version: 2020-03-03-7 -Homepage: https://github.com/abseil/abseil-cpp -Description: an open-source collection designed to augment the C++ standard library. - Abseil is an open-source collection of C++ library code designed to augment the C++ standard library. The Abseil library code is collected from Google's own C++ code base, has been extensively tested and used in production, and is the same code we depend on in our daily coding lives. - In some cases, Abseil provides pieces missing from the C++ standard; in others, Abseil provides alternatives to the standard for special needs we've found through usage in the Google code base. We denote those cases clearly within the library code we provide you. - Abseil is not meant to be a competitor to the standard library; we've just found that many of these utilities serve a purpose within our code base, and we now want to provide those resources to the C++ community as a whole. - -Feature: cxx17 -Description: Enable compiler C++17. diff --git a/ports/abseil/vcpkg.json b/ports/abseil/vcpkg.json new file mode 100644 index 0000000000..cfc1022ea4 --- /dev/null +++ b/ports/abseil/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "abseil", + "version-string": "2020-03-03", + "port-version": 7, + "homepage": "https://github.com/abseil/abseil-cpp", + "description": [ + "an open-source collection designed to augment the C++ standard library.", + "Abseil is an open-source collection of C++ library code designed to augment the C++ standard library. The Abseil library code is collected from Google's own C++ code base, has been extensively tested and used in production, and is the same code we depend on in our daily coding lives.", + "In some cases, Abseil provides pieces missing from the C++ standard; in others, Abseil provides alternatives to the standard for special needs we've found through usage in the Google code base. We denote those cases clearly within the library code we provide you.", + "Abseil is not meant to be a competitor to the standard library; we've just found that many of these utilities serve a purpose within our code base, and we now want to provide those resources to the C++ community as a whole." + ], + "features": [ + { + "name": "cxx17", + "description": "Enable compiler C++17." + } + ] +} diff --git a/ports/argparse/CONTROL b/ports/argparse/CONTROL deleted file mode 100644 index cfb3e8eedb..0000000000 --- a/ports/argparse/CONTROL +++ /dev/null @@ -1,4 +0,0 @@ -Source: argparse -Version: 2.1 -Description: Argument parser for modern C++ -Homepage: https://github.com/p-ranav/argparse diff --git a/ports/argparse/vcpkg.json b/ports/argparse/vcpkg.json new file mode 100644 index 0000000000..9137c655f6 --- /dev/null +++ b/ports/argparse/vcpkg.json @@ -0,0 +1,7 @@ +{ + "name": "argparse", + "version-string": "2.1", + "description": "Argument parser for modern C++", + "license": "MIT", + "homepage": "https://github.com/p-ranav/argparse" +} diff --git a/ports/avisynthplus/CONTROL b/ports/avisynthplus/CONTROL deleted file mode 100644 index 362eaaed95..0000000000 --- a/ports/avisynthplus/CONTROL +++ /dev/null @@ -1,5 +0,0 @@ -Source: avisynthplus -Version: 3.6.0 -Homepage: http://avs-plus.net/ -Description: An improved version of the AviSynth frameserver, with improved features and developer friendliness -Supports: !(uwp|arm|static) diff --git a/ports/avisynthplus/vcpkg.json b/ports/avisynthplus/vcpkg.json new file mode 100644 index 0000000000..1af0142ea4 --- /dev/null +++ b/ports/avisynthplus/vcpkg.json @@ -0,0 +1,7 @@ +{ + "name": "avisynthplus", + "version-string": "3.6.0", + "homepage": "http://avs-plus.net/", + "description": "An improved version of the AviSynth frameserver, with improved features and developer friendliness", + "supports": "!(uwp | arm | static)" +} diff --git a/ports/cmocka/CONTROL b/ports/cmocka/CONTROL index 042cf23a7e..d04945aa5a 100644 --- a/ports/cmocka/CONTROL +++ b/ports/cmocka/CONTROL @@ -1,3 +1,4 @@ Source: cmocka -Version: 1.1.5-1 +Version: 1.1.5 +Port-Version: 2 Description: An elegant unit testing framework for C with support for mock objects diff --git a/ports/cmocka/vcpkg-cmake-wrapper.cmake b/ports/cmocka/vcpkg-cmake-wrapper.cmake index 49b486ff83..c5626845b4 100644 --- a/ports/cmocka/vcpkg-cmake-wrapper.cmake +++ b/ports/cmocka/vcpkg-cmake-wrapper.cmake @@ -3,8 +3,8 @@ _find_package(${ARGS}) get_filename_component(_cmocka_lib_name ${CMOCKA_LIBRARY} NAME) set(CMOCKA_LIBRARY - debug ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/lib/${_cmocka_lib_name} - optimized ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/${_cmocka_lib_name} + debug ${CURRENT_INSTALLED_DIR}/debug/lib/${_cmocka_lib_name} + optimized ${CURRENT_INSTALLED_DIR}/lib/${_cmocka_lib_name} ) set(CMOCKA_LIBRARIES ${CMOCKA_LIBRARY}) diff --git a/ports/libarchive/CONTROL b/ports/libarchive/CONTROL index e3e8211917..7bccf0f453 100644 --- a/ports/libarchive/CONTROL +++ b/ports/libarchive/CONTROL @@ -1,5 +1,6 @@ Source: libarchive -Version: 3.4.1-3 +Version: 3.4.1 +Port-Version: 4 Homepage: https://github.com/libarchive/libarchive Description: Library for reading and writing streaming archives Build-Depends: zlib diff --git a/ports/libarchive/vcpkg-cmake-wrapper.cmake b/ports/libarchive/vcpkg-cmake-wrapper.cmake index c7b951a391..7893a23a44 100644 --- a/ports/libarchive/vcpkg-cmake-wrapper.cmake +++ b/ports/libarchive/vcpkg-cmake-wrapper.cmake @@ -22,8 +22,8 @@ if("@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static") list(APPEND LibArchive_LIBRARIES LibLZMA::LibLZMA) endif() if(@ENABLE_LZO@) - find_library(LZO_LIBRARY_DEBUG NAMES lzo2d lzo2 NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug" NO_DEFAULT_PATH) - find_library(LZO_LIBRARY_RELEASE NAMES lzo2 NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" NO_DEFAULT_PATH) + find_library(LZO_LIBRARY_DEBUG NAMES lzo2d lzo2 NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}/debug" NO_DEFAULT_PATH) + find_library(LZO_LIBRARY_RELEASE NAMES lzo2 NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}" NO_DEFAULT_PATH) if(LZO_LIBRARY_RELEASE) list(APPEND LibArchive_LIBRARIES optimized ${LZO_LIBRARY_RELEASE}) endif() @@ -32,8 +32,8 @@ if("@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static") endif() endif() if(@ENABLE_ZSTD@) - find_library(ZSTD_LIBRARY_DEBUG NAMES zstdd zstd NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug" NO_DEFAULT_PATH) - find_library(ZSTD_LIBRARY_RELEASE NAMES zstd NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" NO_DEFAULT_PATH) + find_library(ZSTD_LIBRARY_DEBUG NAMES zstdd zstd NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}/debug" NO_DEFAULT_PATH) + find_library(ZSTD_LIBRARY_RELEASE NAMES zstd NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}" NO_DEFAULT_PATH) if(ZSTD_LIBRARY_RELEASE) list(APPEND LibArchive_LIBRARIES optimized ${ZSTD_LIBRARY_RELEASE}) endif() diff --git a/ports/libiconv/CONTROL b/ports/libiconv/CONTROL index acff1a8938..4a5599053b 100644 --- a/ports/libiconv/CONTROL +++ b/ports/libiconv/CONTROL @@ -1,4 +1,5 @@ Source: libiconv -Version: 1.16-3 +Version: 1.16 +Port-Version: 4 Homepage: https://www.gnu.org/software/libiconv/ Description: GNU Unicode text conversion diff --git a/ports/libiconv/vcpkg-cmake-wrapper.cmake b/ports/libiconv/vcpkg-cmake-wrapper.cmake index 472dd8082d..503cc57e21 100644 --- a/ports/libiconv/vcpkg-cmake-wrapper.cmake +++ b/ports/libiconv/vcpkg-cmake-wrapper.cmake @@ -2,8 +2,8 @@ include(SelectLibraryConfigurations) _find_package(${ARGS}) if(Iconv_FOUND) - find_library(CHARSET_LIBRARY_DEBUG NAMES charsetd libcharsetd charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug" NO_DEFAULT_PATH) - find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" NO_DEFAULT_PATH) + find_library(CHARSET_LIBRARY_DEBUG NAMES charsetd libcharsetd charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}/debug" NO_DEFAULT_PATH) + find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}" NO_DEFAULT_PATH) find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib) select_library_configurations(CHARSET) list(APPEND Iconv_LIBRARIES ${CHARSET_LIBRARIES}) diff --git a/ports/libpq/vcpkg-cmake-wrapper.cmake b/ports/libpq/vcpkg-cmake-wrapper.cmake index 5fd40d26ca..b95afddc11 100644 --- a/ports/libpq/vcpkg-cmake-wrapper.cmake +++ b/ports/libpq/vcpkg-cmake-wrapper.cmake @@ -2,7 +2,7 @@ find_library(PostgreSQL_LIBRARY_DEBUG NAMES pq PATHS - "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/lib" + "${CURRENT_INSTALLED_DIR}/debug/lib" NO_DEFAULT_PATH ) _find_package(${ARGS}) diff --git a/ports/libxml2/CONTROL b/ports/libxml2/CONTROL index 80a0bc7e04..6c8d5c1bf3 100644 --- a/ports/libxml2/CONTROL +++ b/ports/libxml2/CONTROL @@ -1,5 +1,6 @@ Source: libxml2 -Version: 2.9.9-6 +Version: 2.9.9 +Port-Version: 7 Homepage: https://xmlsoft.org/ Description: Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform) Build-Depends: zlib, libiconv, liblzma diff --git a/ports/libxml2/vcpkg-cmake-wrapper.cmake b/ports/libxml2/vcpkg-cmake-wrapper.cmake index 8c81e2267f..47a3f4f1c3 100644 --- a/ports/libxml2/vcpkg-cmake-wrapper.cmake +++ b/ports/libxml2/vcpkg-cmake-wrapper.cmake @@ -3,11 +3,11 @@ if(LibXml2_FOUND) find_package(LibLZMA) find_package(ZLIB) include(SelectLibraryConfigurations) - find_library(ICONV_LIBRARY_DEBUG NAMES iconvd libiconvd iconv libiconv NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug" NO_DEFAULT_PATH) - find_library(ICONV_LIBRARY_RELEASE NAMES iconv libiconv NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" NO_DEFAULT_PATH) + find_library(ICONV_LIBRARY_DEBUG NAMES iconvd libiconvd iconv libiconv NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}/debug" NO_DEFAULT_PATH) + find_library(ICONV_LIBRARY_RELEASE NAMES iconv libiconv NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}" NO_DEFAULT_PATH) find_library(ICONV_LIBRARY_RELEASE NAMES iconv libiconv NAMES_PER_DIR PATH_SUFFIXES lib) - find_library(CHARSET_LIBRARY_DEBUG NAMES charsetd libcharsetd charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug" NO_DEFAULT_PATH) - find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" NO_DEFAULT_PATH) + find_library(CHARSET_LIBRARY_DEBUG NAMES charsetd libcharsetd charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}/debug" NO_DEFAULT_PATH) + find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib PATHS "${CURRENT_INSTALLED_DIR}" NO_DEFAULT_PATH) find_library(CHARSET_LIBRARY_RELEASE NAMES charset libcharset NAMES_PER_DIR PATH_SUFFIXES lib) select_library_configurations(ICONV) select_library_configurations(CHARSET) diff --git a/ports/qt5-base/cmake/find_qt_mkspec.cmake b/ports/qt5-base/cmake/find_qt_mkspec.cmake index 08fae07cfb..c9c06c8bd9 100644 --- a/ports/qt5-base/cmake/find_qt_mkspec.cmake +++ b/ports/qt5-base/cmake/find_qt_mkspec.cmake @@ -77,10 +77,10 @@ function(find_qt_mkspec TARGET_PLATFORM_MKSPEC_OUT HOST_PLATFORM_MKSPEC_OUT EXT_ else() endif() foreach(_triplet ${_test_triplets}) - find_program(QMAKE_PATH qmake PATHS ${_VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5/bin NO_DEFAULT_PATHS) - message(STATUS "Checking: ${_VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5/bin. ${QMAKE_PATH}") + find_program(QMAKE_PATH qmake PATHS ${VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5/bin NO_DEFAULT_PATHS) + message(STATUS "Checking: ${VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5/bin. ${QMAKE_PATH}") if(QMAKE_PATH) - set(_tmp_host_root "${_VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5") + set(_tmp_host_root "${VCPKG_INSTALLED_DIR}/${_triplet}/tools/qt5") set(_tmp_host_qmake ${QMAKE_PATH} PARENT_SCOPE) message(STATUS "Qt host tools root dir within vcpkg: ${_tmp_host_root}") break() @@ -98,4 +98,4 @@ function(find_qt_mkspec TARGET_PLATFORM_MKSPEC_OUT HOST_PLATFORM_MKSPEC_OUT EXT_ set(${EXT_HOST_TOOLS_OUT} ${_tmp_host_root} PARENT_SCOPE) endif() -endfunction() \ No newline at end of file +endfunction() diff --git a/ports/raylib/CONTROL b/ports/raylib/CONTROL index 27176d24ed..382de52f3f 100644 --- a/ports/raylib/CONTROL +++ b/ports/raylib/CONTROL @@ -1,5 +1,6 @@ Source: raylib Version: 3.0.0 +Port-Version: 1 Description: A simple and easy-to-use library to enjoy videogames programming Homepage: https://github.com/raysan5/raylib Supports: !(arm|uwp) diff --git a/ports/raylib/vcpkg-cmake-wrapper.cmake b/ports/raylib/vcpkg-cmake-wrapper.cmake index 1efda7c9e5..81e9989ec0 100644 --- a/ports/raylib/vcpkg-cmake-wrapper.cmake +++ b/ports/raylib/vcpkg-cmake-wrapper.cmake @@ -6,8 +6,8 @@ if(raylib_FOUND) get_filename_component(_raylib_lib_name ${raylib_LIBRARY} NAME) set(raylib_LIBRARY - debug ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/lib/${_raylib_lib_name} - optimized ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/${_raylib_lib_name} + debug ${CURRENT_INSTALLED_DIR}/debug/lib/${_raylib_lib_name} + optimized ${CURRENT_INSTALLED_DIR}/lib/${_raylib_lib_name} ) set(raylib_LIBRARIES ${raylib_LIBRARY}) diff --git a/ports/spdk/CONTROL b/ports/spdk/CONTROL index 0233395c11..a127290336 100644 --- a/ports/spdk/CONTROL +++ b/ports/spdk/CONTROL @@ -1,5 +1,6 @@ Source: spdk Version: 19.01.1 +Port-Version: 1 Description: Storage Performance Development Kit Build-Depends: spdk-dpdk, spdk-ipsec, spdk-isal -Supports: linux \ No newline at end of file +Supports: linux diff --git a/ports/spdk/usage b/ports/spdk/usage index 6e791c3fe8..f26b41649c 100644 --- a/ports/spdk/usage +++ b/ports/spdk/usage @@ -7,7 +7,7 @@ Add following to build examples/nvme/perf/perf.c ADD_EXECUTABLE(SPDKTest perf.c) - TARGET_LINK_DIRECTORIES(SPDKTest PRIVATE ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/spdk) + TARGET_LINK_DIRECTORIES(SPDKTest PRIVATE ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/spdk) TARGET_LINK_LIBRARIES(SPDKTest PRIVATE SPDK::spdk_app_rpc SPDK::spdk_bdev diff --git a/scripts/Generate-SpdxLicenseList.ps1 b/scripts/Generate-SpdxLicenseList.ps1 new file mode 100644 index 0000000000..4710747eb7 --- /dev/null +++ b/scripts/Generate-SpdxLicenseList.ps1 @@ -0,0 +1,63 @@ +<# +#> +[CmdletBinding(PositionalBinding=$False)] +Param( + [Parameter(Mandatory=$True)] + [string]$Commit, + + [Parameter()] + [string]$GithubRepository = "spdx/license-list-data", + + [Parameter()] + [string]$LicensesOutFile = "$PSScriptRoot/../toolsrc/src/vcpkg/spdx-licenses.inc", + + [Parameter()] + [string]$ExceptionsOutFile = "$PSScriptRoot/../toolsrc/src/vcpkg/spdx-exceptions.inc" +) + +function Transform-JsonFile { + [CmdletBinding()] + Param( + [string]$Uri, + [string]$OutFile, + [string]$OuterName, + [string]$Id + ) + + $req = Invoke-WebRequest -Uri $Uri + + if ($req.StatusCode -ne 200) + { + Write-Error "Failed to GET $Uri" + return + } + + $json = $req.Content | ConvertFrom-Json -Depth 10 + Write-Verbose "Writing output to $OutFile" + + $fileContent = @( + "// Data downloaded from $Uri", + "// Generated by scripts/Generate-SpdxLicenseList.ps1", + "{") + $json.$OuterName | ForEach-Object { + $fileContent += " `"$($_.$Id)`"," + } + $fileContent += "}" + + $fileContent -join "`n" | Out-File -FilePath $OutFile -Encoding 'utf8' +} + +$baseUrl = "https://raw.githubusercontent.com/$GithubRepository/$Commit/json" +Write-Verbose "Getting json files from $baseUrl" + +Transform-JsonFile ` + -Uri "$baseUrl/licenses.json" ` + -OutFile $LicensesOutFile ` + -OuterName 'licenses' ` + -Id 'licenseId' + +Transform-JsonFile ` + -Uri "$baseUrl/exceptions.json" ` + -OutFile $ExceptionsOutFile ` + -OuterName 'exceptions' ` + -Id 'licenseExceptionId' diff --git a/scripts/buildsystems/msbuild/vcpkg-general.xml b/scripts/buildsystems/msbuild/vcpkg-general.xml index 2ee5599bea..55d5a736bd 100644 --- a/scripts/buildsystems/msbuild/vcpkg-general.xml +++ b/scripts/buildsystems/msbuild/vcpkg-general.xml @@ -1,6 +1,6 @@  - - + + + + + + + Subtype="folder" + Visible="false"> @@ -54,4 +74,4 @@ - \ No newline at end of file + diff --git a/scripts/buildsystems/msbuild/vcpkg.props b/scripts/buildsystems/msbuild/vcpkg.props index a9b97348f3..f9db4fc58a 100644 --- a/scripts/buildsystems/msbuild/vcpkg.props +++ b/scripts/buildsystems/msbuild/vcpkg.props @@ -25,11 +25,17 @@ $(Platform) + + + false + true + $([MSbuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), vcpkg.json)) + + $(VcpkgPlatformTarget)-$(VcpkgOSTarget) $(VcpkgUserTriplet) - $(VcpkgRoot)\installed\$(VcpkgTriplet)\ $(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg-general.xml - + diff --git a/scripts/buildsystems/msbuild/vcpkg.targets b/scripts/buildsystems/msbuild/vcpkg.targets index 626e72228f..0f562a876c 100644 --- a/scripts/buildsystems/msbuild/vcpkg.targets +++ b/scripts/buildsystems/msbuild/vcpkg.targets @@ -7,6 +7,9 @@ $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), .vcpkg-root)) $(Configuration) $(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg-general.xml + false + true + $([MSbuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), vcpkg.json)) @@ -22,7 +25,7 @@ $(PlatformTarget)-$(VcpkgOSTarget) $(VcpkgUserTriplet) $(VcpkgRoot)\installed\$(VcpkgTriplet)\ - + @@ -31,19 +34,24 @@ - - - $(VcpkgUserTriplet) - $(VcpkgTripletTmp)-static - $(VcpkgRoot)\installed\$(VcpkgTriplet)\ - + + + $(VcpkgManifestRoot)\vcpkg_installed\ + + + $(VcpkgRoot)\installed\ + + + $(VcpkgUserTriplet)-static + - $(VcpkgTriplet) - $(VcpkgUserTriplet) - $(VcpkgRoot)\installed\$(VcpkgUserTriplet)\ - + $(VcpkgUserTriplet) + + + + $(VcpkgInstalledDir)$(VcpkgTriplet) @@ -51,8 +59,9 @@ Release $(VcpkgRoot)\ $(VcpkgCurrentInstalledDir)\ + $(VcpkgManifestRoot)\ true - false @@ -72,12 +81,22 @@ + + + + + + + + + + - \ No newline at end of file + diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake index 03926336b2..10be7a4235 100644 --- a/scripts/buildsystems/vcpkg.cmake +++ b/scripts/buildsystems/vcpkg.cmake @@ -5,6 +5,46 @@ mark_as_advanced(CMAKE_TOOLCHAIN_FILE) option(VCPKG_VERBOSE "Enables messages from the VCPKG toolchain for debugging purposes." OFF) mark_as_advanced(VCPKG_VERBOSE) +function(_vcpkg_get_directory_name_of_file_above OUT DIRECTORY FILENAME) + if(DEFINED ${OUT}) + return() + endif() + + set(_vcpkg_get_dir_candidate ${DIRECTORY}) + while(IS_DIRECTORY ${_vcpkg_get_dir_candidate} AND NOT DEFINED _vcpkg_get_dir_out) + if(EXISTS ${_vcpkg_get_dir_candidate}/${FILENAME}) + set(_vcpkg_get_dir_out ${_vcpkg_get_dir_candidate}) + else() + get_filename_component(_vcpkg_get_dir_candidate_tmp ${_vcpkg_get_dir_candidate} DIRECTORY) + if(_vcpkg_get_dir_candidate STREQUAL _vcpkg_get_dir_candidate_tmp) # we've reached the root + set(_vcpkg_get_dir_out "${OUT}-NOTFOUND") + else() + set(_vcpkg_get_dir_candidate ${_vcpkg_get_dir_candidate_tmp}) + endif() + endif() + endwhile() + + set(${OUT} ${_vcpkg_get_dir_out} CACHE INTERNAL "_vcpkg_get_directory_name_of_file_above: ${OUT}") +endfunction() + +_vcpkg_get_directory_name_of_file_above(_VCPKG_MANIFEST_DIR ${CMAKE_CURRENT_SOURCE_DIR} "vcpkg.json") +if(_VCPKG_MANIFEST_DIR) + set(_VCPKG_MANIFEST_MODE_DEFAULT ON) +else() + set(_VCPKG_MANIFEST_MODE_DEFAULT OFF) +endif() + +option(VCPKG_MANIFEST_MODE "Set vcpkg to manifest mode" ${_VCPKG_MANIFEST_MODE_DEFAULT}) + +if(NOT _VCPKG_MANIFEST_DIR AND VCPKG_MANIFEST_MODE) + message(FATAL_ERROR + "vcpkg manifest mode was enabled, but we couldn't find a manifest file (vcpkg.json) " + "in any directories above ${CMAKE_CURRENT_SOURCE_DIR}. Please add a manifest, or " + "disable manifests by turning off VCPKG_MANIFEST_MODE.") +endif() + +option(VCPKG_MANIFEST_INSTALL "Install packages from the manifest" ON) + # Determine whether the toolchain is loaded during a try-compile configuration get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) @@ -144,19 +184,28 @@ if(NOT DEFINED _VCPKG_ROOT_DIR) while(IS_DIRECTORY ${_VCPKG_ROOT_DIR_CANDIDATE} AND NOT EXISTS "${_VCPKG_ROOT_DIR_CANDIDATE}/.vcpkg-root") get_filename_component(_VCPKG_ROOT_DIR_TEMP ${_VCPKG_ROOT_DIR_CANDIDATE} DIRECTORY) if (_VCPKG_ROOT_DIR_TEMP STREQUAL _VCPKG_ROOT_DIR_CANDIDATE) # If unchanged, we have reached the root of the drive - message(FATAL_ERROR "Could not find .vcpkg-root") else() SET(_VCPKG_ROOT_DIR_CANDIDATE ${_VCPKG_ROOT_DIR_TEMP}) endif() endwhile() set(_VCPKG_ROOT_DIR ${_VCPKG_ROOT_DIR_CANDIDATE} CACHE INTERNAL "Vcpkg root directory") endif() -if (NOT DEFINED _VCPKG_INSTALLED_DIR) - set(_VCPKG_INSTALLED_DIR ${_VCPKG_ROOT_DIR}/installed) + +_vcpkg_get_directory_name_of_file_above(_VCPKG_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR} ".vcpkg-root") +if(NOT _VCPKG_ROOT_DIR) + message(FATAL_ERROR "Could not find .vcpkg-root") endif() -if(NOT EXISTS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" AND NOT _CMAKE_IN_TRY_COMPILE AND NOT VCPKG_SUPPRESS_INSTALLED_LIBRARIES_WARNING) - message(WARNING "There are no libraries installed for the Vcpkg triplet ${VCPKG_TARGET_TRIPLET}.") +if (NOT DEFINED _VCPKG_INSTALLED_DIR) + if(_VCPKG_MANIFEST_DIR) + set(_VCPKG_INSTALLED_DIR ${_VCPKG_MANIFEST_DIR}/vcpkg_installed) + else() + set(_VCPKG_INSTALLED_DIR ${_VCPKG_ROOT_DIR}/installed) + endif() + + set(_VCPKG_INSTALLED_DIR ${_VCPKG_INSTALLED_DIR} + CACHE PATH + "The directory which contains the installed libraries for each triplet") endif() if(CMAKE_BUILD_TYPE MATCHES "^[Dd][Ee][Bb][Uu][Gg]$" OR NOT DEFINED CMAKE_BUILD_TYPE) #Debug build: Put Debug paths before Release paths. @@ -218,6 +267,31 @@ foreach(_VCPKG_TOOLS_DIR ${_VCPKG_TOOLS_DIRS}) endif() endforeach() + +# CMAKE_EXECUTABLE_SUFFIX is not yet defined +if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(_VCPKG_EXECUTABLE_SUFFIX ".exe") +else() + set(_VCPKG_EXECUTABLE_SUFFIX "") +endif() + +if(VCPKG_MANIFEST_MODE AND VCPKG_MANIFEST_INSTALL AND NOT _CMAKE_IN_TRY_COMPILE) + execute_process( + COMMAND "${_VCPKG_ROOT_DIR}/vcpkg${_VCPKG_EXECUTABLE_SUFFIX}" install + --triplet ${VCPKG_TARGET_TRIPLET} + --vcpkg-root ${_VCPKG_ROOT_DIR} + --x-manifest-root=${_VCPKG_MANIFEST_DIR} + --x-install-root=${_VCPKG_INSTALLED_DIR} + --binarycaching + RESULT_VARIABLE _VCPKG_INSTALL_RESULT) + if (NOT _VCPKG_INSTALL_RESULT EQUAL 0) + message(FATAL_ERROR "vcpkg install failed") + endif() + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${_VCPKG_MANIFEST_DIR}/vcpkg.json" + "${_VCPKG_INSTALLED_DIR}/vcpkg/status") +endif() + option(VCPKG_APPLOCAL_DEPS "Automatically copy dependencies into the output directory for executables." ON) function(add_executable name) _add_executable(${ARGV}) diff --git a/scripts/ci.baseline.txt b/scripts/ci.baseline.txt index e77a6c4cdf..ab8ea0e60b 100644 --- a/scripts/ci.baseline.txt +++ b/scripts/ci.baseline.txt @@ -1,2021 +1,2021 @@ -########################################################################### -## This file defines the current expected build state of ports in CI. -## -## States -## pass - (default) the port builds in the CI system. If a port is -## missing from this file then it is assumed to build. -## fail - the port does not build in the CI system. -## This is not necessarily the same as if a port is expected to build -## on a developers machine because it may fail due to the machine -## configuration. When set to fail the CI system will still attempt -## to build the port and will report a CI failure until this file is updated. -## skip - Do not build this port in the CI system. -## This is added to ports that may be flaky or conflict with other -## ports. Please comment for why a port is skipped so it can be -## removed when the issue is resolved. -## ignore - attempt to build the port, but do not fail the CI test if the -## port does not build. Any ignored build failures will be reported -## in the test summary. -## -## -## CI tested triplets: -## arm64-windows -## arm-uwp -## x64-linux -## x64-osx -## x64-uwp -## x64-windows -## x64-windows-static -## x86-windows -## - - -# Add new items alphabetically - -3fd:arm64-windows=fail -3fd:arm-uwp=fail -3fd:x64-linux=fail -3fd:x64-osx=fail -3fd:x64-windows=fail -3fd:x64-windows-static=fail -3fd:x86-windows=ignore -7zip:arm64-windows=fail -7zip:arm-uwp=fail -7zip:x64-linux=fail -7zip:x64-osx=fail -7zip:x64-uwp=fail -activemq-cpp:x64-linux=fail -activemq-cpp:x64-osx=fail -akali:x64-uwp=fail -akali:arm-uwp=fail -akali:arm64-windows=fail -alac:arm-uwp=fail -alac:x64-uwp=fail -alembic:x64-osx=fail -alembic:x64-windows-static=fail -aliyun-oss-c-sdk:x64-linux=fail -aliyun-oss-c-sdk:x64-osx=fail -ampl-mp:arm64-windows=fail -ampl-mp:arm-uwp=fail -ampl-mp:x64-uwp=fail -amqpcpp:arm-uwp=fail -amqpcpp:x64-uwp=fail -angelscript:arm64-windows=fail -angelscript:arm-uwp=fail -antlr4:arm-uwp=fail -antlr4:x64-uwp=fail -anyrpc:arm-uwp=ignore -anyrpc:x86-windows=ignore -anyrpc:x64-windows-static=ignore -apr:arm-uwp=fail -apr:x64-uwp=fail -# Cross compiling CI machine cannot run gen_test_char to generate apr_escape_test_char.h -apr:arm64-windows=fail -argtable2:arm-uwp=fail -argtable2:x64-uwp=fail -arrow:arm64-windows=fail -arrow:x86-windows=fail -asiosdk:x64-linux=fail -asiosdk:x64-osx=fail -asiosdk:x64-uwp=fail -asiosdk:arm64-windows=fail -asiosdk:arm-uwp=fail -asmjit:arm64-windows=fail -asmjit:arm-uwp=fail -asyncplusplus:arm-uwp=fail -asyncplusplus:x64-uwp=fail -atk:x64-osx=fail -atk:arm64-windows=fail -atkmm:x64-linux=fail -atlmfc:x64-linux=fail -atlmfc:x64-osx=fail -aubio:x64-linux=fail -aubio:x64-osx=fail -avisynthplus:x64-linux=fail -avisynthplus:x64-windows-static=fail -avro-c:arm-uwp=fail -avro-c:x64-osx=fail -avro-c:x64-uwp=fail -aws-c-common:arm64-windows=fail -aws-c-common:arm-uwp=fail -aws-c-common:x64-uwp=fail -aws-checksums:arm64-windows=fail -aws-lambda-cpp:arm64-windows=fail -aws-lambda-cpp:arm-uwp=fail -aws-lambda-cpp:x64-uwp=fail -aws-lambda-cpp:x64-windows=fail -aws-lambda-cpp:x64-windows-static=fail -aws-lambda-cpp:x86-windows=fail -aws-lambda-cpp:x64-osx=fail -aws-sdk-cpp:x64-linux=ignore -azure-c-shared-utility:arm-uwp=fail -azure-c-shared-utility:x64-uwp=fail -basisu:x64-linux=ignore -bde:arm64-windows=fail -bde:arm-uwp=fail -bde:x64-uwp=fail -bde:x64-windows=fail -bde:x64-windows-static=fail -bde:x86-windows=fail -benchmark:arm64-windows=fail -benchmark:arm-uwp=fail -benchmark:x64-uwp=fail -berkeleydb:arm-uwp=fail -berkeleydb:x64-linux=fail -berkeleydb:x64-osx=fail -berkeleydb:x64-uwp=fail -bitserializer-rapidyaml:arm-uwp=skip -bitserializer-rapidyaml:arm64-windows=skip -bitserializer-rapidyaml:x64-osx=skip -bitserializer:arm-uwp=skip -bitserializer:arm64-windows=skip -bitserializer:x64-osx=skip -blaze:x64-windows=fail -blaze:x64-windows-static=fail -blaze:x86-windows=fail -blend2d:arm64-windows=fail -blend2d:arm-uwp=fail -blend2d:x64-uwp=fail -blitz:x64-uwp=fail -blitz:arm64-windows=fail -blitz:arm-uwp=fail -blosc:arm64-windows=fail -blosc:arm-uwp=fail -blosc:x64-uwp=fail -bond:arm-uwp=fail -bond:x64-osx=fail -bond:x64-uwp=fail -boost-coroutine:arm-uwp=fail -boost-coroutine:arm64-windows=fail -boost-fiber:arm-uwp=fail -boost-fiber:arm64-windows=fail -boost-fiber:x64-osx=fail -boost-fiber:x64-uwp=fail -boost-fiber:x64-linux=ignore -boost-filesystem:arm-uwp=fail -boost-filesystem:x64-uwp=fail -boost-iostreams:arm-uwp=fail -boost-iostreams:x64-uwp=fail -boost-locale:arm-uwp=fail -boost-locale:x64-uwp=fail -boost-log:arm-uwp=fail -boost-log:x64-uwp=fail -boost-stacktrace:arm-uwp=fail -boost-stacktrace:x64-uwp=fail -boost-test:arm-uwp=fail -boost-test:x64-uwp=fail -boost-wave:arm-uwp=fail -boost-wave:x64-uwp=fail -botan:arm64-windows=fail -botan:arm-uwp=fail -botan:x64-uwp=fail -box2d:x64-uwp=fail -box2d:arm-uwp=fail -breakpad:arm64-windows=fail -bullet3:arm64-windows=fail -bullet3:arm-uwp=fail -bullet3:x64-uwp=fail -butteraugli:x64-linux=ignore -caf:arm-uwp=fail -caf:arm64-windows=fail -caf:x64-uwp=fail -caf:x64-linux=ignore -caffe2:x86-windows=fail -caffe2:arm64-windows=fail -cairomm:x64-linux=fail -capnproto:arm64-windows=fail -capnproto:arm-uwp=fail -capnproto:x64-uwp=fail -c-ares:arm-uwp=fail -c-ares:x64-uwp=fail -cartographer:x64-osx=fail -casclib:arm-uwp=fail -casclib:x64-uwp=fail -catch-classic:arm64-windows = skip -catch-classic:arm-uwp = skip -catch-classic:x64-linux = skip -catch-classic:x64-osx = skip -catch-classic:x64-uwp = skip -catch-classic:x64-windows = skip -catch-classic:x64-windows-static = skip -catch-classic:x86-windows = skip -ccd:arm-uwp=fail -ccd:x64-uwp=fail -cello:arm-uwp=fail -cello:x64-uwp=fail -cfitsio:arm-uwp=fail -cfitsio:x64-uwp=fail -cgicc:arm-uwp=fail -cgicc:x64-uwp=fail -chakracore:arm64-windows=fail -chakracore:arm-uwp=fail -chakracore:x64-linux=fail -chakracore:x64-osx=fail -chakracore:x64-uwp=fail -chakracore:x64-windows-static=fail -# DCMTK currently has a vendored copy of libcharls.a, which causes conflicts with charls (TODO: use charls' copy) -charls:arm64-windows=skip -charls:arm-uwp=skip -charls:x64-linux=skip -charls:x64-osx=skip -charls:x64-uwp=skip -charls:x64-windows=skip -charls:x64-windows-static=skip -charls:x86-windows=skip -chartdir:arm64-windows=fail -chartdir:arm-uwp=fail -chartdir:x64-uwp=fail -chartdir:x64-windows-static=fail -chipmunk:arm64-windows=fail -chipmunk:arm-uwp=fail -chipmunk:x64-linux=fail -chipmunk:x64-osx=fail -chipmunk:x64-uwp=fail -chmlib:arm-uwp=fail -chmlib:x64-uwp=fail -civetweb:arm64-windows = skip -civetweb:arm-uwp = skip -civetweb:x64-uwp = skip -clapack:x64-uwp=fail -clblas:arm64-windows=fail -clblast:x64-osx=ignore -clblast:x64-linux=fail -clblast:x64-windows-static=fail -clockutils:x64-linux=fail -clockutils:x64-osx=fail -cmark:x64-windows-static=fail -cmcstl2:arm64-windows = skip -cmcstl2:arm-uwp = skip -cmcstl2:x64-linux = skip -cmcstl2:x64-osx = skip -cmcstl2:x64-uwp = skip -cmcstl2:x64-windows = skip -cmcstl2:x64-windows-static = skip -cmcstl2:x86-windows = skip -coin:arm64-windows=fail -coin:arm-uwp=fail -coin:x64-uwp=fail -collada-dom:x64-windows-static=fail -coolprop:arm-uwp=fail -coolprop:x64-linux=fail -coolprop:x64-osx=fail -coolprop:x64-uwp=fail -coroutine:arm-uwp=fail -coroutine:x64-linux=fail -coroutine:x64-uwp=fail -corrade:arm-uwp=fail -corrade:x64-uwp=fail -cppcms:x64-linux=fail -cppcms:x64-osx=fail -cppcms:x64-windows-static=fail -cppfs:arm-uwp=fail -cppfs:x64-uwp=fail -cppgraphqlgen:arm-uwp=ignore -cppgraphqlgen:x64-uwp=ignore -cppkafka:x64-linux=ignore -cppmicroservices:arm64-windows=fail -cppmicroservices:arm-uwp=fail -cppmicroservices:x64-uwp=fail -cpp-netlib:arm-uwp=fail -cpp-netlib:x64-uwp=fail -cpp-netlib:x64-linux=ignore -cpp-taskflow:x64-osx=fail -cppcoro:x64-linux=fail -cppcoro:arm-uwp=fail -cppcoro:x64-uwp=fail -cppunit:arm64-windows=fail -cppunit:arm-uwp=fail -cppunit:x64-linux=fail -cppunit:x64-osx=fail -cppunit:x64-uwp=fail -cpr:x64-linux=ignore -cpuinfo:arm64-windows=ignore -crashpad:arm64-windows=fail -crashpad:arm-uwp=fail -crashpad:x64-linux=fail -crashpad:x64-uwp=fail -crashpad:x86-windows=fail -crfsuite:arm-uwp=fail -crfsuite:x64-uwp=fail -crossguid:x64-osx=fail -cspice:arm-uwp=fail -cspice:x64-uwp=fail -ctemplate:arm64-windows=fail -ctemplate:arm-uwp=fail -ctemplate:x64-linux=fail -ctemplate:x64-osx=fail -cuda:x64-osx=fail -cudnn:arm64-windows=fail -cudnn:arm-uwp=fail -cudnn:x64-uwp=fail -cudnn:x64-windows-static=fail -cudnn:x86-windows=fail -dbow2:x64-osx=fail -dcmtk:arm-uwp=fail -dcmtk:arm64-windows=fail -dcmtk:x64-uwp=fail -detours:x64-linux=fail -detours:x64-osx=fail -devicenameresolver:arm-uwp=fail -devicenameresolver:x64-linux=fail -devicenameresolver:x64-osx=fail -devicenameresolver:x64-uwp=fail -devicenameresolver:x64-windows-static=fail -dimcli:arm-uwp=fail -dimcli:x64-osx=fail -dimcli:x64-uwp=fail -directxmesh:x64-linux=fail -directxmesh:x64-osx=fail -directxmesh:x64-windows-static=fail -directxtex:x64-linux=fail -directxtex:x64-osx=fail -directxtex:x64-windows-static=fail -directxtk:x64-linux=fail -directxtk:x64-osx=fail -directxtk:x64-windows-static=fail -directxtk12:x64-linux=fail -directxtk12:x64-osx=fail -directxtk12:x64-windows-static=fail -discord-game-sdk:x64-windows-static=fail -discord-rpc:arm-uwp=fail -discord-rpc:x64-uwp=fail -dlfcn-win32:arm-uwp=fail -dlfcn-win32:x64-linux=fail -dlfcn-win32:x64-osx=fail -dlfcn-win32:x64-uwp=fail -dmlc:arm-uwp=fail -dmlc:arm64-windows=ignore -dmlc:x64-uwp=fail -dmlc:x64-windows-static=ignore -dmlc:x86-windows=ignore -dpdk:arm-uwp=fail -dpdk:arm64-windows=fail -dpdk:x64-linux=fail -dpdk:x64-osx=fail -dpdk:x64-uwp=fail -dpdk:x64-windows-static=fail -dpdk:x64-windows=fail -dpdk:x86-windows=fail -duckx:arm64-windows = skip -duckx:arm-uwp = skip -duckx:x64-linux = skip -duckx:x64-osx = skip -duckx:x64-uwp = skip -duckx:x64-windows = skip -duckx:x64-windows-static = skip -duckx:x86-windows = skip -duilib:arm-uwp=fail -duilib:x64-linux=fail -duilib:x64-osx=fail -duilib:x64-uwp=fail - -# requires python@2 from brew, but that no longer exists -# python2 EOL yay! -duktape:x64-osx=skip - -dxut:arm64-windows=fail -dxut:arm-uwp=fail -dxut:x64-linux=fail -dxut:x64-osx=fail -dxut:x64-windows-static=fail -eastl:arm-uwp=fail -easyhook:arm64-windows=fail -easyhook:arm-uwp=fail -easyhook:x64-linux=fail -easyhook:x64-osx=fail -easyhook:x64-uwp=fail -easyhook:x64-windows-static=fail -easyloggingpp:arm-uwp=fail -easyloggingpp:x64-uwp=fail -eathread:arm64-windows=fail -eathread:arm-uwp=fail -eathread:x64-uwp=fail -eathread:x86-windows=fail -ebml:arm-uwp=fail -ebml:x64-uwp=fail -ecm:arm64-windows = skip -ecm:arm-uwp = skip -ecm:x64-linux = skip -ecm:x64-osx = skip -ecm:x64-uwp = skip -ecm:x64-windows = skip -ecm:x64-windows-static = skip -ecm:x86-windows = skip -ecsutil:arm64-windows=fail -ecsutil:arm-uwp=fail -ecsutil:x64-linux=fail -ecsutil:x64-osx=fail -ecsutil:x64-uwp=fail -embree2:x64-linux=fail -embree2:x64-osx=fail -embree2:x64-windows-static=fail -enet:arm-uwp=fail -enet:x64-uwp=fail -epsilon:x64-windows-static=fail -epsilon:arm-uwp=fail -epsilon:x64-linux=fail -epsilon:x64-osx=fail -epsilon:x64-uwp=fail -evpp:x64-osx=fail -expat:arm-uwp=fail -expat:x64-uwp=fail -faad2:x64-linux=fail -faad2:x64-osx=fail -fann:arm-uwp=fail -fann:x64-linux=fail -fann:x64-osx=fail -fann:x64-uwp=fail -fann:x64-windows-static=fail -farmhash:arm64-windows=fail -farmhash:arm-uwp=fail -farmhash:x64-uwp=fail -farmhash:x64-windows=fail -farmhash:x64-windows-static=fail -farmhash:x86-windows=fail -fastcdr:x64-linux=fail -fastrtps:arm-uwp=fail -fastrtps:x64-linux=fail -fastrtps:x64-osx=fail -fastrtps:x64-uwp=fail -fastrtps:x64-windows-static=fail -fdk-aac:arm64-windows=fail -fdk-aac:arm-uwp=fail -fdk-aac:x64-uwp=fail -fdlibm:arm-uwp=fail -fdlibm:x64-uwp=fail -fftw3:arm-uwp=fail -fftw3:x64-uwp=fail -flint:x64-linux=fail -flint:x64-osx=fail -fltk:arm-uwp=fail -fltk:x64-uwp=fail -fluidsynth:x64-linux=fail -fluidsynth:x64-osx=fail -fmem:arm-uwp=fail -fmem:x64-uwp=fail -fmi4cpp:arm-uwp=fail -fmi4cpp:x64-uwp=fail -fmilib:arm64-windows=fail -fmilib:arm-uwp=fail -fmilib:x64-linux=ignore -fmilib:x64-uwp=fail -fmilib:x64-windows=ignore -fmilib:x64-windows-static=ignore -fmilib:x86-windows=ignore -foonathan-memory:arm64-windows=fail -foonathan-memory:arm-uwp=fail -foonathan-memory:x64-uwp=fail -forge:x86-windows=fail -freeglut:arm64-windows=fail -freeglut:arm-uwp=fail -freeglut:x64-uwp=fail -freeglut:x64-osx=fail -freerdp:arm64-windows=fail -freerdp:arm-uwp=fail -freerdp:x64-osx=fail -freerdp:x64-uwp=fail -freetds:arm-uwp=fail -freetds:x64-linux=fail -freetds:x64-osx=fail -freetds:x64-uwp=fail -freetype-gl:x64-uwp=fail -freexl:arm-uwp=fail -freexl:arm64-windows=ignore -freexl:x64-uwp=fail -freexl:x86-windows=ignore -freexl:x64-windows=ignore -freexl:x64-windows-static=ignore -fribidi:arm64-windows=fail -fribidi:arm-uwp=fail -fribidi:x64-linux=fail -fribidi:x64-osx=fail -fribidi:x64-uwp=fail -ftgl:x64-uwp=fail -fuzzylite:arm-uwp=fail -fuzzylite:x64-linux=fail -fuzzylite:x64-osx=fail -fuzzylite:x64-uwp=fail -g3log:arm64-windows=fail -g3log:arm-uwp=fail -g3log:x64-uwp=fail -gainput:arm-uwp=fail -gainput:x64-linux=fail -gainput:x64-uwp=fail -gamma:x64-linux=fail -gamma:x64-osx=fail -gasol:arm64-windows=fail -gasol:arm-uwp=fail -gasol:x64-uwp=fail -gdcm:arm64-windows=fail -gdcm:x64-linux = skip -geographiclib:x64-linux=ignore -geos:arm-uwp=fail -geos:x64-uwp=fail -getopt:arm-uwp=fail -getopt:x64-uwp=fail -getopt-win32:arm64-windows=fail -getopt-win32:arm-uwp=fail -getopt-win32:x64-linux=fail -getopt-win32:x64-osx=fail -getopt-win32:x64-uwp=fail -getopt-win32:x64-windows-static=fail -gflags:arm-uwp=fail -gflags:x64-uwp=fail - -# Conflicts with libevent -gherkin-c:arm64-windows = skip -gherkin-c:arm-uwp = skip -gherkin-c:x64-linux=fail -gherkin-c:x64-osx=fail -gherkin-c:x64-uwp = skip -gherkin-c:x64-windows = skip -gherkin-c:x64-windows-static = skip -gherkin-c:x86-windows = skip -gl3w:arm64-windows=fail -gl3w:arm-uwp=fail -glew:arm64-windows=fail -glew:arm-uwp=fail -glfw3:arm-uwp=fail -glfw3:x64-uwp=fail -glib:x64-uwp=fail -glib:x64-windows-static=fail -glib:x64-osx=fail -globjects:x64-linux=ignore -gmmlib:arm64-windows=fail -gmmlib:arm-uwp=fail -gmmlib:x64-osx=fail -gmmlib:x64-uwp=fail -gmmlib:x64-windows=fail -gmmlib:x64-windows-static=fail -gmmlib:x86-windows=fail -google-cloud-cpp:arm64-windows=fail -google-cloud-cpp:arm-uwp=fail -google-cloud-cpp:x64-uwp=fail -gppanel:x64-osx=fail -gperf:x64-uwp=fail -gperf:arm-uwp=fail -gperftools:arm64-windows=fail -gperftools:x64-uwp=fail -gperftools:arm-uwp=fail -graphicsmagick:arm-uwp=fail -graphicsmagick:x64-uwp=fail -graphite2:arm-uwp=fail -graphite2:x64-uwp=fail -graphqlparser:arm-uwp=fail -graphqlparser:x64-uwp=fail -gsl:arm-uwp=fail -gsl:x64-uwp=fail -# https://github.com/microsoft/vcpkg/pull/11048 -gsoap:x64-linux=fail -gsoap:x64-osx=fail -gsoap:x64-uwp=fail -gtk:x64-linux=fail -gtk:x86-windows=ignore -guetzli:x64-osx=fail -h3:arm64-windows=fail -h3:arm-uwp=fail -h3:x64-uwp=fail -halide:x64-windows-static=fail -hdf5:arm64-windows=fail -hdf5:arm-uwp=fail -hdf5:x64-uwp=fail -healpix:x86-windows=fail -healpix:x64-windows=fail -healpix:x64-windows-static=fail -healpix:x64-uwp=fail -healpix:arm64-windows=fail -healpix:arm-uwp=fail -healpix:x64-osx=fail -hidapi:arm64-windows=fail -hidapi:arm-uwp=fail -hidapi:x64-linux=fail -hidapi:x64-osx=fail -hidapi:x64-uwp=fail -hiredis:arm-uwp=fail -hiredis:x64-uwp=fail -hpx:x64-windows-static=fail -hpx:x64-linux=fail -hwloc:arm64-windows=fail -hwloc:arm-uwp=fail -hwloc:x64-uwp=fail -hyperscan:x64-linux=ignore -# hypre has a conflict with 'superlu' port -hypre:x64-linux=skip -hypre:x64-osx=skip -icu:arm64-windows=fail -icu:arm-uwp=fail -icu:x64-uwp=fail -idevicerestore:x64-linux=fail -idevicerestore:x64-osx=fail -ignition-common1:x64-linux=fail -ignition-msgs1:arm64-windows=fail -ignition-msgs1:arm-uwp=fail -ignition-msgs1:x64-uwp=fail -ignition-msgs5:x64-linux=fail -ignition-msgs5:arm64-windows=fail -ignition-msgs5:arm-uwp=fail -ignition-msgs5:x64-uwp=fail -ignition-msgs5:x64-osx=skip -imgui-sfml:x64-linux=ignore -intel-ipsec:arm64-windows=fail -intel-ipsec:arm-uwp=fail -intel-ipsec:x64-osx=fail -intel-ipsec:x64-uwp=fail -intel-ipsec:x64-windows=fail -intel-ipsec:x64-windows-static=fail -intel-ipsec:x86-windows=fail -intel-mkl:arm64-windows=fail -intel-mkl:arm-uwp=fail -intel-mkl:x64-linux=fail -intel-mkl:x64-osx=fail -intel-mkl:x64-uwp=fail -intel-mkl:x64-windows=fail -intel-mkl:x64-windows-static=fail -intel-mkl:x86-windows=fail -intelrdfpmathlib:arm-uwp=fail -intelrdfpmathlib:x64-linux=fail -intelrdfpmathlib:x64-uwp=fail -irrlicht:arm64-windows=fail -irrlicht:arm-uwp=fail -irrlicht:x64-osx=fail -irrlicht:x64-uwp=fail -isal:arm64-windows=fail -isal:arm-uwp=fail -isal:x64-osx=fail -isal:x64-uwp=fail -isal:x64-windows=fail -isal:x64-windows-static=fail -isal:x86-windows=fail -itk:x64-windows=fail -itk:x64-windows-static=fail -itk:x86-windows=fail -ixwebsocket:x64-linux=ignore -jack2:arm-uwp=fail -jack2:x64-uwp=fail -jaeger-client-cpp:arm64-windows=fail -jbig2dec:arm-uwp=fail -jbig2dec:x64-uwp=fail -jemalloc:arm64-windows=fail -jemalloc:arm-uwp=fail -jemalloc:x64-linux=fail -jemalloc:x64-osx=fail -jemalloc:x64-uwp=fail -jemalloc:x64-windows-static=fail -jinja2cpplight:arm-uwp=fail -jinja2cpplight:x64-uwp=fail -keystone:arm-uwp=fail -keystone:x64-uwp=fail -kinectsdk1:arm64-windows=fail -kinectsdk1:arm-uwp=fail -kinectsdk1:x64-linux=fail -kinectsdk1:x64-osx=fail -kinectsdk2:arm64-windows=fail -kinectsdk2:arm-uwp=fail -kinectsdk2:x64-linux=fail -kinectsdk2:x64-osx=fail -lastools:arm-uwp=fail -lastools:x64-uwp=fail -laszip:arm-uwp=fail -laszip:x64-uwp=fail -lcm:x64-linux=fail -lcm:x64-osx=fail -leptonica:x64-uwp=fail -leptonica:arm-uwp=fail -leveldb:arm-uwp=fail -leveldb:x64-uwp=fail -libaiff:x64-linux=fail -libarchive:arm-uwp=fail -libass:x64-windows-static=fail -libb2:x86-windows=fail -libb2:x64-windows=fail -libb2:x64-windows-static=fail -libb2:x64-uwp=fail -libb2:arm64-windows=fail -libb2:arm-uwp=fail -libbf:arm64-windows=fail -libbf:arm-uwp=fail -libbf:x64-uwp=fail -libbf:x64-windows=fail -libbf:x64-windows-static=fail -libbf:x86-windows=fail -libbson:arm-uwp=fail -libbson:x64-uwp=fail -libcds:arm64-windows=fail -libcds:arm-uwp=fail -libcds:x64-uwp=fail -libconfig:x64-osx=fail -libcopp:arm64-windows=fail -libcopp:arm-uwp=fail -libcopp:x64-windows-static=fail -libcrafter:x86-windows=fail -libcrafter:x64-windows=fail -cpuid:arm-uwp=fail -cpuid:x64-uwp=fail -cpuid:arm64-windows=fail -libdatrie:x64-linux=fail -libdatrie:x64-osx=fail -libdisasm:arm-uwp=fail -libdisasm:x64-uwp=fail -libdshowcapture:arm-uwp=fail -libdshowcapture:x64-linux=fail -libdshowcapture:x64-osx=fail -libdshowcapture:x64-uwp=fail -libepoxy:arm64-windows=fail -libepoxy:arm-uwp=fail -libepoxy:x64-osx=fail -libepoxy:x64-uwp=fail -libepoxy:x64-windows-static=fail -libevent:arm-uwp=fail -libevent:x64-uwp=fail -libevhtp:x86-windows=fail -libevhtp:x64-windows=fail -libevhtp:x64-windows-static=fail -libevhtp:x64-uwp=fail -libevhtp:arm64-windows=fail -libevhtp:arm-uwp=fail -libexif:arm-uwp=fail -libexif:x64-uwp=fail -libfabric:arm-uwp=fail -libfabric:x64-linux=fail -libfabric:x64-osx=fail -libfabric:x64-uwp=fail -libfabric:x64-windows=ignore -libfabric:x64-windows-static=fail -libfreenect2:arm64-windows=fail -libgd:x64-linux=ignore -libgit2:arm-uwp=fail -libgit2:x64-uwp=fail -libgo:arm-uwp=fail -libgo:x64-uwp=fail -libgo:arm64-windows=fail -libgo:x64-windows=fail -libgo:x86-windows=fail -libgpod:arm64-windows=fail -libgpod:arm-uwp=fail -libgpod:x64-uwp=fail -libgpod:x64-windows=fail -libgpod:x64-windows-static=fail -libgpod:x86-windows=fail -libhdfs3:arm64-windows=fail -libhdfs3:arm-uwp=fail -libhdfs3:x64-uwp=fail -libhdfs3:x64-windows=fail -libhdfs3:x64-windows-static=fail -libhdfs3:x86-windows=fail -libhdfs3:x64-linux=fail -libhydrogen:arm64-windows=fail -libics:arm-uwp=fail -libics:x64-uwp=fail -libidn2:x64-linux=fail -libidn2:x64-osx=fail -libigl:arm64-windows=fail -libigl:arm-uwp=fail -libigl:x64-uwp=fail -liblemon:arm-uwp=fail -liblemon:x64-uwp=fail -liblinear:arm-uwp=fail -liblinear:x64-uwp=fail -liblo:arm-uwp=fail -liblo:x64-linux=fail -liblo:x64-osx=fail -liblo:x64-uwp=fail -liblsl:arm64-windows=fail -liblsl:arm-uwp=fail -liblsl:x64-linux=fail -liblsl:x64-osx=fail -liblsl:x64-uwp=fail -libmad:arm-uwp=fail -libmad:x64-uwp=fail -libmagic:x86-windows=fail -libmagic:x64-windows=fail -libmagic:x64-windows-static=fail -libmagic:x64-uwp=fail -libmagic:arm64-windows=fail -libmagic:arm-uwp=fail -libmariadb:arm64-windows = skip -libmariadb:arm-uwp = skip -libmariadb:x64-linux = skip -libmariadb:x64-osx = skip -libmariadb:x64-uwp = skip -libmariadb:x64-windows = skip -libmariadb:x64-windows-static = skip -libmariadb:x86-windows = skip -# libmesh installs tons of problematic files that conflict with other ports (boost, eigen, etc) -libmesh:arm64-windows=skip -libmesh:arm-uwp=skip -libmesh:x64-uwp=skip -libmesh:x64-windows=skip -libmesh:x64-windows-static=skip -libmesh:x86-windows=skip -libmesh:x64-osx=skip -libmesh:x64-linux=skip -libmodbus:arm-uwp=fail -libmodbus:x64-uwp=fail -libmodman:arm-uwp=fail -libmodman:x64-uwp=fail -libmodman:x64-windows-static=fail -libmodplug:arm-uwp=fail -libmodplug:x64-uwp=fail -libmpeg2:arm-uwp=fail -libmpeg2:x64-linux=fail -libmpeg2:x64-osx=fail -libmpeg2:x64-uwp=fail -libmupdf:x64-osx=fail -libmysql:x86-windows=fail -libnice:x64-linux=fail -libnice:x64-osx=fail -libodb-boost:x64-linux=ignore -libodb-pgsql:x64-linux=ignore -libodb-pgsql:x64-windows=ignore -libopenmpt:x64-linux=fail -libopenmpt:x64-osx=fail -libopusenc:arm-uwp=fail -libopusenc:x64-linux=fail -libopusenc:x64-osx=fail -libopusenc:x64-uwp=fail -libosip2:arm64-windows=fail -libosip2:arm-uwp=fail -libosip2:x64-uwp=fail -libosip2:x64-windows=fail -libosip2:x64-windows-static=fail -libosip2:x86-windows=fail -libp7-baical:arm64-windows = skip -libp7-baical:arm-uwp = skip -libp7-baical:x64-linux = skip -libp7-baical:x64-osx = skip -libp7-baical:x64-uwp = skip -libp7-baical:x64-windows = skip -libp7-baical:x64-windows-static = skip -libp7-baical:x86-windows = skip -libp7client:arm64-windows=fail -libp7client:arm-uwp=fail -libp7client:x64-linux=fail -libp7client:x64-osx=fail -libp7client:x64-uwp=fail -libpcap:arm64-windows=fail -libpcap:arm-uwp=fail -libpcap:x64-osx=fail -libpcap:x64-uwp=fail -libpcap:x64-windows-static=fail -libpff:arm-uwp=fail -libpff:x64-linux=fail -libpff:x64-osx=fail -libpff:x64-uwp=fail -libpff:x64-windows-static=fail -libplist:x64-windows-static=fail -libpng-apng:arm64-windows = skip -libpng-apng:arm-uwp = skip -libpng-apng:x64-linux = skip -libpng-apng:x64-osx = skip -libpng-apng:x64-uwp = skip -libpng-apng:x64-windows = skip -libpng-apng:x64-windows-static = skip -libpng-apng:x86-windows = skip -libpq:arm-uwp=fail -libpq:x64-uwp=fail -libqcow:arm-uwp=fail -libqcow:x64-uwp=fail -libqcow:x64-windows-static=fail -librabbitmq:x64-linux=ignore -libraqm:x64-windows-static=fail -librdkafka:arm-uwp=fail -librdkafka:x64-uwp=fail - -# Conflicts with openssl -boringssl:arm64-windows = skip -boringssl:arm-uwp = skip -boringssl:x64-linux = skip -boringssl:x64-osx = skip -boringssl:x64-uwp = skip -boringssl:x64-windows = skip -boringssl:x64-windows-static = skip -boringssl:x86-windows = skip -libressl:arm64-windows = skip -libressl:arm-uwp = skip -libressl:x64-linux = skip -libressl:x64-osx = skip -libressl:x64-uwp = skip -libressl:x64-windows = skip -libressl:x64-windows-static = skip -libressl:x86-windows = skip -librsync:arm-uwp=fail -librsync:x64-uwp=fail -libsamplerate:arm64-windows=fail -libsamplerate:arm-uwp=fail -libsamplerate:x64-osx=fail -libsoundio:arm64-windows=fail -libsoundio:arm-uwp=fail -libsoundio:x64-uwp=fail -libsrt:arm-uwp=fail -libsrt:x64-uwp=fail -libssh:arm64-windows=fail -libssh:arm-uwp=fail -libssh:x64-uwp=fail -libstk:arm-uwp=fail -libstk:x64-uwp=fail -libtins:arm-uwp=fail -libtins:x64-uwp=fail -libtomcrypt:arm64-windows=fail -libtomcrypt:arm-uwp=fail -libtorrent:arm-uwp=fail -libtorrent:x64-uwp=fail -libudis86:arm-uwp=fail -libudis86:x64-linux=fail -libudis86:x64-osx=fail -libudis86:x64-uwp=fail -libudns:arm64-windows=fail -libudns:arm-uwp=fail -libudns:x64-uwp=fail -libudns:x64-windows=fail -libudns:x64-windows-static=fail -libudns:x86-windows=fail -libudns:x64-osx=fail -libui:arm-uwp=fail -libui:x64-linux=fail -libui:x64-uwp=fail -libusb:arm-uwp=fail -libusb:x64-linux=fail -libusb:x64-osx=fail -libusb:x64-uwp=fail -libusbmuxd:arm-uwp=fail -libusbmuxd:x64-uwp=fail -libusbmuxd:x64-linux=fail -libusbmuxd:x64-osx=fail -libusb-win32:arm-uwp=fail -libusb-win32:x64-linux=fail -libusb-win32:x64-osx=fail -libusb-win32:x64-uwp=fail -libuuid:arm64-windows=fail -libuuid:arm-uwp=fail - -# Causes build failures in vxl and podofo on osx -# Conflicts with Darwin kernel sdk uuid.h (has missing definitions) -libuuid:x64-osx = skip -libuuid:x64-uwp=fail -libuuid:x64-windows=fail -libuuid:x64-windows-static=fail -libuuid:x86-windows=fail -libuv:arm-uwp=fail -libuv:x64-uwp=fail -libvmdk:arm-uwp=fail -libvmdk:x64-uwp=fail -libwandio:x86-windows=fail -libwandio:x64-windows=fail -libwandio:x64-windows-static=fail -libwandio:x64-uwp=fail -libwandio:arm64-windows=fail -libwandio:arm-uwp=fail -libwebsockets:arm-uwp=fail -libwebsockets:x64-uwp=fail -libxmp-lite:x64-linux=fail -libxmp-lite:x64-osx=fail -libxslt:arm-uwp=fail -libxslt:x64-osx=fail -libxslt:x64-uwp=fail -libyuv:arm-uwp=fail -libyuv:x64-uwp=fail -libzippp:x64-linux=ignore -licensepp:arm-uwp=fail -licensepp:x64-uwp=fail -linenoise-ng:arm-uwp=fail -linenoise-ng:x64-uwp=fail -live555:arm64-windows=fail -live555:arm-uwp=fail -live555:x64-linux=fail -live555:x64-osx=fail -live555:x64-uwp=fail -live555:x64-windows=fail -live555:x64-windows-static=fail -live555:x86-windows=fail -llgl:arm-uwp=fail -llgl:x64-uwp=fail -llvm:arm-uwp=fail -llvm:arm64-windows=fail -llvm:x64-uwp=fail -lmdb:arm-uwp=fail -lmdb:x64-uwp=fail -log4cplus:arm-uwp=fail -log4cplus:x64-uwp=fail -log4cpp:arm-uwp=fail -log4cpp:x64-uwp=fail -log4cxx:arm64-windows=fail -log4cxx:arm-uwp=fail -log4cxx:x64-linux=fail -log4cxx:x64-uwp=fail -log4cxx:x64-windows-static=fail -log4cxx:x64-osx=fail -lua:arm-uwp=fail -lua:x64-uwp=fail -luajit:arm64-windows = skip -luajit:arm-uwp = skip -luajit:x64-linux = skip -luajit:x64-osx = skip -luajit:x64-uwp = skip -luajit:x64-windows = skip -luajit:x64-windows-static = skip -luajit:x86-windows = skip -luasocket:x64-linux=fail -luasocket:x64-osx=fail -lzfse:arm-uwp=fail -magnum:arm64-windows=skip -marl:arm-uwp=fail -marl:x64-uwp=fail -mathgl:x64-osx=fail -mathgl:x64-uwp=fail -mathgl:x64-linux=ignore -matio:x64-linux=fail -matio:x64-osx=fail -mbedtls:arm-uwp=fail -mbedtls:x64-uwp=fail -mdnsresponder:arm64-windows=fail -mdnsresponder:arm-uwp=fail -mdnsresponder:x64-linux=fail -mdnsresponder:x64-osx=fail -mdnsresponder:x64-uwp=fail -mecab:arm64-windows = skip -mecab:arm-uwp = skip -mecab:x64-linux = skip -mecab:x64-uwp = skip -mecab:x64-windows = skip -mecab:x64-windows-static = skip -mecab:x86-windows = skip -memorymodule:arm-uwp=fail -memorymodule:x64-linux=fail -memorymodule:x64-osx=fail -memorymodule:x64-uwp=fail -meschach:arm-uwp=fail -meschach:x64-linux=fail -meschach:x64-osx=fail -meschach:x64-uwp=fail -metis:arm-uwp=fail -metis:x64-uwp=fail -metrohash:arm-uwp=fail -metrohash:x64-uwp=fail -metrohash:x86-windows=fail -metrohash:arm64-windows=fail -mhook:arm64-windows=fail -mhook:arm-uwp=fail -mhook:x64-linux=fail -mhook:x64-osx=fail -mhook:x64-uwp=fail -milerius-sfml-imgui:x64-osx=fail -milerius-sfml-imgui:x64-windows-static=fail -milerius-sfml-imgui:x64-linux=ignore -mimalloc:arm64-windows=fail -mimalloc:arm-uwp=fail -mimalloc:x64-uwp=fail -minhook:arm64-windows=fail -minhook:arm-uwp=fail -minhook:x64-linux=fail -minhook:x64-osx=fail -minhook:x64-uwp=fail -minifb:arm-uwp=fail -minifb:x64-uwp=fail -minisat-master-keying:arm-uwp=fail -minisat-master-keying:x64-uwp=fail -miniupnpc:arm-uwp=fail -miniupnpc:x64-uwp=fail -minizip:arm-uwp=fail -minizip:x64-uwp=fail -# Conflicts with signalrclient -microsoft-signalr:arm64-windows=skip -microsoft-signalr:arm-uwp=skip -microsoft-signalr:x64-linux=skip -microsoft-signalr:x64-osx=skip -microsoft-signalr:x64-uwp=skip -microsoft-signalr:x64-windows=skip -microsoft-signalr:x64-windows-static=skip -microsoft-signalr:x86-windows=skip -mman:x64-linux=fail -mman:x64-osx=fail -mmloader:arm64-windows=fail -mmloader:arm-uwp=fail -mmloader:x64-linux=fail -mmloader:x64-osx=fail -mmloader:x64-uwp=fail -mmloader:x64-windows=fail -mmloader:x86-windows=fail -# mmx installs many problematic headers, such as `json.h` and `sched.h` -mmx:x64-windows=skip -mmx:x64-windows-static=skip -mmx:x86-windows=skip -mmx:x64-linux=skip -mmx:x64-osx=skip -mmx:arm-uwp=skip -mmx:x64-uwp=skip -mmx:arm64-windows=skip -# Flaky strange linker error -mongo-c-driver:x64-osx=skip -mongoose:arm-uwp=fail -mongoose:x64-uwp=fail -monkeys-audio:arm64-windows=fail -monkeys-audio:arm-uwp=fail -monkeys-audio:x64-linux=fail -monkeys-audio:x64-osx=fail -monkeys-audio:x64-uwp=fail -monkeys-audio:x64-windows-static=fail -moos-core:arm-uwp=fail -moos-core:x64-uwp=fail -moos-core:x64-windows=ignore -moos-core:x64-windows-static=fail -moos-core:x86-windows=ignore -moos-essential:arm64-windows=fail -moos-essential:x64-windows=fail -moos-essential:x86-windows=fail -moos-essential:x64-linux=ignore -mozjpeg:arm64-windows = skip -mozjpeg:arm-uwp = skip -mozjpeg:x64-linux = skip -mozjpeg:x64-osx = skip -mozjpeg:x64-uwp = skip -mozjpeg:x64-windows = skip -mozjpeg:x64-windows-static = skip -mozjpeg:x86-windows = skip -# mpir conflicts with gmp -# see https://github.com/microsoft/vcpkg/issues/11756 -mpir:x86-windows=skip -mpir:x64-windows=skip -mpir:x64-windows-static=skip -mpir:arm64-windows=skip -mpir:arm-uwp=skip -mpir:x64-uwp=skip -mpir:x64-osx=skip -mpir:x64-linux=skip -msix:x64-linux=fail -msix:x64-osx=fail -msix:x64-windows-static=fail -msmpi:arm64-windows=fail -msmpi:arm-uwp=fail -msmpi:x64-linux=fail -msmpi:x64-osx=fail -msmpi:x64-uwp=fail -munit:arm-uwp=fail -munit:arm64-windows=fail -munit:x64-uwp=fail -# Though `vcpkg_configure_meson` and `vcpkg_install_meson` support -# `x64-linux` and `x64-osx` now, it still failed on these targets. -# See: https://github.com/microsoft/vcpkg/pull/6780 -munit:x64-linux=fail -munit:x64-osx=fail -muparser:arm-uwp=fail -muparser:x64-uwp=fail -murmurhash:arm-uwp=fail -murmurhash:x64-uwp=fail -murmurhash:arm64-windows=fail -nana:arm-uwp=fail -nana:x64-linux=fail -nana:x64-osx=fail -nana:x64-uwp=fail -nanodbc:arm-uwp=fail -nanodbc:x64-osx=fail -nanodbc:x64-uwp=fail -nanodbc:x64-linux=skip -nanogui:arm64-windows=fail -nanorange:arm64-windows=fail -nanorange:arm-uwp=fail -nanorange:x64-linux=fail -nanorange:x64-osx=fail -nanorange:x64-uwp=fail -nanorange:x64-windows=fail -nanorange:x64-windows-static=fail -nanorange:x86-windows=fail -nanovg:arm-uwp=fail -nanovg:arm64-windows=ignore -nanovg:x64-uwp=fail -nanovg:x64-linux=ignore -nanovg:x64-windows=ignore -nanovg:x64-windows-static=ignore -nanovg:x86-windows=skip -nativefiledialog:arm-uwp=fail -nativefiledialog:x64-uwp=fail -netcdf-cxx4:x64-linux=ignore -nethost:x64-uwp=fail -nethost:arm-uwp=fail -nettle:x64-windows-static=skip -nettle:x64-windows=skip -nettle:x64-osx=fail -networkdirect-sdk:arm64-windows=fail -networkdirect-sdk:arm-uwp=fail -networkdirect-sdk:x64-linux=fail -networkdirect-sdk:x64-osx=fail -networkdirect-sdk:x64-uwp=fail -networkdirect-sdk:x86-windows=fail -nmslib:arm64-windows=fail -nmslib:arm-uwp=fail -nmslib:x64-uwp=fail -nng:arm-uwp=fail -nng:x64-uwp=fail -nrf-ble-driver:arm-uwp=fail -nrf-ble-driver:x64-uwp=fail -nrf-ble-driver:x64-linux=ignore -numactl:arm64-windows=fail -numactl:arm-uwp=fail -numactl:x64-osx=fail -numactl:x64-uwp=fail -numactl:x64-windows=fail -numactl:x64-windows-static=fail -numactl:x86-windows=fail -nvtt:arm64-windows=fail -nvtt:arm-uwp=fail -nvtt:x64-uwp=fail -ocilib:arm64-windows=fail -ocilib:arm-uwp=fail -ocilib:x64-uwp=fail -ocilib:x64-windows-static=fail -octomap:arm-uwp=fail -octomap:x64-uwp=fail -ode:arm64-windows=fail -ode:arm-uwp=fail -ode:x64-uwp=fail -ode:x64-linux=ignore -offscale-libetcd-cpp:arm64-windows=fail -offscale-libetcd-cpp:arm-uwp=fail -offscale-libetcd-cpp:x64-uwp=fail -ogdf:arm64-windows = skip -ogdf:arm-uwp = skip -ogdf:x64-osx=fail -ogdf:x64-uwp = skip -ogdf:x64-windows = skip -ogdf:x64-windows-static = skip -ogdf:x86-windows = skip -ogre:x64-osx=fail -# Conflicts with ogre -ogre-next:arm64-windows = skip -ogre-next:arm-uwp = skip -ogre-next:x64-osx = skip -ogre-next:x64-linux = skip -ogre-next:x64-uwp = skip -ogre-next:x64-windows = skip -ogre-next:x64-windows-static = skip -ogre-next:x86-windows = skip -ois:arm64-windows=fail -ois:arm-uwp=fail -ois:x64-uwp=fail -open62541:arm-uwp=fail -open62541:x64-uwp=fail -openal-soft:arm-uwp=fail -openal-soft:x64-uwp=fail -openblas:arm64-windows=fail -openblas:arm-uwp=fail -# opencc/deps/rapidjson-1.1.0/rapidjson.h: Unknown machine endianess detected -opencc:arm64-windows=fail -# opencc/deps/marisa-0.2.5/lib/marisa/grimoire/io/mapper.cc currently doesn't support UWP. -opencc:arm-uwp=fail -opencc:x64-uwp=fail -opencensus-cpp:arm64-windows=fail -opencensus-cpp:x64-windows=fail -opencensus-cpp:x64-windows-static=fail -opencensus-cpp:x86-windows=fail -opencensus-cpp:x64-uwp=fail -opencl:arm-uwp=fail -opencl:x64-uwp=fail -opencolorio:x64-linux=ignore -opencsg:x64-uwp=fail -opencv2:arm64-windows = skip -opencv2:arm-uwp = skip -opencv2:x64-linux = skip -opencv2:x64-osx = skip -opencv2:x64-uwp = skip -opencv2:x64-windows = skip -opencv2:x64-windows-static = skip -opencv2:x86-windows = skip -opencv3:arm64-windows = skip -opencv3:arm-uwp = skip -opencv3:x64-linux = skip -opencv3:x64-osx = skip -opencv3:x64-uwp = skip -opencv3:x64-windows = skip -opencv3:x64-windows-static = skip -opencv3:x86-windows = skip -opendnp3:x64-uwp=fail -opendnp3:arm-uwp=fail -openexr:arm64-windows=fail -openexr:arm-uwp=fail -openexr:x64-uwp=fail -opengl:arm64-windows=fail -opengl:arm-uwp=fail -openimageio:x64-linux=ignore -openmama:x64-windows=ignore -openmama:x86-windows=ignore -openmama:x64-linux=fail -openmama:x64-osx=fail -openmesh:arm64-windows=fail -openmesh:arm-uwp=fail -openmesh:x64-uwp=fail -openmpi:arm64-windows=fail -openmpi:arm-uwp=fail -openmpi:x64-uwp=fail -openmpi:x64-windows=fail -openmpi:x64-windows-static=fail -openmpi:x86-windows=fail -openmvg:x64-linux=ignore -openmvs:x64-linux=fail -openni2:x64-uwp=fail -openni2:x64-windows-static=fail -openscap:x64-linux=fail -openssl-unix:arm64-windows=fail -openssl-unix:arm-uwp=fail -openssl-unix:x64-uwp=fail -openssl-unix:x64-windows=fail -openssl-unix:x64-windows-static=fail -openssl-unix:x86-windows=fail -openssl-uwp:arm64-windows=fail -openssl-uwp:x64-linux=fail -openssl-uwp:x64-osx=fail -openssl-uwp:x64-windows=fail -openssl-uwp:x64-windows-static=fail -openssl-uwp:x86-windows=fail -openssl-windows:arm-uwp=fail -openssl-windows:x64-linux=fail -openssl-windows:x64-osx=fail -openssl-windows:x64-uwp=fail -opentracing:arm-uwp=fail -opentracing:x64-uwp=fail -openvdb:x64-linux=ignore -openvdb:x64-osx=fail -#openvdb:x64-windows-static=fail # https://github.com/microsoft/vcpkg/pull/10816#issuecomment-613784827 -openvpn3:x64-osx=fail -openvr:arm64-windows=fail -openvr:arm-uwp=fail -openvr:x64-osx=fail -openvr:x64-uwp=fail -openxr-loader:arm64-windows=fail -openxr-loader:arm-uwp=fail -openxr-loader:x64-osx=fail -openxr-loader:x64-uwp=fail -optional-bare:arm64-windows = skip -optional-bare:arm-uwp = skip -optional-bare:x64-linux = skip -optional-bare:x64-osx = skip -optional-bare:x64-uwp = skip -optional-bare:x64-windows = skip -optional-bare:x64-windows-static = skip -optional-bare:x86-windows = skip -opusfile:arm-uwp=fail -opusfile:x64-uwp=fail -orc:x64-linux=ignore -orocos-kdl:arm-uwp=fail -orocos-kdl:x64-uwp=fail -osg:x86-windows=skip -osg:x64-windows=skip -osgearth:x64-osx=fail -osgearth:x64-linux=fail -osgearth:x64-windows-static=fail -osg-qt:x64-windows-static=fail -otl:x64-windows=ignore -otl:x64-windows-static=ignore -otl:x64-uwp=ignore -otl:x64-linux=ignore -otl:x86-windows=ignore -paho-mqtt:arm-uwp=fail -paho-mqtt:x64-uwp=fail -pangolin:x64-linux=fail -pangolin:x64-osx=fail -pangolin:x64-uwp=fail -pangolin:x64-windows-static=fail -pangomm:x64-osx=fail -pangomm:x64-windows=ignore -pangomm:x86-windows=ignore -pangomm:arm64-windows=fail -parmetis:x64-linux=fail -parmetis:x64-osx=fail -pcre2:arm-uwp=fail -pdal:x64-linux=fail -pdal:x64-osx=fail -pdal-c:x64-windows-static=fail -pdcurses:arm-uwp=fail -pdcurses:x64-linux=fail -pdcurses:x64-osx=fail -pdcurses:x64-uwp=fail -pdcurses:x64-windows-static=fail -pfring:arm64-windows=fail -pfring:arm-uwp=fail -pfring:x64-uwp=fail -pfring:x64-windows=fail -pfring:x64-windows-static=fail -pfring:x86-windows=fail -pfring:x64-osx=fail -# pfring on Linux currently fails because its build scripts enable warnings as -# errors, and warnings trigger with the Linux kernel headers in the Azure images. -pfring:x64-linux=fail -physfs:arm64-windows=fail -physx:arm64-windows=fail -physx:x64-linux=fail -physx:x64-osx=fail -piex:x64-osx=fail -pistache:arm64-windows=fail -pistache:arm-uwp=fail -pistache:x64-osx=fail -pistache:x64-uwp=fail -pistache:x64-windows=fail -pistache:x64-windows-static=fail -pistache:x86-windows=fail -pixel:x64-uwp=fail -pixel:x64-windows=fail -pixel:x64-windows-static=fail -pixel:x86-windows=fail -pixel:x64-linux=ignore -platform-folders:arm-uwp=fail -platform-folders:x64-uwp=fail -plib:arm-uwp=fail -plib:x64-osx=fail -plib:x64-uwp=fail -plibsys:arm-uwp=fail -plibsys:x64-uwp=fail -plplot:arm64-windows=fail -plplot:arm-uwp=fail -plplot:x64-uwp=fail -pmdk:arm-uwp=fail -pmdk:arm64-windows=fail -pmdk:x64-linux=fail -pmdk:x64-osx=fail -pmdk:x64-uwp=fail -pmdk:x64-windows-static=fail -pmdk:x86-windows=fail -pngwriter:arm-uwp=fail -pngwriter:x64-uwp=fail -pngwriter:x64-linux=ignore -polyhook2:arm64-windows=fail -polyhook2:arm-uwp=fail -polyhook2:x64-linux=fail -polyhook2:x64-uwp=fail -polyhook2:x64-osx=fail -portable-snippets:arm-uwp=fail -# Portaudio was broken by Ninja 1.9.0 https://github.com/ninja-build/ninja/pull/1406 -portaudio:arm-uwp=fail -portaudio:arm64-windows=fail -portaudio:x64-uwp=fail -portaudio:x64-windows-static=fail -portaudio:x64-windows=fail -portaudio:x86-windows=fail -portmidi:arm-uwp=fail -portmidi:x64-linux=fail -portmidi:x64-osx=fail -portmidi:x64-uwp=fail -ppconsul:x64-linux=ignore -pqp:arm-uwp=fail -pqp:x64-uwp=fail -proj4:arm64-windows=fail -proj4:arm-uwp=fail -proj4:x64-uwp=fail -protobuf:x64-uwp=ignore -protobuf:arm64-windows=ignore -protobuf:arm-uwp=ignore -protobuf-c:x86-windows=fail -protobuf-c:x64-windows=fail -protobuf-c:x64-windows-static=fail -protobuf-c:x64-uwp=fail -protobuf-c:arm64-windows=fail -protobuf-c:arm-uwp=fail -# proxygen fails with "Target 'Windows' not supported by proxygen!" -proxygen:x64-windows=fail -proxygen:x64-windows-static=fail -ptex:arm-uwp=fail -ptex:x64-linux=fail -ptex:x64-osx=fail -ptex:x64-uwp=fail -pthreads:arm64-windows=fail -pthreads:arm-uwp=fail -pthreads:x64-uwp=fail -python2:arm64-windows=fail -python2:arm-uwp=fail -python2:x64-linux=fail -python2:x64-osx=fail -python2:x64-uwp=fail -python3:arm64-windows=fail -python3:arm-uwp=fail -python3:x64-uwp=fail -qca:x64-linux=fail -qca:x64-osx=fail -qca:x64-windows-static=fail -qhull:arm-uwp=ignore -qhull:x64-windows-static=ignore -qhull:x64-uwp=ignore -qpid-proton:arm-uwp=fail -qpid-proton:x64-uwp=fail -qpid-proton:x64-windows-static=fail -qt5-activeqt:x64-linux=fail -qt5-activeqt:x64-osx=fail -qt5-macextras:x64-linux=fail -qt5-macextras:x64-windows=fail -qt5-macextras:x64-windows-static=fail -qt5-macextras:x86-windows=fail -# Missing system libraries -qt5-wayland:x64-osx=fail -# Missing libraries -qt5-wayland:x86-windows=fail -qt5-wayland:x64-windows=fail -qt5-wayland:x64-windows-static=fail -qt5-winextras:x64-linux=fail -qt5-winextras:x64-osx=fail -# Too big for CI. -qt5-webengine:x64-windows=skip -qt5-webengine:x86-windows=skip -# Missing prerequisites for CI success -qt5-webengine:x64-linux=fail -qt5-webengine:x64-osx=fail -# Static builds of qt5-webengine are not supported by the port itself -qt5-webengine:x64-windows-static=skip -# Missing system libraries -qt5-x11extras:x64-osx=fail -# Missing libraries -qt5-x11extras:x86-windows=fail -qt5-x11extras:x64-windows=fail -qt5-x11extras:x64-windows-static=fail -# Broken by VS2019 16.6 and throws a ton of dialogs attempting to build -# fixed by https://github.com/microsoft/vcpkg/pull/11596 -qt5-translations:x64-windows-static=skip -quickfast:x64-linux=ignore -quickfix:x64-linux=ignore -quickfix:x64-windows=ignore -quickfix:x64-windows-static=ignore -quickfix:x86-windows=ignore -quickfix:x64-uwp=fail -quickfix:arm-uwp=fail -quill:arm64-windows=fail -quill:arm-uwp=fail -quill:x64-uwp=fail -quirc:arm64-windows = skip -quirc:arm-uwp = skip -quirc:x64-linux = skip -quirc:x64-osx = skip -quirc:x64-uwp = skip -quirc:x64-windows = skip -quirc:x64-windows-static = skip -quirc:x86-windows = skip -qwt:x64-osx=ignore -rabit:x64-osx=fail -rabit:x64-linux=ignore -ragel:arm-uwp=fail -ragel:x64-uwp=fail -range-v3-vs2015:arm64-windows = skip -range-v3-vs2015:arm-uwp = skip -range-v3-vs2015:x64-linux = skip -range-v3-vs2015:x64-osx = skip -range-v3-vs2015:x64-uwp = skip -range-v3-vs2015:x64-windows = skip -range-v3-vs2015:x64-windows-static = skip -range-v3-vs2015:x86-windows = skip -rapidstring:arm64-windows=fail -rapidstring:arm-uwp=fail -rapidstring:x64-linux=fail -rapidstring:x64-uwp=fail -rapidstring:x64-windows=fail -rapidstring:x64-windows-static=fail -rapidstring:x86-windows=fail -raylib:arm64-windows=fail -raylib:arm-uwp=fail -raylib:x64-uwp=fail -readline:arm-uwp=fail -readline:x64-uwp=fail -readline-win32:arm-uwp=fail -readline-win32:x64-linux=fail -readline-win32:x64-osx=fail -readline-win32:x64-uwp=fail -readosm:x64-linux=fail -readosm:x64-osx=fail -realsense2:arm64-windows=fail -realsense2:arm-uwp=fail -realsense2:x64-linux=fail -realsense2:x64-uwp=fail -redis-plus-plus:x86-windows=fail -redis-plus-plus:x64-windows=fail -redis-plus-plus:x64-windows-static=fail -redis-plus-plus:arm64-windows=fail -replxx:arm-uwp=fail -replxx:x64-uwp=fail -reproc:arm-uwp=fail -reproc:x64-uwp=fail -restbed:arm-uwp=fail -restbed:x64-uwp=fail -rhash:arm64-windows=fail -rhash:arm-uwp=fail -rhash:x64-uwp=fail -rocksdb:arm-uwp=fail -rocksdb:x64-uwp=fail -rocksdb:x64-linux=ignore -rpclib:arm64-windows=fail -rpclib:arm-uwp=fail -rpclib:x64-uwp=fail -rpclib:x64-windows=ignore -rpclib:x86-windows=ignore -rpclib:x64-windows-static=ignore -rtlsdr:x64-uwp=fail -rtlsdr:arm64-windows=fail -rtlsdr:arm-uwp=fail -rtlsdr:x64-linux=fail -rtlsdr:x64-osx=fail -rttr:arm-uwp=fail -rttr:x64-uwp=fail -rxspencer:x64-uwp=fail -rxspencer:arm-uwp=fail -ryml:arm-uwp=fail -ryml:arm64-windows=fail -ryml:x64-osx=fail -ryu:arm-uwp=fail -ryu:x64-uwp=fail -ryu:x64-windows-static=fail -ryu:x86-windows=fail -ryu::arm64-windows=fail -scintilla:arm-uwp=fail -scintilla:x64-linux=fail -scintilla:x64-osx=fail -scintilla:x64-uwp=fail -scintilla:x64-windows-static=fail -sciter:arm64-windows=fail -sciter:arm-uwp=fail -sciter:x64-uwp=fail -sciter:x64-windows-static=fail -scnlib:arm-uwp=fail -scnlib:x64-uwp=fail -scylla-wrapper:arm-uwp=fail -scylla-wrapper:x64-linux=fail -scylla-wrapper:x64-osx=fail -scylla-wrapper:x64-uwp=fail -scylla-wrapper:x64-windows-static=fail -sdformat6:arm64-windows=fail -sdformat6:arm-uwp=fail -sdformat6:x64-uwp=fail -sdformat6:x64-linux=ignore -sdformat9:x64-linux=fail -sdformat9:arm-uwp=fail -sdformat9:x64-uwp=fail -sdl1:arm-uwp=fail -sdl1:x64-uwp=fail -sdl1:x64-osx=fail -sdl2-image:arm-uwp=fail -sdl2-image:x64-uwp=fail -sdl2-mixer:arm-uwp=fail -sdl2-mixer:x64-uwp=fail -sdl2-net:arm-uwp=fail -sdl2-net:x64-uwp=fail -# https://github.com/microsoft/vcpkg/issues/10918 -seal:arm-uwp=fail -seal:x64-uwp=fail -secp256k1:x64-linux=fail -secp256k1:x64-osx=fail -selene:x64-linux=ignore -sentencepiece:arm64-windows=fail -sentencepiece:arm-uwp=fail -sentencepiece:x64-uwp=fail -sentencepiece:x64-windows=fail -sentencepiece:x86-windows=fail -septag-sx:arm64-windows=fail -septag-sx:arm-uwp=fail -septag-sx:x64-uwp=fail -sfgui:x64-linux=ignore -sfml:arm64-windows=fail -shapelib:arm-uwp=fail -shapelib:x64-uwp=fail -shiva:x64-windows-static=fail -shiva-sfml:x64-linux=fail -shiva-sfml:x64-osx=fail -shiva-sfml:x86-windows=fail -shiva-sfml:x64-windows=fail -shogun:arm64-windows = skip -shogun:arm-uwp = skip -shogun:x64-osx = skip -shogun:x64-uwp = skip -shogun:x64-windows = skip -shogun:x64-windows-static = skip -shogun:x86-windows = skip -signalrclient:x64-uwp=fail -signalrclient:arm-uwp=fail -simdjson:arm-uwp=fail -simdjson:x86-windows=fail -skia:arm64-windows=fail -skia:arm-uwp=fail -skia:x64-linux=fail -skia:x64-uwp=fail -skia:x86-windows=fail -slikenet:arm-uwp=fail -slikenet:x64-uwp=fail -smpeg2:arm-uwp=fail -smpeg2:x64-linux=fail -smpeg2:x64-uwp=fail -soci:arm-uwp=fail -soci:x64-uwp=fail -sockpp:arm-uwp=fail -sockpp:x64-uwp=fail -soem:x64-uwp=fail -soem:arm-uwp=fail -soil:arm-uwp=fail -soil:x64-uwp=fail -soil2:arm-uwp=fail -soil2:x64-uwp=fail -sophus:x64-linux=fail -soqt:arm64-windows=fail -soqt:arm-uwp=fail -soqt:x64-uwp=fail -soundtouch:arm-uwp=fail -soundtouch:x64-linux=ignore -soundtouch:x64-uwp=fail -soundtouch:x64-windows-static=fail -spaceland:arm64-windows=fail -spaceland:arm-uwp=fail -spaceland:x64-uwp=fail -spaceland:x64-linux=ignore -spdk:x64-linux=fail -spdk-dpdk:arm64-windows=fail -spdk-dpdk:arm-uwp=fail -spdk-dpdk:x64-osx=fail -spdk-dpdk:x64-uwp=fail -spdk-dpdk:x64-windows=fail -spdk-dpdk:x64-windows-static=fail -spdk-dpdk:x86-windows=fail -spdk-ipsec:arm64-windows=fail -spdk-ipsec:arm-uwp=fail -spdk-ipsec:x64-osx=fail -spdk-ipsec:x64-uwp=fail -spdk-ipsec:x64-windows=fail -spdk-ipsec:x64-windows-static=fail -spdk-ipsec:x86-windows=fail -spdk-isal:arm64-windows=fail -spdk-isal:arm-uwp=fail -spdk-isal:x64-osx=fail -spdk-isal:x64-uwp=fail -spdk-isal:x64-windows=fail -spdk-isal:x64-windows-static=fail -spdk-isal:x86-windows=fail -speex:x64-linux=fail -speex:x64-osx=fail -speexdsp:x64-linux=fail -speexdsp:x64-osx=fail -spirv-tools:arm-uwp=fail -spirv-tools:x64-uwp=fail -stormlib:arm-uwp=fail -stormlib:x64-uwp=fail -stxxl:arm-uwp=fail -stxxl:x64-uwp=fail -# Sundials was broken by Ninja 1.9.0 https://github.com/ninja-build/ninja/pull/1406 -sundials:arm64-windows=fail -sundials:x64-windows=fail -sundials:x86-windows=fail -# Conflicts between ports: -#The following files are already installed in C:/agent/_work/1/s/installed/x64-windows-static -# and are in conflict with superlu:x64-windows-static -# -#Installed by hypre:x64-windows-static -# include/slu_Cnames.h -# include/slu_cdefs.h -# include/slu_dcomplex.h -# include/slu_ddefs.h -# include/slu_scomplex.h -# include/slu_sdefs.h -# include/slu_util.h -# include/slu_zdefs.h -# include/supermatrix.h -superlu:arm-uwp=skip -superlu:arm-windows=skip -superlu:arm64-windows=skip -superlu:x64-uwp=skip -superlu:x64-windows-static=skip -superlu:x64-windows=skip -systemc:arm64-windows=fail -systemc:arm-uwp=fail -systemc:x64-uwp=fail -taglib:x64-linux=ignore -tbb:arm64-windows=fail -tbb:arm-uwp=fail -tbb:x64-uwp=fail -tcl:arm-uwp=ignore -tcl:arm64-windows=ignore -tcl:x64-uwp=ignore -tcl:x64-linux=ignore -tcl:x64-osx=ignore -teemo:x64-uwp=fail -teemo:arm-uwp=fail -teemo:arm64-windows=fail -teemo:x64-osx=fail -telnetpp:arm-uwp=fail -telnetpp:x64-uwp=fail -tensorflow-cc:arm64-windows=fail -tensorflow-cc:x64-linux=skip -tensorflow-cc:x64-osx=skip -tensorflow-cc:x64-windows=fail -tensorflow-cc:x64-windows-static=fail -tensorflow-cc:x86-windows=fail -tesseract:x64-windows=ignore -tesseract:x64-windows-static=ignore -tesseract:x86-windows=ignore -tesseract:arm64-windows=fail -tfhe:x86-windows=fail -tfhe:x64-windows=fail -tfhe:x64-windows-static=fail -tfhe:x64-uwp=fail -tfhe:arm64-windows=fail -tfhe:arm-uwp=fail -theia:arm64-windows = skip -theia:arm-uwp = skip -theia:x64-uwp = skip -theia:x64-windows = skip -theia:x64-windows-static = skip -theia:x86-windows = skip -thor:x64-linux=fail -thor:x64-osx=fail -tidy-html5:arm-uwp=fail -tidy-html5:x64-uwp=fail -tinkerforge:arm-uwp=fail -tinkerforge:x64-uwp=fail -tinyexif:arm-uwp=fail -tinyexif:x64-uwp=fail -tinyfiledialogs:arm-uwp=fail -tinyfiledialogs:x64-uwp=fail -tinynpy:x64-linux=ignore -tiny-process-library:arm-uwp=fail -tiny-process-library:x64-uwp=fail -tinyutf8:arm64-windows=fail -tinyutf8:arm-uwp=fail -tinyutf8:x64-uwp=fail - -#Flaky on windows only due to error PRI210: 0x80070020 - File move failed -tmx:arm64-windows = skip -tmx:arm-uwp = skip -tmx:x64-uwp = skip -tmx:x64-windows = skip -tmx:x64-windows-static = skip -tmx:x86-windows = skip -tmxlite:arm-uwp=fail -tmxlite:x64-uwp=fail -tmxparser:arm64-windows=fail -tmxparser:arm-uwp=fail -tmxparser:x64-uwp=fail -tmxparser:x64-windows=fail -tmxparser:x64-windows-static=fail -tmxparser:x86-windows=fail -torch-th:arm64-windows=fail -torch-th:arm-uwp=fail -torch-th:x64-uwp=fail -torch-th:x64-windows-static=fail -tre:x64-osx=fail -treehopper:x64-windows-static=fail -turbobase64:arm64-windows=fail -turbobase64:arm-uwp=fail -turbobase64:x64-uwp=fail -turbobase64:x64-windows=fail -turbobase64:x64-windows-static=fail -turbobase64:x86-windows=fail -unicorn:arm64-windows=fail -unicorn:arm-uwp=fail -unicorn:x64-linux=fail -unicorn:x64-osx=fail -unicorn:x64-uwp=fail -unicorn-lib:x64-uwp=fail -unittest-cpp:arm64-windows=fail -unittest-cpp:arm-uwp=fail -unittest-cpp:x64-uwp=fail -unixodbc:arm64-windows=fail -unixodbc:arm-uwp=fail -unixodbc:x64-uwp=fail -unixodbc:x64-windows=fail -unixodbc:x64-windows-static=fail -unixodbc:x86-windows=fail -unrar:arm64-windows=fail -unrar:arm-uwp=fail -unrar:x64-linux=fail -unrar:x64-osx=fail -unrar:x64-uwp=fail -unrar:x64-windows-static=fail -urdfdom:x64-windows-static=fail -usd:x86-windows=fail -usrsctp:arm-uwp=fail -usrsctp:x64-uwp=fail -uthenticode:arm-uwp=fail -uthenticode:x64-uwp=fail -uvatlas:arm64-windows=fail -uvatlas:arm-uwp=fail -uvatlas:x64-linux=fail -uvatlas:x64-osx=fail -uvatlas:x64-windows-static=fail -vectorclass:arm64-windows=fail -vectorclass:arm-uwp=fail -vlpp:x64-osx=fail -vulkan:arm64-windows=fail -vulkan:arm-uwp=fail -vulkan:x64-linux=fail -vulkan:x64-osx=fail -vulkan:x64-uwp=fail -vulkan:x64-windows=fail -vulkan:x64-windows-static=fail -vulkan:x86-windows=fail -# Conflicts with latest openjpeg port (vxl ships with an old version of openjpeg) -# conflicts with qt5-location -vxl:arm64-windows = skip -vxl:arm-uwp = skip -vxl:x64-linux = skip -vxl:x64-osx = skip -vxl:x64-uwp = skip -vxl:x64-windows = skip -vxl:x64-windows-static = skip -vxl:x86-windows = skip -wampcc:arm64-windows=fail -wampcc:x64-linux=ignore -wangle:x64-linux=ignore -wavpack:arm64-windows=fail -wavpack:x64-linux=fail -wavpack:x64-osx=fail -wepoll:arm-uwp=ignore -wepoll:x64-uwp=ignore -wepoll:x64-linux=ignore -wepoll:x64-osx=ignore -wildmidi:x64-osx=fail -wincrypt:x64-linux=fail -wincrypt:x64-osx=fail -winpcap:arm64-windows = skip -winpcap:arm-uwp = skip -winpcap:x64-linux=fail -winpcap:x64-osx=fail -winpcap:x64-uwp = skip -winpcap:x64-windows = skip -winpcap:x64-windows-static = skip -winpcap:x86-windows = skip -winreg:x64-linux=fail -winreg:x64-osx=fail -winsock2:x64-linux=fail -winsock2:x64-osx=fail -wintoast:arm-uwp=fail -wintoast:x64-linux=fail -wintoast:x64-osx=fail -wintoast:x64-uwp=fail -woff2:x64-linux=fail -woff2:x64-osx=fail -woff2:x64-windows-static=fail -wpilib:arm64-windows=fail -wpilib:x64-osx=fail -wxchartdir:x64-osx=fail -wxwidgets:x64-linux=fail -x264:arm64-windows=fail -x264:arm-uwp=fail -x264:x64-uwp=ignore -x264:x64-osx=fail -x264:x86-windows=ignore -x264:x64-windows=ignore -x264:x64-windows-static=ignore -x265:arm64-windows=fail -x265:arm-uwp=fail -x265:x64-uwp=fail -xalan-c:x64-windows-static=fail -xalan-c:arm64-windows=fail -xbyak:arm64-windows=fail -xbyak:arm-uwp=fail -xbyak:x64-uwp=fail -xerces-c:arm-uwp=fail -xerces-c:x64-uwp=fail -xeus:x64-linux=ignore -xmlsec:arm-uwp=fail -xmlsec:x64-uwp=fail -# The xmsh upstream repository is gone, if we find no replacement before -# 2021-01-01 we will remove the port outright. -xmsh:arm-uwp=skip -xmsh:arm64-windows=skip -xmsh:x64-linux=skip -xmsh:x64-osx=skip -xmsh:x64-uwp=skip -xmsh:x64-windows-static=skip -xmsh:x64-windows=skip -xmsh:x86-windows=skip -xtensor-io:x64-uwp=ignore -x-plane:arm64-windows=fail -x-plane:arm-uwp=fail -x-plane:x64-linux=fail -x-plane:x86-windows=fail -yajl:arm-uwp=fail -yajl:x64-uwp=fail -yara:arm-uwp=fail -yara:x64-uwp=fail -yasm:arm64-windows=fail -yasm:arm-uwp=fail -yasm:x64-linux=fail -yasm:x64-osx=fail -yasm:x64-uwp=fail -yato:arm64-windows=fail -yato:arm-uwp=fail -yato:x64-uwp=fail -z3:arm64-windows=fail -z3:arm-uwp=fail -z3:x64-uwp=fail -zeromq:arm64-windows=fail -zeromq:arm-uwp=fail -zeromq:x64-uwp=fail -zkpp:x86-windows=fail -zkpp:x64-windows=fail -zkpp:x64-windows-static=fail -zkpp:arm64-windows=fail -zkpp:x64-uwp=fail -zkpp:arm-uwp=fail -c4core:arm-uwp=fail -c4core:arm64-windows=fail -c4core:x64-osx=fail - -# Official downloading server of CTP library is only guaranteed to be available during trading hours of China futures market -# Skip CI to avoid random failures -ctp:arm64-windows=skip -ctp:arm-uwp=skip -ctp:x64-linux=skip -ctp:x64-osx=skip -ctp:x64-uwp=skip -ctp:x64-windows=skip -ctp:x64-windows-static=skip -ctp:x86-windows=skip -protozero:arm-uwp=fail -protozero:x64-uwp=fail +########################################################################### +## This file defines the current expected build state of ports in CI. +## +## States +## pass - (default) the port builds in the CI system. If a port is +## missing from this file then it is assumed to build. +## fail - the port does not build in the CI system. +## This is not necessarily the same as if a port is expected to build +## on a developers machine because it may fail due to the machine +## configuration. When set to fail the CI system will still attempt +## to build the port and will report a CI failure until this file is updated. +## skip - Do not build this port in the CI system. +## This is added to ports that may be flaky or conflict with other +## ports. Please comment for why a port is skipped so it can be +## removed when the issue is resolved. +## ignore - attempt to build the port, but do not fail the CI test if the +## port does not build. Any ignored build failures will be reported +## in the test summary. +## +## +## CI tested triplets: +## arm64-windows +## arm-uwp +## x64-linux +## x64-osx +## x64-uwp +## x64-windows +## x64-windows-static +## x86-windows +## + + +# Add new items alphabetically + +3fd:arm64-windows=fail +3fd:arm-uwp=fail +3fd:x64-linux=fail +3fd:x64-osx=fail +3fd:x64-windows=fail +3fd:x64-windows-static=fail +3fd:x86-windows=ignore +7zip:arm64-windows=fail +7zip:arm-uwp=fail +7zip:x64-linux=fail +7zip:x64-osx=fail +7zip:x64-uwp=fail +activemq-cpp:x64-linux=fail +activemq-cpp:x64-osx=fail +akali:x64-uwp=fail +akali:arm-uwp=fail +akali:arm64-windows=fail +alac:arm-uwp=fail +alac:x64-uwp=fail +alembic:x64-osx=fail +alembic:x64-windows-static=fail +aliyun-oss-c-sdk:x64-linux=fail +aliyun-oss-c-sdk:x64-osx=fail +ampl-mp:arm64-windows=fail +ampl-mp:arm-uwp=fail +ampl-mp:x64-uwp=fail +amqpcpp:arm-uwp=fail +amqpcpp:x64-uwp=fail +angelscript:arm64-windows=fail +angelscript:arm-uwp=fail +antlr4:arm-uwp=fail +antlr4:x64-uwp=fail +anyrpc:arm-uwp=ignore +anyrpc:x86-windows=ignore +anyrpc:x64-windows-static=ignore +apr:arm-uwp=fail +apr:x64-uwp=fail +# Cross compiling CI machine cannot run gen_test_char to generate apr_escape_test_char.h +apr:arm64-windows=fail +argtable2:arm-uwp=fail +argtable2:x64-uwp=fail +arrow:arm64-windows=fail +arrow:x86-windows=fail +asiosdk:x64-linux=fail +asiosdk:x64-osx=fail +asiosdk:x64-uwp=fail +asiosdk:arm64-windows=fail +asiosdk:arm-uwp=fail +asmjit:arm64-windows=fail +asmjit:arm-uwp=fail +asyncplusplus:arm-uwp=fail +asyncplusplus:x64-uwp=fail +atk:x64-osx=fail +atk:arm64-windows=fail +atkmm:x64-linux=fail +atlmfc:x64-linux=fail +atlmfc:x64-osx=fail +aubio:x64-linux=fail +aubio:x64-osx=fail +avisynthplus:x64-linux=fail +avisynthplus:x64-windows-static=fail +avro-c:arm-uwp=fail +avro-c:x64-osx=fail +avro-c:x64-uwp=fail +aws-c-common:arm64-windows=fail +aws-c-common:arm-uwp=fail +aws-c-common:x64-uwp=fail +aws-checksums:arm64-windows=fail +aws-lambda-cpp:arm64-windows=fail +aws-lambda-cpp:arm-uwp=fail +aws-lambda-cpp:x64-uwp=fail +aws-lambda-cpp:x64-windows=fail +aws-lambda-cpp:x64-windows-static=fail +aws-lambda-cpp:x86-windows=fail +aws-lambda-cpp:x64-osx=fail +aws-sdk-cpp:x64-linux=ignore +azure-c-shared-utility:arm-uwp=fail +azure-c-shared-utility:x64-uwp=fail +basisu:x64-linux=ignore +bde:arm64-windows=fail +bde:arm-uwp=fail +bde:x64-uwp=fail +bde:x64-windows=fail +bde:x64-windows-static=fail +bde:x86-windows=fail +benchmark:arm64-windows=fail +benchmark:arm-uwp=fail +benchmark:x64-uwp=fail +berkeleydb:arm-uwp=fail +berkeleydb:x64-linux=fail +berkeleydb:x64-osx=fail +berkeleydb:x64-uwp=fail +bitserializer-rapidyaml:arm-uwp=skip +bitserializer-rapidyaml:arm64-windows=skip +bitserializer-rapidyaml:x64-osx=skip +bitserializer:arm-uwp=skip +bitserializer:arm64-windows=skip +bitserializer:x64-osx=skip +blaze:x64-windows=fail +blaze:x64-windows-static=fail +blaze:x86-windows=fail +blend2d:arm64-windows=fail +blend2d:arm-uwp=fail +blend2d:x64-uwp=fail +blitz:x64-uwp=fail +blitz:arm64-windows=fail +blitz:arm-uwp=fail +blosc:arm64-windows=fail +blosc:arm-uwp=fail +blosc:x64-uwp=fail +bond:arm-uwp=fail +bond:x64-osx=fail +bond:x64-uwp=fail +boost-coroutine:arm-uwp=fail +boost-coroutine:arm64-windows=fail +boost-fiber:arm-uwp=fail +boost-fiber:arm64-windows=fail +boost-fiber:x64-osx=fail +boost-fiber:x64-uwp=fail +boost-fiber:x64-linux=ignore +boost-filesystem:arm-uwp=fail +boost-filesystem:x64-uwp=fail +boost-iostreams:arm-uwp=fail +boost-iostreams:x64-uwp=fail +boost-locale:arm-uwp=fail +boost-locale:x64-uwp=fail +boost-log:arm-uwp=fail +boost-log:x64-uwp=fail +boost-stacktrace:arm-uwp=fail +boost-stacktrace:x64-uwp=fail +boost-test:arm-uwp=fail +boost-test:x64-uwp=fail +boost-wave:arm-uwp=fail +boost-wave:x64-uwp=fail +botan:arm64-windows=fail +botan:arm-uwp=fail +botan:x64-uwp=fail +box2d:x64-uwp=fail +box2d:arm-uwp=fail +breakpad:arm64-windows=fail +bullet3:arm64-windows=fail +bullet3:arm-uwp=fail +bullet3:x64-uwp=fail +butteraugli:x64-linux=ignore +caf:arm-uwp=fail +caf:arm64-windows=fail +caf:x64-uwp=fail +caf:x64-linux=ignore +caffe2:x86-windows=fail +caffe2:arm64-windows=fail +cairomm:x64-linux=fail +capnproto:arm64-windows=fail +capnproto:arm-uwp=fail +capnproto:x64-uwp=fail +c-ares:arm-uwp=fail +c-ares:x64-uwp=fail +cartographer:x64-osx=fail +casclib:arm-uwp=fail +casclib:x64-uwp=fail +catch-classic:arm64-windows = skip +catch-classic:arm-uwp = skip +catch-classic:x64-linux = skip +catch-classic:x64-osx = skip +catch-classic:x64-uwp = skip +catch-classic:x64-windows = skip +catch-classic:x64-windows-static = skip +catch-classic:x86-windows = skip +ccd:arm-uwp=fail +ccd:x64-uwp=fail +cello:arm-uwp=fail +cello:x64-uwp=fail +cfitsio:arm-uwp=fail +cfitsio:x64-uwp=fail +cgicc:arm-uwp=fail +cgicc:x64-uwp=fail +chakracore:arm64-windows=fail +chakracore:arm-uwp=fail +chakracore:x64-linux=fail +chakracore:x64-osx=fail +chakracore:x64-uwp=fail +chakracore:x64-windows-static=fail +# DCMTK currently has a vendored copy of libcharls.a, which causes conflicts with charls (TODO: use charls' copy) +charls:arm64-windows=skip +charls:arm-uwp=skip +charls:x64-linux=skip +charls:x64-osx=skip +charls:x64-uwp=skip +charls:x64-windows=skip +charls:x64-windows-static=skip +charls:x86-windows=skip +chartdir:arm64-windows=fail +chartdir:arm-uwp=fail +chartdir:x64-uwp=fail +chartdir:x64-windows-static=fail +chipmunk:arm64-windows=fail +chipmunk:arm-uwp=fail +chipmunk:x64-linux=fail +chipmunk:x64-osx=fail +chipmunk:x64-uwp=fail +chmlib:arm-uwp=fail +chmlib:x64-uwp=fail +civetweb:arm64-windows = skip +civetweb:arm-uwp = skip +civetweb:x64-uwp = skip +clapack:x64-uwp=fail +clblas:arm64-windows=fail +clblast:x64-osx=ignore +clblast:x64-linux=fail +clblast:x64-windows-static=fail +clockutils:x64-linux=fail +clockutils:x64-osx=fail +cmark:x64-windows-static=fail +cmcstl2:arm64-windows = skip +cmcstl2:arm-uwp = skip +cmcstl2:x64-linux = skip +cmcstl2:x64-osx = skip +cmcstl2:x64-uwp = skip +cmcstl2:x64-windows = skip +cmcstl2:x64-windows-static = skip +cmcstl2:x86-windows = skip +coin:arm64-windows=fail +coin:arm-uwp=fail +coin:x64-uwp=fail +collada-dom:x64-windows-static=fail +coolprop:arm-uwp=fail +coolprop:x64-linux=fail +coolprop:x64-osx=fail +coolprop:x64-uwp=fail +coroutine:arm-uwp=fail +coroutine:x64-linux=fail +coroutine:x64-uwp=fail +corrade:arm-uwp=fail +corrade:x64-uwp=fail +cppcms:x64-linux=fail +cppcms:x64-osx=fail +cppcms:x64-windows-static=fail +cppfs:arm-uwp=fail +cppfs:x64-uwp=fail +cppgraphqlgen:arm-uwp=ignore +cppgraphqlgen:x64-uwp=ignore +cppkafka:x64-linux=ignore +cppmicroservices:arm64-windows=fail +cppmicroservices:arm-uwp=fail +cppmicroservices:x64-uwp=fail +cpp-netlib:arm-uwp=fail +cpp-netlib:x64-uwp=fail +cpp-netlib:x64-linux=ignore +cpp-taskflow:x64-osx=fail +cppcoro:x64-linux=fail +cppcoro:arm-uwp=fail +cppcoro:x64-uwp=fail +cppunit:arm64-windows=fail +cppunit:arm-uwp=fail +cppunit:x64-linux=fail +cppunit:x64-osx=fail +cppunit:x64-uwp=fail +cpr:x64-linux=ignore +cpuinfo:arm64-windows=ignore +crashpad:arm64-windows=fail +crashpad:arm-uwp=fail +crashpad:x64-linux=fail +crashpad:x64-uwp=fail +crashpad:x86-windows=fail +crfsuite:arm-uwp=fail +crfsuite:x64-uwp=fail +crossguid:x64-osx=fail +cspice:arm-uwp=fail +cspice:x64-uwp=fail +ctemplate:arm64-windows=fail +ctemplate:arm-uwp=fail +ctemplate:x64-linux=fail +ctemplate:x64-osx=fail +cuda:x64-osx=fail +cudnn:arm64-windows=fail +cudnn:arm-uwp=fail +cudnn:x64-uwp=fail +cudnn:x64-windows-static=fail +cudnn:x86-windows=fail +dbow2:x64-osx=fail +dcmtk:arm-uwp=fail +dcmtk:arm64-windows=fail +dcmtk:x64-uwp=fail +detours:x64-linux=fail +detours:x64-osx=fail +devicenameresolver:arm-uwp=fail +devicenameresolver:x64-linux=fail +devicenameresolver:x64-osx=fail +devicenameresolver:x64-uwp=fail +devicenameresolver:x64-windows-static=fail +dimcli:arm-uwp=fail +dimcli:x64-osx=fail +dimcli:x64-uwp=fail +directxmesh:x64-linux=fail +directxmesh:x64-osx=fail +directxmesh:x64-windows-static=fail +directxtex:x64-linux=fail +directxtex:x64-osx=fail +directxtex:x64-windows-static=fail +directxtk:x64-linux=fail +directxtk:x64-osx=fail +directxtk:x64-windows-static=fail +directxtk12:x64-linux=fail +directxtk12:x64-osx=fail +directxtk12:x64-windows-static=fail +discord-game-sdk:x64-windows-static=fail +discord-rpc:arm-uwp=fail +discord-rpc:x64-uwp=fail +dlfcn-win32:arm-uwp=fail +dlfcn-win32:x64-linux=fail +dlfcn-win32:x64-osx=fail +dlfcn-win32:x64-uwp=fail +dmlc:arm-uwp=fail +dmlc:arm64-windows=ignore +dmlc:x64-uwp=fail +dmlc:x64-windows-static=ignore +dmlc:x86-windows=ignore +dpdk:arm-uwp=fail +dpdk:arm64-windows=fail +dpdk:x64-linux=fail +dpdk:x64-osx=fail +dpdk:x64-uwp=fail +dpdk:x64-windows-static=fail +dpdk:x64-windows=fail +dpdk:x86-windows=fail +duckx:arm64-windows = skip +duckx:arm-uwp = skip +duckx:x64-linux = skip +duckx:x64-osx = skip +duckx:x64-uwp = skip +duckx:x64-windows = skip +duckx:x64-windows-static = skip +duckx:x86-windows = skip +duilib:arm-uwp=fail +duilib:x64-linux=fail +duilib:x64-osx=fail +duilib:x64-uwp=fail + +# requires python@2 from brew, but that no longer exists +# python2 EOL yay! +duktape:x64-osx=skip + +dxut:arm64-windows=fail +dxut:arm-uwp=fail +dxut:x64-linux=fail +dxut:x64-osx=fail +dxut:x64-windows-static=fail +eastl:arm-uwp=fail +easyhook:arm64-windows=fail +easyhook:arm-uwp=fail +easyhook:x64-linux=fail +easyhook:x64-osx=fail +easyhook:x64-uwp=fail +easyhook:x64-windows-static=fail +easyloggingpp:arm-uwp=fail +easyloggingpp:x64-uwp=fail +eathread:arm64-windows=fail +eathread:arm-uwp=fail +eathread:x64-uwp=fail +eathread:x86-windows=fail +ebml:arm-uwp=fail +ebml:x64-uwp=fail +ecm:arm64-windows = skip +ecm:arm-uwp = skip +ecm:x64-linux = skip +ecm:x64-osx = skip +ecm:x64-uwp = skip +ecm:x64-windows = skip +ecm:x64-windows-static = skip +ecm:x86-windows = skip +ecsutil:arm64-windows=fail +ecsutil:arm-uwp=fail +ecsutil:x64-linux=fail +ecsutil:x64-osx=fail +ecsutil:x64-uwp=fail +embree2:x64-linux=fail +embree2:x64-osx=fail +embree2:x64-windows-static=fail +enet:arm-uwp=fail +enet:x64-uwp=fail +epsilon:x64-windows-static=fail +epsilon:arm-uwp=fail +epsilon:x64-linux=fail +epsilon:x64-osx=fail +epsilon:x64-uwp=fail +evpp:x64-osx=fail +expat:arm-uwp=fail +expat:x64-uwp=fail +faad2:x64-linux=fail +faad2:x64-osx=fail +fann:arm-uwp=fail +fann:x64-linux=fail +fann:x64-osx=fail +fann:x64-uwp=fail +fann:x64-windows-static=fail +farmhash:arm64-windows=fail +farmhash:arm-uwp=fail +farmhash:x64-uwp=fail +farmhash:x64-windows=fail +farmhash:x64-windows-static=fail +farmhash:x86-windows=fail +fastcdr:x64-linux=fail +fastrtps:arm-uwp=fail +fastrtps:x64-linux=fail +fastrtps:x64-osx=fail +fastrtps:x64-uwp=fail +fastrtps:x64-windows-static=fail +fdk-aac:arm64-windows=fail +fdk-aac:arm-uwp=fail +fdk-aac:x64-uwp=fail +fdlibm:arm-uwp=fail +fdlibm:x64-uwp=fail +fftw3:arm-uwp=fail +fftw3:x64-uwp=fail +flint:x64-linux=fail +flint:x64-osx=fail +fltk:arm-uwp=fail +fltk:x64-uwp=fail +fluidsynth:x64-linux=fail +fluidsynth:x64-osx=fail +fmem:arm-uwp=fail +fmem:x64-uwp=fail +fmi4cpp:arm-uwp=fail +fmi4cpp:x64-uwp=fail +fmilib:arm64-windows=fail +fmilib:arm-uwp=fail +fmilib:x64-linux=ignore +fmilib:x64-uwp=fail +fmilib:x64-windows=ignore +fmilib:x64-windows-static=ignore +fmilib:x86-windows=ignore +foonathan-memory:arm64-windows=fail +foonathan-memory:arm-uwp=fail +foonathan-memory:x64-uwp=fail +forge:x86-windows=fail +freeglut:arm64-windows=fail +freeglut:arm-uwp=fail +freeglut:x64-uwp=fail +freeglut:x64-osx=fail +freerdp:arm64-windows=fail +freerdp:arm-uwp=fail +freerdp:x64-osx=fail +freerdp:x64-uwp=fail +freetds:arm-uwp=fail +freetds:x64-linux=fail +freetds:x64-osx=fail +freetds:x64-uwp=fail +freetype-gl:x64-uwp=fail +freexl:arm-uwp=fail +freexl:arm64-windows=ignore +freexl:x64-uwp=fail +freexl:x86-windows=ignore +freexl:x64-windows=ignore +freexl:x64-windows-static=ignore +fribidi:arm64-windows=fail +fribidi:arm-uwp=fail +fribidi:x64-linux=fail +fribidi:x64-osx=fail +fribidi:x64-uwp=fail +ftgl:x64-uwp=fail +fuzzylite:arm-uwp=fail +fuzzylite:x64-linux=fail +fuzzylite:x64-osx=fail +fuzzylite:x64-uwp=fail +g3log:arm64-windows=fail +g3log:arm-uwp=fail +g3log:x64-uwp=fail +gainput:arm-uwp=fail +gainput:x64-linux=fail +gainput:x64-uwp=fail +gamma:x64-linux=fail +gamma:x64-osx=fail +gasol:arm64-windows=fail +gasol:arm-uwp=fail +gasol:x64-uwp=fail +gdcm:arm64-windows=fail +gdcm:x64-linux = skip +geographiclib:x64-linux=ignore +geos:arm-uwp=fail +geos:x64-uwp=fail +getopt:arm-uwp=fail +getopt:x64-uwp=fail +getopt-win32:arm64-windows=fail +getopt-win32:arm-uwp=fail +getopt-win32:x64-linux=fail +getopt-win32:x64-osx=fail +getopt-win32:x64-uwp=fail +getopt-win32:x64-windows-static=fail +gflags:arm-uwp=fail +gflags:x64-uwp=fail + +# Conflicts with libevent +gherkin-c:arm64-windows = skip +gherkin-c:arm-uwp = skip +gherkin-c:x64-linux=fail +gherkin-c:x64-osx=fail +gherkin-c:x64-uwp = skip +gherkin-c:x64-windows = skip +gherkin-c:x64-windows-static = skip +gherkin-c:x86-windows = skip +gl3w:arm64-windows=fail +gl3w:arm-uwp=fail +glew:arm64-windows=fail +glew:arm-uwp=fail +glfw3:arm-uwp=fail +glfw3:x64-uwp=fail +glib:x64-uwp=fail +glib:x64-windows-static=fail +glib:x64-osx=fail +globjects:x64-linux=ignore +gmmlib:arm64-windows=fail +gmmlib:arm-uwp=fail +gmmlib:x64-osx=fail +gmmlib:x64-uwp=fail +gmmlib:x64-windows=fail +gmmlib:x64-windows-static=fail +gmmlib:x86-windows=fail +google-cloud-cpp:arm64-windows=fail +google-cloud-cpp:arm-uwp=fail +google-cloud-cpp:x64-uwp=fail +gppanel:x64-osx=fail +gperf:x64-uwp=fail +gperf:arm-uwp=fail +gperftools:arm64-windows=fail +gperftools:x64-uwp=fail +gperftools:arm-uwp=fail +graphicsmagick:arm-uwp=fail +graphicsmagick:x64-uwp=fail +graphite2:arm-uwp=fail +graphite2:x64-uwp=fail +graphqlparser:arm-uwp=fail +graphqlparser:x64-uwp=fail +gsl:arm-uwp=fail +gsl:x64-uwp=fail +# https://github.com/microsoft/vcpkg/pull/11048 +gsoap:x64-linux=fail +gsoap:x64-osx=fail +gsoap:x64-uwp=fail +gtk:x64-linux=fail +gtk:x86-windows=ignore +guetzli:x64-osx=fail +h3:arm64-windows=fail +h3:arm-uwp=fail +h3:x64-uwp=fail +halide:x64-windows-static=fail +hdf5:arm64-windows=fail +hdf5:arm-uwp=fail +hdf5:x64-uwp=fail +healpix:x86-windows=fail +healpix:x64-windows=fail +healpix:x64-windows-static=fail +healpix:x64-uwp=fail +healpix:arm64-windows=fail +healpix:arm-uwp=fail +healpix:x64-osx=fail +hidapi:arm64-windows=fail +hidapi:arm-uwp=fail +hidapi:x64-linux=fail +hidapi:x64-osx=fail +hidapi:x64-uwp=fail +hiredis:arm-uwp=fail +hiredis:x64-uwp=fail +hpx:x64-windows-static=fail +hpx:x64-linux=fail +hwloc:arm64-windows=fail +hwloc:arm-uwp=fail +hwloc:x64-uwp=fail +hyperscan:x64-linux=ignore +# hypre has a conflict with 'superlu' port +hypre:x64-linux=skip +hypre:x64-osx=skip +icu:arm64-windows=fail +icu:arm-uwp=fail +icu:x64-uwp=fail +idevicerestore:x64-linux=fail +idevicerestore:x64-osx=fail +ignition-common1:x64-linux=fail +ignition-msgs1:arm64-windows=fail +ignition-msgs1:arm-uwp=fail +ignition-msgs1:x64-uwp=fail +ignition-msgs5:x64-linux=fail +ignition-msgs5:arm64-windows=fail +ignition-msgs5:arm-uwp=fail +ignition-msgs5:x64-uwp=fail +ignition-msgs5:x64-osx=skip +imgui-sfml:x64-linux=ignore +intel-ipsec:arm64-windows=fail +intel-ipsec:arm-uwp=fail +intel-ipsec:x64-osx=fail +intel-ipsec:x64-uwp=fail +intel-ipsec:x64-windows=fail +intel-ipsec:x64-windows-static=fail +intel-ipsec:x86-windows=fail +intel-mkl:arm64-windows=fail +intel-mkl:arm-uwp=fail +intel-mkl:x64-linux=fail +intel-mkl:x64-osx=fail +intel-mkl:x64-uwp=fail +intel-mkl:x64-windows=fail +intel-mkl:x64-windows-static=fail +intel-mkl:x86-windows=fail +intelrdfpmathlib:arm-uwp=fail +intelrdfpmathlib:x64-linux=fail +intelrdfpmathlib:x64-uwp=fail +irrlicht:arm64-windows=fail +irrlicht:arm-uwp=fail +irrlicht:x64-osx=fail +irrlicht:x64-uwp=fail +isal:arm64-windows=fail +isal:arm-uwp=fail +isal:x64-osx=fail +isal:x64-uwp=fail +isal:x64-windows=fail +isal:x64-windows-static=fail +isal:x86-windows=fail +itk:x64-windows=fail +itk:x64-windows-static=fail +itk:x86-windows=fail +ixwebsocket:x64-linux=ignore +jack2:arm-uwp=fail +jack2:x64-uwp=fail +jaeger-client-cpp:arm64-windows=fail +jbig2dec:arm-uwp=fail +jbig2dec:x64-uwp=fail +jemalloc:arm64-windows=fail +jemalloc:arm-uwp=fail +jemalloc:x64-linux=fail +jemalloc:x64-osx=fail +jemalloc:x64-uwp=fail +jemalloc:x64-windows-static=fail +jinja2cpplight:arm-uwp=fail +jinja2cpplight:x64-uwp=fail +keystone:arm-uwp=fail +keystone:x64-uwp=fail +kinectsdk1:arm64-windows=fail +kinectsdk1:arm-uwp=fail +kinectsdk1:x64-linux=fail +kinectsdk1:x64-osx=fail +kinectsdk2:arm64-windows=fail +kinectsdk2:arm-uwp=fail +kinectsdk2:x64-linux=fail +kinectsdk2:x64-osx=fail +lastools:arm-uwp=fail +lastools:x64-uwp=fail +laszip:arm-uwp=fail +laszip:x64-uwp=fail +lcm:x64-linux=fail +lcm:x64-osx=fail +leptonica:x64-uwp=fail +leptonica:arm-uwp=fail +leveldb:arm-uwp=fail +leveldb:x64-uwp=fail +libaiff:x64-linux=fail +libarchive:arm-uwp=fail +libass:x64-windows-static=fail +libb2:x86-windows=fail +libb2:x64-windows=fail +libb2:x64-windows-static=fail +libb2:x64-uwp=fail +libb2:arm64-windows=fail +libb2:arm-uwp=fail +libbf:arm64-windows=fail +libbf:arm-uwp=fail +libbf:x64-uwp=fail +libbf:x64-windows=fail +libbf:x64-windows-static=fail +libbf:x86-windows=fail +libbson:arm-uwp=fail +libbson:x64-uwp=fail +libcds:arm64-windows=fail +libcds:arm-uwp=fail +libcds:x64-uwp=fail +libconfig:x64-osx=fail +libcopp:arm64-windows=fail +libcopp:arm-uwp=fail +libcopp:x64-windows-static=fail +libcrafter:x86-windows=fail +libcrafter:x64-windows=fail +cpuid:arm-uwp=fail +cpuid:x64-uwp=fail +cpuid:arm64-windows=fail +libdatrie:x64-linux=fail +libdatrie:x64-osx=fail +libdisasm:arm-uwp=fail +libdisasm:x64-uwp=fail +libdshowcapture:arm-uwp=fail +libdshowcapture:x64-linux=fail +libdshowcapture:x64-osx=fail +libdshowcapture:x64-uwp=fail +libepoxy:arm64-windows=fail +libepoxy:arm-uwp=fail +libepoxy:x64-osx=fail +libepoxy:x64-uwp=fail +libepoxy:x64-windows-static=fail +libevent:arm-uwp=fail +libevent:x64-uwp=fail +libevhtp:x86-windows=fail +libevhtp:x64-windows=fail +libevhtp:x64-windows-static=fail +libevhtp:x64-uwp=fail +libevhtp:arm64-windows=fail +libevhtp:arm-uwp=fail +libexif:arm-uwp=fail +libexif:x64-uwp=fail +libfabric:arm-uwp=fail +libfabric:x64-linux=fail +libfabric:x64-osx=fail +libfabric:x64-uwp=fail +libfabric:x64-windows=ignore +libfabric:x64-windows-static=fail +libfreenect2:arm64-windows=fail +libgd:x64-linux=ignore +libgit2:arm-uwp=fail +libgit2:x64-uwp=fail +libgo:arm-uwp=fail +libgo:x64-uwp=fail +libgo:arm64-windows=fail +libgo:x64-windows=fail +libgo:x86-windows=fail +libgpod:arm64-windows=fail +libgpod:arm-uwp=fail +libgpod:x64-uwp=fail +libgpod:x64-windows=fail +libgpod:x64-windows-static=fail +libgpod:x86-windows=fail +libhdfs3:arm64-windows=fail +libhdfs3:arm-uwp=fail +libhdfs3:x64-uwp=fail +libhdfs3:x64-windows=fail +libhdfs3:x64-windows-static=fail +libhdfs3:x86-windows=fail +libhdfs3:x64-linux=fail +libhydrogen:arm64-windows=fail +libics:arm-uwp=fail +libics:x64-uwp=fail +libidn2:x64-linux=fail +libidn2:x64-osx=fail +libigl:arm64-windows=fail +libigl:arm-uwp=fail +libigl:x64-uwp=fail +liblemon:arm-uwp=fail +liblemon:x64-uwp=fail +liblinear:arm-uwp=fail +liblinear:x64-uwp=fail +liblo:arm-uwp=fail +liblo:x64-linux=fail +liblo:x64-osx=fail +liblo:x64-uwp=fail +liblsl:arm64-windows=fail +liblsl:arm-uwp=fail +liblsl:x64-linux=fail +liblsl:x64-osx=fail +liblsl:x64-uwp=fail +libmad:arm-uwp=fail +libmad:x64-uwp=fail +libmagic:x86-windows=fail +libmagic:x64-windows=fail +libmagic:x64-windows-static=fail +libmagic:x64-uwp=fail +libmagic:arm64-windows=fail +libmagic:arm-uwp=fail +libmariadb:arm64-windows = skip +libmariadb:arm-uwp = skip +libmariadb:x64-linux = skip +libmariadb:x64-osx = skip +libmariadb:x64-uwp = skip +libmariadb:x64-windows = skip +libmariadb:x64-windows-static = skip +libmariadb:x86-windows = skip +# libmesh installs tons of problematic files that conflict with other ports (boost, eigen, etc) +libmesh:arm64-windows=skip +libmesh:arm-uwp=skip +libmesh:x64-uwp=skip +libmesh:x64-windows=skip +libmesh:x64-windows-static=skip +libmesh:x86-windows=skip +libmesh:x64-osx=skip +libmesh:x64-linux=skip +libmodbus:arm-uwp=fail +libmodbus:x64-uwp=fail +libmodman:arm-uwp=fail +libmodman:x64-uwp=fail +libmodman:x64-windows-static=fail +libmodplug:arm-uwp=fail +libmodplug:x64-uwp=fail +libmpeg2:arm-uwp=fail +libmpeg2:x64-linux=fail +libmpeg2:x64-osx=fail +libmpeg2:x64-uwp=fail +libmupdf:x64-osx=fail +libmysql:x86-windows=fail +libnice:x64-linux=fail +libnice:x64-osx=fail +libodb-boost:x64-linux=ignore +libodb-pgsql:x64-linux=ignore +libodb-pgsql:x64-windows=ignore +libopenmpt:x64-linux=fail +libopenmpt:x64-osx=fail +libopusenc:arm-uwp=fail +libopusenc:x64-linux=fail +libopusenc:x64-osx=fail +libopusenc:x64-uwp=fail +libosip2:arm64-windows=fail +libosip2:arm-uwp=fail +libosip2:x64-uwp=fail +libosip2:x64-windows=fail +libosip2:x64-windows-static=fail +libosip2:x86-windows=fail +libp7-baical:arm64-windows = skip +libp7-baical:arm-uwp = skip +libp7-baical:x64-linux = skip +libp7-baical:x64-osx = skip +libp7-baical:x64-uwp = skip +libp7-baical:x64-windows = skip +libp7-baical:x64-windows-static = skip +libp7-baical:x86-windows = skip +libp7client:arm64-windows=fail +libp7client:arm-uwp=fail +libp7client:x64-linux=fail +libp7client:x64-osx=fail +libp7client:x64-uwp=fail +libpcap:arm64-windows=fail +libpcap:arm-uwp=fail +libpcap:x64-osx=fail +libpcap:x64-uwp=fail +libpcap:x64-windows-static=fail +libpff:arm-uwp=fail +libpff:x64-linux=fail +libpff:x64-osx=fail +libpff:x64-uwp=fail +libpff:x64-windows-static=fail +libplist:x64-windows-static=fail +libpng-apng:arm64-windows = skip +libpng-apng:arm-uwp = skip +libpng-apng:x64-linux = skip +libpng-apng:x64-osx = skip +libpng-apng:x64-uwp = skip +libpng-apng:x64-windows = skip +libpng-apng:x64-windows-static = skip +libpng-apng:x86-windows = skip +libpq:arm-uwp=fail +libpq:x64-uwp=fail +libqcow:arm-uwp=fail +libqcow:x64-uwp=fail +libqcow:x64-windows-static=fail +librabbitmq:x64-linux=ignore +libraqm:x64-windows-static=fail +librdkafka:arm-uwp=fail +librdkafka:x64-uwp=fail + +# Conflicts with openssl +boringssl:arm64-windows = skip +boringssl:arm-uwp = skip +boringssl:x64-linux = skip +boringssl:x64-osx = skip +boringssl:x64-uwp = skip +boringssl:x64-windows = skip +boringssl:x64-windows-static = skip +boringssl:x86-windows = skip +libressl:arm64-windows = skip +libressl:arm-uwp = skip +libressl:x64-linux = skip +libressl:x64-osx = skip +libressl:x64-uwp = skip +libressl:x64-windows = skip +libressl:x64-windows-static = skip +libressl:x86-windows = skip +librsync:arm-uwp=fail +librsync:x64-uwp=fail +libsamplerate:arm64-windows=fail +libsamplerate:arm-uwp=fail +libsamplerate:x64-osx=fail +libsoundio:arm64-windows=fail +libsoundio:arm-uwp=fail +libsoundio:x64-uwp=fail +libsrt:arm-uwp=fail +libsrt:x64-uwp=fail +libssh:arm64-windows=fail +libssh:arm-uwp=fail +libssh:x64-uwp=fail +libstk:arm-uwp=fail +libstk:x64-uwp=fail +libtins:arm-uwp=fail +libtins:x64-uwp=fail +libtomcrypt:arm64-windows=fail +libtomcrypt:arm-uwp=fail +libtorrent:arm-uwp=fail +libtorrent:x64-uwp=fail +libudis86:arm-uwp=fail +libudis86:x64-linux=fail +libudis86:x64-osx=fail +libudis86:x64-uwp=fail +libudns:arm64-windows=fail +libudns:arm-uwp=fail +libudns:x64-uwp=fail +libudns:x64-windows=fail +libudns:x64-windows-static=fail +libudns:x86-windows=fail +libudns:x64-osx=fail +libui:arm-uwp=fail +libui:x64-linux=fail +libui:x64-uwp=fail +libusb:arm-uwp=fail +libusb:x64-linux=fail +libusb:x64-osx=fail +libusb:x64-uwp=fail +libusbmuxd:arm-uwp=fail +libusbmuxd:x64-uwp=fail +libusbmuxd:x64-linux=fail +libusbmuxd:x64-osx=fail +libusb-win32:arm-uwp=fail +libusb-win32:x64-linux=fail +libusb-win32:x64-osx=fail +libusb-win32:x64-uwp=fail +libuuid:arm64-windows=fail +libuuid:arm-uwp=fail + +# Causes build failures in vxl and podofo on osx +# Conflicts with Darwin kernel sdk uuid.h (has missing definitions) +libuuid:x64-osx = skip +libuuid:x64-uwp=fail +libuuid:x64-windows=fail +libuuid:x64-windows-static=fail +libuuid:x86-windows=fail +libuv:arm-uwp=fail +libuv:x64-uwp=fail +libvmdk:arm-uwp=fail +libvmdk:x64-uwp=fail +libwandio:x86-windows=fail +libwandio:x64-windows=fail +libwandio:x64-windows-static=fail +libwandio:x64-uwp=fail +libwandio:arm64-windows=fail +libwandio:arm-uwp=fail +libwebsockets:arm-uwp=fail +libwebsockets:x64-uwp=fail +libxmp-lite:x64-linux=fail +libxmp-lite:x64-osx=fail +libxslt:arm-uwp=fail +libxslt:x64-osx=fail +libxslt:x64-uwp=fail +libyuv:arm-uwp=fail +libyuv:x64-uwp=fail +libzippp:x64-linux=ignore +licensepp:arm-uwp=fail +licensepp:x64-uwp=fail +linenoise-ng:arm-uwp=fail +linenoise-ng:x64-uwp=fail +live555:arm64-windows=fail +live555:arm-uwp=fail +live555:x64-linux=fail +live555:x64-osx=fail +live555:x64-uwp=fail +live555:x64-windows=fail +live555:x64-windows-static=fail +live555:x86-windows=fail +llgl:arm-uwp=fail +llgl:x64-uwp=fail +llvm:arm-uwp=fail +llvm:arm64-windows=fail +llvm:x64-uwp=fail +lmdb:arm-uwp=fail +lmdb:x64-uwp=fail +log4cplus:arm-uwp=fail +log4cplus:x64-uwp=fail +log4cpp:arm-uwp=fail +log4cpp:x64-uwp=fail +log4cxx:arm64-windows=fail +log4cxx:arm-uwp=fail +log4cxx:x64-linux=fail +log4cxx:x64-uwp=fail +log4cxx:x64-windows-static=fail +log4cxx:x64-osx=fail +lua:arm-uwp=fail +lua:x64-uwp=fail +luajit:arm64-windows = skip +luajit:arm-uwp = skip +luajit:x64-linux = skip +luajit:x64-osx = skip +luajit:x64-uwp = skip +luajit:x64-windows = skip +luajit:x64-windows-static = skip +luajit:x86-windows = skip +luasocket:x64-linux=fail +luasocket:x64-osx=fail +lzfse:arm-uwp=fail +magnum:arm64-windows=skip +marl:arm-uwp=fail +marl:x64-uwp=fail +mathgl:x64-osx=fail +mathgl:x64-uwp=fail +mathgl:x64-linux=ignore +matio:x64-linux=fail +matio:x64-osx=fail +mbedtls:arm-uwp=fail +mbedtls:x64-uwp=fail +mdnsresponder:arm64-windows=fail +mdnsresponder:arm-uwp=fail +mdnsresponder:x64-linux=fail +mdnsresponder:x64-osx=fail +mdnsresponder:x64-uwp=fail +mecab:arm64-windows = skip +mecab:arm-uwp = skip +mecab:x64-linux = skip +mecab:x64-uwp = skip +mecab:x64-windows = skip +mecab:x64-windows-static = skip +mecab:x86-windows = skip +memorymodule:arm-uwp=fail +memorymodule:x64-linux=fail +memorymodule:x64-osx=fail +memorymodule:x64-uwp=fail +meschach:arm-uwp=fail +meschach:x64-linux=fail +meschach:x64-osx=fail +meschach:x64-uwp=fail +metis:arm-uwp=fail +metis:x64-uwp=fail +metrohash:arm-uwp=fail +metrohash:x64-uwp=fail +metrohash:x86-windows=fail +metrohash:arm64-windows=fail +mhook:arm64-windows=fail +mhook:arm-uwp=fail +mhook:x64-linux=fail +mhook:x64-osx=fail +mhook:x64-uwp=fail +milerius-sfml-imgui:x64-osx=fail +milerius-sfml-imgui:x64-windows-static=fail +milerius-sfml-imgui:x64-linux=ignore +mimalloc:arm64-windows=fail +mimalloc:arm-uwp=fail +mimalloc:x64-uwp=fail +minhook:arm64-windows=fail +minhook:arm-uwp=fail +minhook:x64-linux=fail +minhook:x64-osx=fail +minhook:x64-uwp=fail +minifb:arm-uwp=fail +minifb:x64-uwp=fail +minisat-master-keying:arm-uwp=fail +minisat-master-keying:x64-uwp=fail +miniupnpc:arm-uwp=fail +miniupnpc:x64-uwp=fail +minizip:arm-uwp=fail +minizip:x64-uwp=fail +# Conflicts with signalrclient +microsoft-signalr:arm64-windows=skip +microsoft-signalr:arm-uwp=skip +microsoft-signalr:x64-linux=skip +microsoft-signalr:x64-osx=skip +microsoft-signalr:x64-uwp=skip +microsoft-signalr:x64-windows=skip +microsoft-signalr:x64-windows-static=skip +microsoft-signalr:x86-windows=skip +mman:x64-linux=fail +mman:x64-osx=fail +mmloader:arm64-windows=fail +mmloader:arm-uwp=fail +mmloader:x64-linux=fail +mmloader:x64-osx=fail +mmloader:x64-uwp=fail +mmloader:x64-windows=fail +mmloader:x86-windows=fail +# mmx installs many problematic headers, such as `json.h` and `sched.h` +mmx:x64-windows=skip +mmx:x64-windows-static=skip +mmx:x86-windows=skip +mmx:x64-linux=skip +mmx:x64-osx=skip +mmx:arm-uwp=skip +mmx:x64-uwp=skip +mmx:arm64-windows=skip +# Flaky strange linker error +mongo-c-driver:x64-osx=skip +mongoose:arm-uwp=fail +mongoose:x64-uwp=fail +monkeys-audio:arm64-windows=fail +monkeys-audio:arm-uwp=fail +monkeys-audio:x64-linux=fail +monkeys-audio:x64-osx=fail +monkeys-audio:x64-uwp=fail +monkeys-audio:x64-windows-static=fail +moos-core:arm-uwp=fail +moos-core:x64-uwp=fail +moos-core:x64-windows=ignore +moos-core:x64-windows-static=fail +moos-core:x86-windows=ignore +moos-essential:arm64-windows=fail +moos-essential:x64-windows=fail +moos-essential:x86-windows=fail +moos-essential:x64-linux=ignore +mozjpeg:arm64-windows = skip +mozjpeg:arm-uwp = skip +mozjpeg:x64-linux = skip +mozjpeg:x64-osx = skip +mozjpeg:x64-uwp = skip +mozjpeg:x64-windows = skip +mozjpeg:x64-windows-static = skip +mozjpeg:x86-windows = skip +# mpir conflicts with gmp +# see https://github.com/microsoft/vcpkg/issues/11756 +mpir:x86-windows=skip +mpir:x64-windows=skip +mpir:x64-windows-static=skip +mpir:arm64-windows=skip +mpir:arm-uwp=skip +mpir:x64-uwp=skip +mpir:x64-osx=skip +mpir:x64-linux=skip +msix:x64-linux=fail +msix:x64-osx=fail +msix:x64-windows-static=fail +msmpi:arm64-windows=fail +msmpi:arm-uwp=fail +msmpi:x64-linux=fail +msmpi:x64-osx=fail +msmpi:x64-uwp=fail +munit:arm-uwp=fail +munit:arm64-windows=fail +munit:x64-uwp=fail +# Though `vcpkg_configure_meson` and `vcpkg_install_meson` support +# `x64-linux` and `x64-osx` now, it still failed on these targets. +# See: https://github.com/microsoft/vcpkg/pull/6780 +munit:x64-linux=fail +munit:x64-osx=fail +muparser:arm-uwp=fail +muparser:x64-uwp=fail +murmurhash:arm-uwp=fail +murmurhash:x64-uwp=fail +murmurhash:arm64-windows=fail +nana:arm-uwp=fail +nana:x64-linux=fail +nana:x64-osx=fail +nana:x64-uwp=fail +nanodbc:arm-uwp=fail +nanodbc:x64-osx=fail +nanodbc:x64-uwp=fail +nanodbc:x64-linux=skip +nanogui:arm64-windows=fail +nanorange:arm64-windows=fail +nanorange:arm-uwp=fail +nanorange:x64-linux=fail +nanorange:x64-osx=fail +nanorange:x64-uwp=fail +nanorange:x64-windows=fail +nanorange:x64-windows-static=fail +nanorange:x86-windows=fail +nanovg:arm-uwp=fail +nanovg:arm64-windows=ignore +nanovg:x64-uwp=fail +nanovg:x64-linux=ignore +nanovg:x64-windows=ignore +nanovg:x64-windows-static=ignore +nanovg:x86-windows=skip +nativefiledialog:arm-uwp=fail +nativefiledialog:x64-uwp=fail +netcdf-cxx4:x64-linux=ignore +nethost:x64-uwp=fail +nethost:arm-uwp=fail +nettle:x64-windows-static=skip +nettle:x64-windows=skip +nettle:x64-osx=fail +networkdirect-sdk:arm64-windows=fail +networkdirect-sdk:arm-uwp=fail +networkdirect-sdk:x64-linux=fail +networkdirect-sdk:x64-osx=fail +networkdirect-sdk:x64-uwp=fail +networkdirect-sdk:x86-windows=fail +nmslib:arm64-windows=fail +nmslib:arm-uwp=fail +nmslib:x64-uwp=fail +nng:arm-uwp=fail +nng:x64-uwp=fail +nrf-ble-driver:arm-uwp=fail +nrf-ble-driver:x64-uwp=fail +nrf-ble-driver:x64-linux=ignore +numactl:arm64-windows=fail +numactl:arm-uwp=fail +numactl:x64-osx=fail +numactl:x64-uwp=fail +numactl:x64-windows=fail +numactl:x64-windows-static=fail +numactl:x86-windows=fail +nvtt:arm64-windows=fail +nvtt:arm-uwp=fail +nvtt:x64-uwp=fail +ocilib:arm64-windows=fail +ocilib:arm-uwp=fail +ocilib:x64-uwp=fail +ocilib:x64-windows-static=fail +octomap:arm-uwp=fail +octomap:x64-uwp=fail +ode:arm64-windows=fail +ode:arm-uwp=fail +ode:x64-uwp=fail +ode:x64-linux=ignore +offscale-libetcd-cpp:arm64-windows=fail +offscale-libetcd-cpp:arm-uwp=fail +offscale-libetcd-cpp:x64-uwp=fail +ogdf:arm64-windows = skip +ogdf:arm-uwp = skip +ogdf:x64-osx=fail +ogdf:x64-uwp = skip +ogdf:x64-windows = skip +ogdf:x64-windows-static = skip +ogdf:x86-windows = skip +ogre:x64-osx=fail +# Conflicts with ogre +ogre-next:arm64-windows = skip +ogre-next:arm-uwp = skip +ogre-next:x64-osx = skip +ogre-next:x64-linux = skip +ogre-next:x64-uwp = skip +ogre-next:x64-windows = skip +ogre-next:x64-windows-static = skip +ogre-next:x86-windows = skip +ois:arm64-windows=fail +ois:arm-uwp=fail +ois:x64-uwp=fail +open62541:arm-uwp=fail +open62541:x64-uwp=fail +openal-soft:arm-uwp=fail +openal-soft:x64-uwp=fail +openblas:arm64-windows=fail +openblas:arm-uwp=fail +# opencc/deps/rapidjson-1.1.0/rapidjson.h: Unknown machine endianess detected +opencc:arm64-windows=fail +# opencc/deps/marisa-0.2.5/lib/marisa/grimoire/io/mapper.cc currently doesn't support UWP. +opencc:arm-uwp=fail +opencc:x64-uwp=fail +opencensus-cpp:arm64-windows=fail +opencensus-cpp:x64-windows=fail +opencensus-cpp:x64-windows-static=fail +opencensus-cpp:x86-windows=fail +opencensus-cpp:x64-uwp=fail +opencl:arm-uwp=fail +opencl:x64-uwp=fail +opencolorio:x64-linux=ignore +opencsg:x64-uwp=fail +opencv2:arm64-windows = skip +opencv2:arm-uwp = skip +opencv2:x64-linux = skip +opencv2:x64-osx = skip +opencv2:x64-uwp = skip +opencv2:x64-windows = skip +opencv2:x64-windows-static = skip +opencv2:x86-windows = skip +opencv3:arm64-windows = skip +opencv3:arm-uwp = skip +opencv3:x64-linux = skip +opencv3:x64-osx = skip +opencv3:x64-uwp = skip +opencv3:x64-windows = skip +opencv3:x64-windows-static = skip +opencv3:x86-windows = skip +opendnp3:x64-uwp=fail +opendnp3:arm-uwp=fail +openexr:arm64-windows=fail +openexr:arm-uwp=fail +openexr:x64-uwp=fail +opengl:arm64-windows=fail +opengl:arm-uwp=fail +openimageio:x64-linux=ignore +openmama:x64-windows=ignore +openmama:x86-windows=ignore +openmama:x64-linux=fail +openmama:x64-osx=fail +openmesh:arm64-windows=fail +openmesh:arm-uwp=fail +openmesh:x64-uwp=fail +openmpi:arm64-windows=fail +openmpi:arm-uwp=fail +openmpi:x64-uwp=fail +openmpi:x64-windows=fail +openmpi:x64-windows-static=fail +openmpi:x86-windows=fail +openmvg:x64-linux=ignore +openmvs:x64-linux=fail +openni2:x64-uwp=fail +openni2:x64-windows-static=fail +openscap:x64-linux=fail +openssl-unix:arm64-windows=fail +openssl-unix:arm-uwp=fail +openssl-unix:x64-uwp=fail +openssl-unix:x64-windows=fail +openssl-unix:x64-windows-static=fail +openssl-unix:x86-windows=fail +openssl-uwp:arm64-windows=fail +openssl-uwp:x64-linux=fail +openssl-uwp:x64-osx=fail +openssl-uwp:x64-windows=fail +openssl-uwp:x64-windows-static=fail +openssl-uwp:x86-windows=fail +openssl-windows:arm-uwp=fail +openssl-windows:x64-linux=fail +openssl-windows:x64-osx=fail +openssl-windows:x64-uwp=fail +opentracing:arm-uwp=fail +opentracing:x64-uwp=fail +openvdb:x64-linux=ignore +openvdb:x64-osx=fail +#openvdb:x64-windows-static=fail # https://github.com/microsoft/vcpkg/pull/10816#issuecomment-613784827 +openvpn3:x64-osx=fail +openvr:arm64-windows=fail +openvr:arm-uwp=fail +openvr:x64-osx=fail +openvr:x64-uwp=fail +openxr-loader:arm64-windows=fail +openxr-loader:arm-uwp=fail +openxr-loader:x64-osx=fail +openxr-loader:x64-uwp=fail +optional-bare:arm64-windows = skip +optional-bare:arm-uwp = skip +optional-bare:x64-linux = skip +optional-bare:x64-osx = skip +optional-bare:x64-uwp = skip +optional-bare:x64-windows = skip +optional-bare:x64-windows-static = skip +optional-bare:x86-windows = skip +opusfile:arm-uwp=fail +opusfile:x64-uwp=fail +orc:x64-linux=ignore +orocos-kdl:arm-uwp=fail +orocos-kdl:x64-uwp=fail +osg:x86-windows=skip +osg:x64-windows=skip +osgearth:x64-osx=fail +osgearth:x64-linux=fail +osgearth:x64-windows-static=fail +osg-qt:x64-windows-static=fail +otl:x64-windows=ignore +otl:x64-windows-static=ignore +otl:x64-uwp=ignore +otl:x64-linux=ignore +otl:x86-windows=ignore +paho-mqtt:arm-uwp=fail +paho-mqtt:x64-uwp=fail +pangolin:x64-linux=fail +pangolin:x64-osx=fail +pangolin:x64-uwp=fail +pangolin:x64-windows-static=fail +pangomm:x64-osx=fail +pangomm:x64-windows=ignore +pangomm:x86-windows=ignore +pangomm:arm64-windows=fail +parmetis:x64-linux=fail +parmetis:x64-osx=fail +pcre2:arm-uwp=fail +pdal:x64-linux=fail +pdal:x64-osx=fail +pdal-c:x64-windows-static=fail +pdcurses:arm-uwp=fail +pdcurses:x64-linux=fail +pdcurses:x64-osx=fail +pdcurses:x64-uwp=fail +pdcurses:x64-windows-static=fail +pfring:arm64-windows=fail +pfring:arm-uwp=fail +pfring:x64-uwp=fail +pfring:x64-windows=fail +pfring:x64-windows-static=fail +pfring:x86-windows=fail +pfring:x64-osx=fail +# pfring on Linux currently fails because its build scripts enable warnings as +# errors, and warnings trigger with the Linux kernel headers in the Azure images. +pfring:x64-linux=fail +physfs:arm64-windows=fail +physx:arm64-windows=fail +physx:x64-linux=fail +physx:x64-osx=fail +piex:x64-osx=fail +pistache:arm64-windows=fail +pistache:arm-uwp=fail +pistache:x64-osx=fail +pistache:x64-uwp=fail +pistache:x64-windows=fail +pistache:x64-windows-static=fail +pistache:x86-windows=fail +pixel:x64-uwp=fail +pixel:x64-windows=fail +pixel:x64-windows-static=fail +pixel:x86-windows=fail +pixel:x64-linux=ignore +platform-folders:arm-uwp=fail +platform-folders:x64-uwp=fail +plib:arm-uwp=fail +plib:x64-osx=fail +plib:x64-uwp=fail +plibsys:arm-uwp=fail +plibsys:x64-uwp=fail +plplot:arm64-windows=fail +plplot:arm-uwp=fail +plplot:x64-uwp=fail +pmdk:arm-uwp=fail +pmdk:arm64-windows=fail +pmdk:x64-linux=fail +pmdk:x64-osx=fail +pmdk:x64-uwp=fail +pmdk:x64-windows-static=fail +pmdk:x86-windows=fail +pngwriter:arm-uwp=fail +pngwriter:x64-uwp=fail +pngwriter:x64-linux=ignore +polyhook2:arm64-windows=fail +polyhook2:arm-uwp=fail +polyhook2:x64-linux=fail +polyhook2:x64-uwp=fail +polyhook2:x64-osx=fail +portable-snippets:arm-uwp=fail +# Portaudio was broken by Ninja 1.9.0 https://github.com/ninja-build/ninja/pull/1406 +portaudio:arm-uwp=fail +portaudio:arm64-windows=fail +portaudio:x64-uwp=fail +portaudio:x64-windows-static=fail +portaudio:x64-windows=fail +portaudio:x86-windows=fail +portmidi:arm-uwp=fail +portmidi:x64-linux=fail +portmidi:x64-osx=fail +portmidi:x64-uwp=fail +ppconsul:x64-linux=ignore +pqp:arm-uwp=fail +pqp:x64-uwp=fail +proj4:arm64-windows=fail +proj4:arm-uwp=fail +proj4:x64-uwp=fail +protobuf:x64-uwp=ignore +protobuf:arm64-windows=ignore +protobuf:arm-uwp=ignore +protobuf-c:x86-windows=fail +protobuf-c:x64-windows=fail +protobuf-c:x64-windows-static=fail +protobuf-c:x64-uwp=fail +protobuf-c:arm64-windows=fail +protobuf-c:arm-uwp=fail +# proxygen fails with "Target 'Windows' not supported by proxygen!" +proxygen:x64-windows=fail +proxygen:x64-windows-static=fail +ptex:arm-uwp=fail +ptex:x64-linux=fail +ptex:x64-osx=fail +ptex:x64-uwp=fail +pthreads:arm64-windows=fail +pthreads:arm-uwp=fail +pthreads:x64-uwp=fail +python2:arm64-windows=fail +python2:arm-uwp=fail +python2:x64-linux=fail +python2:x64-osx=fail +python2:x64-uwp=fail +python3:arm64-windows=fail +python3:arm-uwp=fail +python3:x64-uwp=fail +qca:x64-linux=fail +qca:x64-osx=fail +qca:x64-windows-static=fail +qhull:arm-uwp=ignore +qhull:x64-windows-static=ignore +qhull:x64-uwp=ignore +qpid-proton:arm-uwp=fail +qpid-proton:x64-uwp=fail +qpid-proton:x64-windows-static=fail +qt5-activeqt:x64-linux=fail +qt5-activeqt:x64-osx=fail +qt5-macextras:x64-linux=fail +qt5-macextras:x64-windows=fail +qt5-macextras:x64-windows-static=fail +qt5-macextras:x86-windows=fail +# Missing system libraries +qt5-wayland:x64-osx=fail +# Missing libraries +qt5-wayland:x86-windows=fail +qt5-wayland:x64-windows=fail +qt5-wayland:x64-windows-static=fail +qt5-winextras:x64-linux=fail +qt5-winextras:x64-osx=fail +# Too big for CI. +qt5-webengine:x64-windows=skip +qt5-webengine:x86-windows=skip +# Missing prerequisites for CI success +qt5-webengine:x64-linux=fail +qt5-webengine:x64-osx=fail +# Static builds of qt5-webengine are not supported by the port itself +qt5-webengine:x64-windows-static=skip +# Missing system libraries +qt5-x11extras:x64-osx=fail +# Missing libraries +qt5-x11extras:x86-windows=fail +qt5-x11extras:x64-windows=fail +qt5-x11extras:x64-windows-static=fail +# Broken by VS2019 16.6 and throws a ton of dialogs attempting to build +# fixed by https://github.com/microsoft/vcpkg/pull/11596 +qt5-translations:x64-windows-static=skip +quickfast:x64-linux=ignore +quickfix:x64-linux=ignore +quickfix:x64-windows=ignore +quickfix:x64-windows-static=ignore +quickfix:x86-windows=ignore +quickfix:x64-uwp=fail +quickfix:arm-uwp=fail +quill:arm64-windows=fail +quill:arm-uwp=fail +quill:x64-uwp=fail +quirc:arm64-windows = skip +quirc:arm-uwp = skip +quirc:x64-linux = skip +quirc:x64-osx = skip +quirc:x64-uwp = skip +quirc:x64-windows = skip +quirc:x64-windows-static = skip +quirc:x86-windows = skip +qwt:x64-osx=ignore +rabit:x64-osx=fail +rabit:x64-linux=ignore +ragel:arm-uwp=fail +ragel:x64-uwp=fail +range-v3-vs2015:arm64-windows = skip +range-v3-vs2015:arm-uwp = skip +range-v3-vs2015:x64-linux = skip +range-v3-vs2015:x64-osx = skip +range-v3-vs2015:x64-uwp = skip +range-v3-vs2015:x64-windows = skip +range-v3-vs2015:x64-windows-static = skip +range-v3-vs2015:x86-windows = skip +rapidstring:arm64-windows=fail +rapidstring:arm-uwp=fail +rapidstring:x64-linux=fail +rapidstring:x64-uwp=fail +rapidstring:x64-windows=fail +rapidstring:x64-windows-static=fail +rapidstring:x86-windows=fail +raylib:arm64-windows=fail +raylib:arm-uwp=fail +raylib:x64-uwp=fail +readline:arm-uwp=fail +readline:x64-uwp=fail +readline-win32:arm-uwp=fail +readline-win32:x64-linux=fail +readline-win32:x64-osx=fail +readline-win32:x64-uwp=fail +readosm:x64-linux=fail +readosm:x64-osx=fail +realsense2:arm64-windows=fail +realsense2:arm-uwp=fail +realsense2:x64-linux=fail +realsense2:x64-uwp=fail +redis-plus-plus:x86-windows=fail +redis-plus-plus:x64-windows=fail +redis-plus-plus:x64-windows-static=fail +redis-plus-plus:arm64-windows=fail +replxx:arm-uwp=fail +replxx:x64-uwp=fail +reproc:arm-uwp=fail +reproc:x64-uwp=fail +restbed:arm-uwp=fail +restbed:x64-uwp=fail +rhash:arm64-windows=fail +rhash:arm-uwp=fail +rhash:x64-uwp=fail +rocksdb:arm-uwp=fail +rocksdb:x64-uwp=fail +rocksdb:x64-linux=ignore +rpclib:arm64-windows=fail +rpclib:arm-uwp=fail +rpclib:x64-uwp=fail +rpclib:x64-windows=ignore +rpclib:x86-windows=ignore +rpclib:x64-windows-static=ignore +rtlsdr:x64-uwp=fail +rtlsdr:arm64-windows=fail +rtlsdr:arm-uwp=fail +rtlsdr:x64-linux=fail +rtlsdr:x64-osx=fail +rttr:arm-uwp=fail +rttr:x64-uwp=fail +rxspencer:x64-uwp=fail +rxspencer:arm-uwp=fail +ryml:arm-uwp=fail +ryml:arm64-windows=fail +ryml:x64-osx=fail +ryu:arm-uwp=fail +ryu:x64-uwp=fail +ryu:x64-windows-static=fail +ryu:x86-windows=fail +ryu::arm64-windows=fail +scintilla:arm-uwp=fail +scintilla:x64-linux=fail +scintilla:x64-osx=fail +scintilla:x64-uwp=fail +scintilla:x64-windows-static=fail +sciter:arm64-windows=fail +sciter:arm-uwp=fail +sciter:x64-uwp=fail +sciter:x64-windows-static=fail +scnlib:arm-uwp=fail +scnlib:x64-uwp=fail +scylla-wrapper:arm-uwp=fail +scylla-wrapper:x64-linux=fail +scylla-wrapper:x64-osx=fail +scylla-wrapper:x64-uwp=fail +scylla-wrapper:x64-windows-static=fail +sdformat6:arm64-windows=fail +sdformat6:arm-uwp=fail +sdformat6:x64-uwp=fail +sdformat6:x64-linux=ignore +sdformat9:x64-linux=fail +sdformat9:arm-uwp=fail +sdformat9:x64-uwp=fail +sdl1:arm-uwp=fail +sdl1:x64-uwp=fail +sdl1:x64-osx=fail +sdl2-image:arm-uwp=fail +sdl2-image:x64-uwp=fail +sdl2-mixer:arm-uwp=fail +sdl2-mixer:x64-uwp=fail +sdl2-net:arm-uwp=fail +sdl2-net:x64-uwp=fail +# https://github.com/microsoft/vcpkg/issues/10918 +seal:arm-uwp=fail +seal:x64-uwp=fail +secp256k1:x64-linux=fail +secp256k1:x64-osx=fail +selene:x64-linux=ignore +sentencepiece:arm64-windows=fail +sentencepiece:arm-uwp=fail +sentencepiece:x64-uwp=fail +sentencepiece:x64-windows=fail +sentencepiece:x86-windows=fail +septag-sx:arm64-windows=fail +septag-sx:arm-uwp=fail +septag-sx:x64-uwp=fail +sfgui:x64-linux=ignore +sfml:arm64-windows=fail +shapelib:arm-uwp=fail +shapelib:x64-uwp=fail +shiva:x64-windows-static=fail +shiva-sfml:x64-linux=fail +shiva-sfml:x64-osx=fail +shiva-sfml:x86-windows=fail +shiva-sfml:x64-windows=fail +shogun:arm64-windows = skip +shogun:arm-uwp = skip +shogun:x64-osx = skip +shogun:x64-uwp = skip +shogun:x64-windows = skip +shogun:x64-windows-static = skip +shogun:x86-windows = skip +signalrclient:x64-uwp=fail +signalrclient:arm-uwp=fail +simdjson:arm-uwp=fail +simdjson:x86-windows=fail +skia:arm64-windows=fail +skia:arm-uwp=fail +skia:x64-linux=fail +skia:x64-uwp=fail +skia:x86-windows=fail +slikenet:arm-uwp=fail +slikenet:x64-uwp=fail +smpeg2:arm-uwp=fail +smpeg2:x64-linux=fail +smpeg2:x64-uwp=fail +soci:arm-uwp=fail +soci:x64-uwp=fail +sockpp:arm-uwp=fail +sockpp:x64-uwp=fail +soem:x64-uwp=fail +soem:arm-uwp=fail +soil:arm-uwp=fail +soil:x64-uwp=fail +soil2:arm-uwp=fail +soil2:x64-uwp=fail +sophus:x64-linux=fail +soqt:arm64-windows=fail +soqt:arm-uwp=fail +soqt:x64-uwp=fail +soundtouch:arm-uwp=fail +soundtouch:x64-linux=ignore +soundtouch:x64-uwp=fail +soundtouch:x64-windows-static=fail +spaceland:arm64-windows=fail +spaceland:arm-uwp=fail +spaceland:x64-uwp=fail +spaceland:x64-linux=ignore +spdk:x64-linux=fail +spdk-dpdk:arm64-windows=fail +spdk-dpdk:arm-uwp=fail +spdk-dpdk:x64-osx=fail +spdk-dpdk:x64-uwp=fail +spdk-dpdk:x64-windows=fail +spdk-dpdk:x64-windows-static=fail +spdk-dpdk:x86-windows=fail +spdk-ipsec:arm64-windows=fail +spdk-ipsec:arm-uwp=fail +spdk-ipsec:x64-osx=fail +spdk-ipsec:x64-uwp=fail +spdk-ipsec:x64-windows=fail +spdk-ipsec:x64-windows-static=fail +spdk-ipsec:x86-windows=fail +spdk-isal:arm64-windows=fail +spdk-isal:arm-uwp=fail +spdk-isal:x64-osx=fail +spdk-isal:x64-uwp=fail +spdk-isal:x64-windows=fail +spdk-isal:x64-windows-static=fail +spdk-isal:x86-windows=fail +speex:x64-linux=fail +speex:x64-osx=fail +speexdsp:x64-linux=fail +speexdsp:x64-osx=fail +spirv-tools:arm-uwp=fail +spirv-tools:x64-uwp=fail +stormlib:arm-uwp=fail +stormlib:x64-uwp=fail +stxxl:arm-uwp=fail +stxxl:x64-uwp=fail +# Sundials was broken by Ninja 1.9.0 https://github.com/ninja-build/ninja/pull/1406 +sundials:arm64-windows=fail +sundials:x64-windows=fail +sundials:x86-windows=fail +# Conflicts between ports: +#The following files are already installed in C:/agent/_work/1/s/installed/x64-windows-static +# and are in conflict with superlu:x64-windows-static +# +#Installed by hypre:x64-windows-static +# include/slu_Cnames.h +# include/slu_cdefs.h +# include/slu_dcomplex.h +# include/slu_ddefs.h +# include/slu_scomplex.h +# include/slu_sdefs.h +# include/slu_util.h +# include/slu_zdefs.h +# include/supermatrix.h +superlu:arm-uwp=skip +superlu:arm-windows=skip +superlu:arm64-windows=skip +superlu:x64-uwp=skip +superlu:x64-windows-static=skip +superlu:x64-windows=skip +systemc:arm64-windows=fail +systemc:arm-uwp=fail +systemc:x64-uwp=fail +taglib:x64-linux=ignore +tbb:arm64-windows=fail +tbb:arm-uwp=fail +tbb:x64-uwp=fail +tcl:arm-uwp=ignore +tcl:arm64-windows=ignore +tcl:x64-uwp=ignore +tcl:x64-linux=ignore +tcl:x64-osx=ignore +teemo:x64-uwp=fail +teemo:arm-uwp=fail +teemo:arm64-windows=fail +teemo:x64-osx=fail +telnetpp:arm-uwp=fail +telnetpp:x64-uwp=fail +tensorflow-cc:arm64-windows=fail +tensorflow-cc:x64-linux=skip +tensorflow-cc:x64-osx=skip +tensorflow-cc:x64-windows=fail +tensorflow-cc:x64-windows-static=fail +tensorflow-cc:x86-windows=fail +tesseract:x64-windows=ignore +tesseract:x64-windows-static=ignore +tesseract:x86-windows=ignore +tesseract:arm64-windows=fail +tfhe:x86-windows=fail +tfhe:x64-windows=fail +tfhe:x64-windows-static=fail +tfhe:x64-uwp=fail +tfhe:arm64-windows=fail +tfhe:arm-uwp=fail +theia:arm64-windows = skip +theia:arm-uwp = skip +theia:x64-uwp = skip +theia:x64-windows = skip +theia:x64-windows-static = skip +theia:x86-windows = skip +thor:x64-linux=fail +thor:x64-osx=fail +tidy-html5:arm-uwp=fail +tidy-html5:x64-uwp=fail +tinkerforge:arm-uwp=fail +tinkerforge:x64-uwp=fail +tinyexif:arm-uwp=fail +tinyexif:x64-uwp=fail +tinyfiledialogs:arm-uwp=fail +tinyfiledialogs:x64-uwp=fail +tinynpy:x64-linux=ignore +tiny-process-library:arm-uwp=fail +tiny-process-library:x64-uwp=fail +tinyutf8:arm64-windows=fail +tinyutf8:arm-uwp=fail +tinyutf8:x64-uwp=fail + +#Flaky on windows only due to error PRI210: 0x80070020 - File move failed +tmx:arm64-windows = skip +tmx:arm-uwp = skip +tmx:x64-uwp = skip +tmx:x64-windows = skip +tmx:x64-windows-static = skip +tmx:x86-windows = skip +tmxlite:arm-uwp=fail +tmxlite:x64-uwp=fail +tmxparser:arm64-windows=fail +tmxparser:arm-uwp=fail +tmxparser:x64-uwp=fail +tmxparser:x64-windows=fail +tmxparser:x64-windows-static=fail +tmxparser:x86-windows=fail +torch-th:arm64-windows=fail +torch-th:arm-uwp=fail +torch-th:x64-uwp=fail +torch-th:x64-windows-static=fail +tre:x64-osx=fail +treehopper:x64-windows-static=fail +turbobase64:arm64-windows=fail +turbobase64:arm-uwp=fail +turbobase64:x64-uwp=fail +turbobase64:x64-windows=fail +turbobase64:x64-windows-static=fail +turbobase64:x86-windows=fail +unicorn:arm64-windows=fail +unicorn:arm-uwp=fail +unicorn:x64-linux=fail +unicorn:x64-osx=fail +unicorn:x64-uwp=fail +unicorn-lib:x64-uwp=fail +unittest-cpp:arm64-windows=fail +unittest-cpp:arm-uwp=fail +unittest-cpp:x64-uwp=fail +unixodbc:arm64-windows=fail +unixodbc:arm-uwp=fail +unixodbc:x64-uwp=fail +unixodbc:x64-windows=fail +unixodbc:x64-windows-static=fail +unixodbc:x86-windows=fail +unrar:arm64-windows=fail +unrar:arm-uwp=fail +unrar:x64-linux=fail +unrar:x64-osx=fail +unrar:x64-uwp=fail +unrar:x64-windows-static=fail +urdfdom:x64-windows-static=fail +usd:x86-windows=fail +usrsctp:arm-uwp=fail +usrsctp:x64-uwp=fail +uthenticode:arm-uwp=fail +uthenticode:x64-uwp=fail +uvatlas:arm64-windows=fail +uvatlas:arm-uwp=fail +uvatlas:x64-linux=fail +uvatlas:x64-osx=fail +uvatlas:x64-windows-static=fail +vectorclass:arm64-windows=fail +vectorclass:arm-uwp=fail +vlpp:x64-osx=fail +vulkan:arm64-windows=fail +vulkan:arm-uwp=fail +vulkan:x64-linux=fail +vulkan:x64-osx=fail +vulkan:x64-uwp=fail +vulkan:x64-windows=fail +vulkan:x64-windows-static=fail +vulkan:x86-windows=fail +# Conflicts with latest openjpeg port (vxl ships with an old version of openjpeg) +# conflicts with qt5-location +vxl:arm64-windows = skip +vxl:arm-uwp = skip +vxl:x64-linux = skip +vxl:x64-osx = skip +vxl:x64-uwp = skip +vxl:x64-windows = skip +vxl:x64-windows-static = skip +vxl:x86-windows = skip +wampcc:arm64-windows=fail +wampcc:x64-linux=ignore +wangle:x64-linux=ignore +wavpack:arm64-windows=fail +wavpack:x64-linux=fail +wavpack:x64-osx=fail +wepoll:arm-uwp=ignore +wepoll:x64-uwp=ignore +wepoll:x64-linux=ignore +wepoll:x64-osx=ignore +wildmidi:x64-osx=fail +wincrypt:x64-linux=fail +wincrypt:x64-osx=fail +winpcap:arm64-windows = skip +winpcap:arm-uwp = skip +winpcap:x64-linux=fail +winpcap:x64-osx=fail +winpcap:x64-uwp = skip +winpcap:x64-windows = skip +winpcap:x64-windows-static = skip +winpcap:x86-windows = skip +winreg:x64-linux=fail +winreg:x64-osx=fail +winsock2:x64-linux=fail +winsock2:x64-osx=fail +wintoast:arm-uwp=fail +wintoast:x64-linux=fail +wintoast:x64-osx=fail +wintoast:x64-uwp=fail +woff2:x64-linux=fail +woff2:x64-osx=fail +woff2:x64-windows-static=fail +wpilib:arm64-windows=fail +wpilib:x64-osx=fail +wxchartdir:x64-osx=fail +wxwidgets:x64-linux=fail +x264:arm64-windows=fail +x264:arm-uwp=fail +x264:x64-uwp=ignore +x264:x64-osx=fail +x264:x86-windows=ignore +x264:x64-windows=ignore +x264:x64-windows-static=ignore +x265:arm64-windows=fail +x265:arm-uwp=fail +x265:x64-uwp=fail +xalan-c:x64-windows-static=fail +xalan-c:arm64-windows=fail +xbyak:arm64-windows=fail +xbyak:arm-uwp=fail +xbyak:x64-uwp=fail +xerces-c:arm-uwp=fail +xerces-c:x64-uwp=fail +xeus:x64-linux=ignore +xmlsec:arm-uwp=fail +xmlsec:x64-uwp=fail +# The xmsh upstream repository is gone, if we find no replacement before +# 2021-01-01 we will remove the port outright. +xmsh:arm-uwp=skip +xmsh:arm64-windows=skip +xmsh:x64-linux=skip +xmsh:x64-osx=skip +xmsh:x64-uwp=skip +xmsh:x64-windows-static=skip +xmsh:x64-windows=skip +xmsh:x86-windows=skip +xtensor-io:x64-uwp=ignore +x-plane:arm64-windows=fail +x-plane:arm-uwp=fail +x-plane:x64-linux=fail +x-plane:x86-windows=fail +yajl:arm-uwp=fail +yajl:x64-uwp=fail +yara:arm-uwp=fail +yara:x64-uwp=fail +yasm:arm64-windows=fail +yasm:arm-uwp=fail +yasm:x64-linux=fail +yasm:x64-osx=fail +yasm:x64-uwp=fail +yato:arm64-windows=fail +yato:arm-uwp=fail +yato:x64-uwp=fail +z3:arm64-windows=fail +z3:arm-uwp=fail +z3:x64-uwp=fail +zeromq:arm64-windows=fail +zeromq:arm-uwp=fail +zeromq:x64-uwp=fail +zkpp:x86-windows=fail +zkpp:x64-windows=fail +zkpp:x64-windows-static=fail +zkpp:arm64-windows=fail +zkpp:x64-uwp=fail +zkpp:arm-uwp=fail +c4core:arm-uwp=fail +c4core:arm64-windows=fail +c4core:x64-osx=fail + +# Official downloading server of CTP library is only guaranteed to be available during trading hours of China futures market +# Skip CI to avoid random failures +ctp:arm64-windows=skip +ctp:arm-uwp=skip +ctp:x64-linux=skip +ctp:x64-osx=skip +ctp:x64-uwp=skip +ctp:x64-windows=skip +ctp:x64-windows-static=skip +ctp:x86-windows=skip +protozero:arm-uwp=fail +protozero:x64-uwp=fail diff --git a/scripts/cmake/vcpkg_build_msbuild.cmake b/scripts/cmake/vcpkg_build_msbuild.cmake index 67ff3d3ae6..bc118b4c0d 100644 --- a/scripts/cmake/vcpkg_build_msbuild.cmake +++ b/scripts/cmake/vcpkg_build_msbuild.cmake @@ -96,6 +96,7 @@ function(vcpkg_build_msbuild) /p:VCPkgLocalAppDataDisabled=true /p:UseIntelMKL=No /p:WindowsTargetPlatformVersion=${_csc_TARGET_PLATFORM_VERSION} + /p:VcpkgManifestInstall=false /m ) diff --git a/scripts/cmake/vcpkg_configure_cmake.cmake b/scripts/cmake/vcpkg_configure_cmake.cmake index 4debcb718e..9f75c5e071 100644 --- a/scripts/cmake/vcpkg_configure_cmake.cmake +++ b/scripts/cmake/vcpkg_configure_cmake.cmake @@ -238,6 +238,7 @@ function(vcpkg_configure_cmake) "-DCMAKE_INSTALL_BINDIR:STRING=bin" "-D_VCPKG_ROOT_DIR=${VCPKG_ROOT_DIR}" "-D_VCPKG_INSTALLED_DIR=${_VCPKG_INSTALLED_DIR}" + "-DVCPKG_MANIFEST_INSTALL=OFF" ) if(DEFINED ARCH) diff --git a/scripts/cmake/vcpkg_fixup_pkgconfig.cmake b/scripts/cmake/vcpkg_fixup_pkgconfig.cmake index a5495a423b..6acb51360b 100644 --- a/scripts/cmake/vcpkg_fixup_pkgconfig.cmake +++ b/scripts/cmake/vcpkg_fixup_pkgconfig.cmake @@ -13,7 +13,7 @@ ## ## ## Parameters ## ### RELEASE_FILES -## Specifies a list of files to apply the fixes for release paths. +## Specifies a list of files to apply the fixes for release paths. ## Defaults to every *.pc file in the folder ${CURRENT_PACKAGES_DIR} without ${CURRENT_PACKAGES_DIR}/debug/ ## ## ### DEBUG_FILES @@ -22,11 +22,11 @@ ## ## ### SYSTEM_PACKAGES ## If the *.pc file contains system packages outside vcpkg these need to be listed here. -## Since vcpkg checks the existence of all required packages within vcpkg. +## Since vcpkg checks the existence of all required packages within vcpkg. ## ## ### SYSTEM_LIBRARIES ## If the *.pc file contains system libraries outside vcpkg these need to be listed here. -## VCPKG checks every -l flag for the existence of the required library within vcpkg. +## VCPKG checks every -l flag for the existence of the required library within vcpkg. ## ## ### IGNORE_FLAGS ## If the *.pc file contains flags in the lib field which are not libraries. These can be listed here @@ -36,7 +36,7 @@ ## ## ## Examples ## -## Just call vcpkg_fixup_pkgconfig() after any install step which installs *.pc files. +## Just call vcpkg_fixup_pkgconfig() after any install step which installs *.pc files. function(vcpkg_fixup_pkgconfig_check_libraries _config _contents_var _system_libs _system_packages _ignore_flags) set(CMAKE_FIND_LIBRARY_SUFFIXES_BACKUP ${CMAKE_FIND_LIBRARY_SUFFIXES}) list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll.a;.a") @@ -64,7 +64,7 @@ function(vcpkg_fixup_pkgconfig_check_libraries _config _contents_var _system_lib string(REPLACE "-l" "" _system_lib "${_system_lib}") list(APPEND _system_lib_normalized "${_system_lib}") endforeach() - + ## Extra libraries: string(REGEX MATCH "Libs:[^\n#]+" _libs "${_contents}") #message(STATUS "LIB LINE: ${_libs}") @@ -133,9 +133,9 @@ function(vcpkg_fixup_pkgconfig_check_libraries _config _contents_var _system_lib endif() else() #handle special cases - if(_lib STREQUAL "-pthread" OR _lib STREQUAL "-pthreads") + if(_lib STREQUAL "-pthread" OR _lib STREQUAL "-pthreads") # Replace with VCPKG version? - #VCPKG should probably rename one of the pthread versions to avoid linking against system pthread? + #VCPKG should probably rename one of the pthread versions to avoid linking against system pthread? # set(PTHREAD_SUFFIX ) # if("${_config}" STREQUAL "DEBUG") # file(GLOB PTHREAD_LIB "${CURRENT_INSTALLED_DIR}/debug/lib/${VCPKG_TARGET_STATIC_LIBRARY_PREFIX}pthread*C3d.*") @@ -165,18 +165,18 @@ function(vcpkg_fixup_pkgconfig_check_libraries _config _contents_var _system_lib string(REGEX REPLACE "[\t ]*,[\t ]*" ";" _pkg_private_list_tmp "${_pkg_private_list_tmp}") string(REGEX REPLACE "[\t ]*(>|=)+[\t ]*([0-9]+|\\.)+" " " _pkg_private_list_tmp "${_pkg_private_list_tmp}") string(REGEX REPLACE "[\t ]+" ";" _pkg_private_list_tmp "${_pkg_private_list_tmp}") - + debug_message("Required packages: ${_pkg_list_tmp}") debug_message("Required private packages: ${_pkg_private_list_tmp}") - + #message(STATUS "System packages: ${_system_packages}") foreach(_package ${_pkg_list_tmp} ${_pkg_private_list_tmp}) debug_message("Searching for package: ${_package}") set(PKG_CHECK ON) if(NOT "${_system_packages}" STREQUAL "") - #message(STATUS "Checking ${_package} for SYSTEM PACKAGE: ${_system_packages}") + #message(STATUS "Checking ${_package} for SYSTEM PACKAGE: ${_system_packages}") if("${_system_packages}" MATCHES "${_package}" ) - debug_message("Package ${_package} is SYSTEM PACKAGE!") + debug_message("Package ${_package} is SYSTEM PACKAGE!") set(PKG_CHECK OFF) endif() endif() @@ -193,7 +193,7 @@ endfunction() function(vcpkg_fixup_pkgconfig) cmake_parse_arguments(_vfpkg "" "" "RELEASE_FILES;DEBUG_FILES;SYSTEM_LIBRARIES;SYSTEM_PACKAGES;IGNORE_FLAGS" ${ARGN}) - + if(VCPKG_SYSTEM_LIBRARIES) list(APPEND _vfpkg_SYSTEM_LIBRARIES ${VCPKG_SYSTEM_LIBRARIES}) endif() @@ -206,16 +206,16 @@ function(vcpkg_fixup_pkgconfig) file(GLOB_RECURSE _vfpkg_RELEASE_FILES "${CURRENT_PACKAGES_DIR}/**/*.pc") list(FILTER _vfpkg_RELEASE_FILES EXCLUDE REGEX "${CURRENT_PACKAGES_DIR}/debug/") endif() - + if(NOT _vfpkg_DEBUG_FILES) file(GLOB_RECURSE _vfpkg_DEBUG_FILES "${CURRENT_PACKAGES_DIR}/debug/**/*.pc") list(FILTER _vfpkg_DEBUG_FILES INCLUDE REGEX "${CURRENT_PACKAGES_DIR}/debug/") endif() - - #Absolute Unix like paths + + #Absolute Unix like paths string(REGEX REPLACE "([a-zA-Z]):/" "/\\1/" _VCPKG_PACKAGES_DIR "${CURRENT_PACKAGES_DIR}") string(REGEX REPLACE "([a-zA-Z]):/" "/\\1/" _VCPKG_INSTALLED_DIR "${CURRENT_INSTALLED_DIR}") - + message(STATUS "Fixing pkgconfig - release") debug_message("Files: ${_vfpkg_RELEASE_FILES}") foreach(_file ${_vfpkg_RELEASE_FILES}) @@ -235,7 +235,7 @@ function(vcpkg_fixup_pkgconfig) file(WRITE "${_file}" "${_contents}") unset(PKG_LIB_SEARCH_PATH) endforeach() - + message(STATUS "Fixing pkgconfig - debug") debug_message("Files: ${_vfpkg_DEBUG_FILES}") foreach(_file ${_vfpkg_DEBUG_FILES}) @@ -257,17 +257,17 @@ function(vcpkg_fixup_pkgconfig) string(REPLACE "debug/lib" "lib" _contents "${_contents}") # the prefix will contain the debug keyword string(REGEX REPLACE "^prefix=(\\\\)?\\\${prefix}(/debug)?" "prefix=\${pcfiledir}/${RELATIVE_PC_PATH}" _contents "${_contents}") # make pc file relocatable - string(REPLACE "\${prefix}/debug" "\${prefix}" _contents "${_contents}") # replace remaining debug paths if they exist. + string(REPLACE "\${prefix}/debug" "\${prefix}" _contents "${_contents}") # replace remaining debug paths if they exist. vcpkg_fixup_pkgconfig_check_libraries("DEBUG" _contents "${_vfpkg_SYSTEM_LIBRARIES}" "${_vfpkg_SYSTEM_PACKAGES}" "${_vfpkg_IGNORE_FLAGS}") file(WRITE "${_file}" "${_contents}") unset(PKG_LIB_SEARCH_PATH) endforeach() message(STATUS "Fixing pkgconfig --- finished") - - set(VCPKG_FIXUP_PKGCONFIG_CALLED TRUE CACHE INTERNAL "See below" FORCE) - # Variable to check if this function has been called! + + set(VCPKG_FIXUP_PKGCONFIG_CALLED TRUE CACHE INTERNAL "See below" FORCE) + # Variable to check if this function has been called! # Theoreotically vcpkg could look for *.pc files and automatically call this function - # or check if this function has been called if *.pc files are detected. + # or check if this function has been called if *.pc files are detected. # The same is true for vcpkg_fixup_cmake_targets endfunction() diff --git a/scripts/cmake/vcpkg_install_msbuild.cmake b/scripts/cmake/vcpkg_install_msbuild.cmake index 8fc0298e07..1a0d9513df 100644 --- a/scripts/cmake/vcpkg_install_msbuild.cmake +++ b/scripts/cmake/vcpkg_install_msbuild.cmake @@ -138,6 +138,7 @@ function(vcpkg_install_msbuild) /p:WindowsTargetPlatformVersion=${_csc_TARGET_PLATFORM_VERSION} /p:VcpkgTriplet=${TARGET_TRIPLET} "/p:VcpkgCurrentInstalledDir=${CURRENT_INSTALLED_DIR}" + /p:VcpkgManifestInstall=false /m ) diff --git a/scripts/ports.cmake b/scripts/ports.cmake index 8c7c71d34a..f4ac28e6a2 100644 --- a/scripts/ports.cmake +++ b/scripts/ports.cmake @@ -43,6 +43,9 @@ if(CMD MATCHES "^BUILD$") if(NOT EXISTS ${CURRENT_PORT_DIR}/portfile.cmake) message(FATAL_ERROR "Port is missing portfile: ${CURRENT_PORT_DIR}/portfile.cmake") endif() + if(NOT EXISTS ${CURRENT_PORT_DIR}/CONTROL AND NOT EXISTS ${CURRENT_PORT_DIR}/vcpkg.json) + message(FATAL_ERROR "Port is missing control or manifest file: ${CURRENT_PORT_DIR}/{CONTROL,vcpkg.json}") + endif() unset(PACKAGES_DIR) unset(BUILDTREES_DIR) @@ -77,33 +80,44 @@ if(CMD MATCHES "^BUILD$") elseif(CMD MATCHES "^CREATE$") file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR) file(TO_NATIVE_PATH ${DOWNLOADS} NATIVE_DOWNLOADS) - if(EXISTS ${VCPKG_ROOT_DIR}/ports/${PORT}/portfile.cmake) - message(FATAL_ERROR "Portfile already exists: '${NATIVE_VCPKG_ROOT_DIR}\\ports\\${PORT}\\portfile.cmake'") + set(PORT_PATH "${VCPKG_ROOT_DIR}/ports/${PORT}") + file(TO_NATIVE_PATH ${PORT_PATH} NATIVE_PORT_PATH) + set(PORTFILE_PATH "${PORT_PATH}/portfile.cmake") + file(TO_NATIVE_PATH ${PORTFILE_PATH} NATIVE_PORTFILE_PATH) + set(MANIFEST_PATH "${PORT_PATH}/vcpkg.json") + file(TO_NATIVE_PATH ${MANIFEST_PATH} NATIVE_MANIFEST_PATH) + + if(EXISTS "${PORTFILE_PATH}") + message(FATAL_ERROR "Portfile already exists: '${NATIVE_PORTFILE_PATH}'") endif() if(NOT FILENAME) get_filename_component(FILENAME "${URL}" NAME) endif() string(REGEX REPLACE "(\\.(zip|gz|tar|tgz|bz2))+\$" "" ROOT_NAME ${FILENAME}) - if(EXISTS ${DOWNLOADS}/${FILENAME}) - message(STATUS "Using pre-downloaded: ${NATIVE_DOWNLOADS}\\${FILENAME}") - message(STATUS "If this is not desired, delete the file and ${NATIVE_VCPKG_ROOT_DIR}\\ports\\${PORT}") + + set(DOWNLOAD_PATH "${DOWNLOADS}/${FILENAME}") + file(TO_NATIVE_PATH ${DOWNLOAD_PATH} NATIVE_DOWNLOAD_PATH) + + if(EXISTS "${DOWNLOAD_PATH}") + message(STATUS "Using pre-downloaded: ${NATIVE_DOWNLOAD_PATH}") + message(STATUS "If this is not desired, delete the file and ${NATIVE_PORT_PATH}") else() include(vcpkg_download_distfile) - set(_VCPKG_INTERNAL_NO_HASH_CHECK "TRUE") + set(_VCPKG_INTERNAL_NO_HASH_CHECK ON) vcpkg_download_distfile(ARCHIVE URLS ${URL} FILENAME ${FILENAME} ) - set(_VCPKG_INTERNAL_NO_HASH_CHECK "FALSE") + set(_VCPKG_INTERNAL_NO_HASH_CHECK OFF) endif() - file(SHA512 ${DOWNLOADS}/${FILENAME} SHA512) + file(SHA512 ${DOWNLOAD_PATH} SHA512) - file(MAKE_DIRECTORY ${VCPKG_ROOT_DIR}/ports/${PORT}) - configure_file(${SCRIPTS}/templates/portfile.in.cmake ${VCPKG_ROOT_DIR}/ports/${PORT}/portfile.cmake @ONLY) - configure_file(${SCRIPTS}/templates/CONTROL.in ${VCPKG_ROOT_DIR}/ports/${PORT}/CONTROL @ONLY) + file(MAKE_DIRECTORY ${PORT_PATH}) + configure_file(${SCRIPTS}/templates/portfile.in.cmake ${PORTFILE_PATH} @ONLY) + configure_file(${SCRIPTS}/templates/vcpkg.json.in ${MANIFEST_PATH} @ONLY) - message(STATUS "Generated portfile: ${NATIVE_VCPKG_ROOT_DIR}\\ports\\${PORT}\\portfile.cmake") - message(STATUS "Generated CONTROL: ${NATIVE_VCPKG_ROOT_DIR}\\ports\\${PORT}\\CONTROL") + message(STATUS "Generated portfile: ${NATIVE_PORTFILE_PATH}") + message(STATUS "Generated manifest: ${NATIVE_MANIFEST_PATH}") message(STATUS "To launch an editor for these new files, run") message(STATUS " .\\vcpkg edit ${PORT}") endif() diff --git a/scripts/templates/CONTROL.in b/scripts/templates/CONTROL.in deleted file mode 100644 index 77f287e0aa..0000000000 --- a/scripts/templates/CONTROL.in +++ /dev/null @@ -1,10 +0,0 @@ -Source: @PORT@ -Version: -Homepage: -Description: -Build-Depends: -Default-Features: - -Feature: -Description: -Build-Depends: \ No newline at end of file diff --git a/scripts/templates/vcpkg.json.in b/scripts/templates/vcpkg.json.in new file mode 100644 index 0000000000..2e217387e7 --- /dev/null +++ b/scripts/templates/vcpkg.json.in @@ -0,0 +1,16 @@ +{ + "name": "@PORT@", + "version-string": "", + "homepage": "", + "description": "", + "dependencies": [], + + "default-features": [], + "features": [ + { + "name": "", + "description": "", + "dependencies": [] + } + ] +} diff --git a/toolsrc/CMakeLists.txt b/toolsrc/CMakeLists.txt index e940cdf16b..10a280faac 100644 --- a/toolsrc/CMakeLists.txt +++ b/toolsrc/CMakeLists.txt @@ -51,9 +51,11 @@ if(MSVC) if(VCPKG_DEVELOPMENT_WARNINGS) string(REGEX REPLACE "[-/]W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - add_compile_options(-W4 -analyze) + add_compile_options(-W4) if(VCPKG_COMPILER STREQUAL "clang") add_compile_options(-Wmissing-prototypes -Wno-missing-field-initializers) + else() + add_compile_options(-analyze) endif() endif() diff --git a/toolsrc/cmake/utilities.cmake b/toolsrc/cmake/utilities.cmake index 73e42a9fde..b99063a658 100644 --- a/toolsrc/cmake/utilities.cmake +++ b/toolsrc/cmake/utilities.cmake @@ -1,6 +1,7 @@ # Outputs to Cache: VCPKG_COMPILER function(vcpkg_detect_compiler) if(NOT DEFINED CACHE{VCPKG_COMPILER}) + message(STATUS "Detecting the C++ compiler in use") if(CMAKE_COMPILER_IS_GNUXX OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) message(FATAL_ERROR [[ @@ -45,6 +46,7 @@ If you would like to try anyway, pass --allowAppleClang to bootstrap.sh. set(VCPKG_COMPILER ${COMPILER} CACHE STRING "The compiler in use; one of gcc, clang, msvc") + message(STATUS "Detecting the C++ compiler in use - ${VCPKG_COMPILER}") endif() endfunction() diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index ff60149ac9..40f5af40f2 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -31,7 +31,7 @@ namespace vcpkg template<> struct ErrorHolder { - ErrorHolder() : m_is_error(false) {} + ErrorHolder() : m_is_error(false) { } template ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) { @@ -53,7 +53,7 @@ namespace vcpkg struct ErrorHolder { ErrorHolder() = default; - ErrorHolder(const std::error_code& err) : m_err(err) {} + ErrorHolder(const std::error_code& err) : m_err(err) { } bool has_error() const { return bool(m_err); } @@ -79,8 +79,8 @@ namespace vcpkg struct ExpectedHolder { ExpectedHolder() = default; - ExpectedHolder(const T& t) : t(t) {} - ExpectedHolder(T&& t) : t(std::move(t)) {} + ExpectedHolder(const T& t) : t(t) { } + ExpectedHolder(T&& t) : t(std::move(t)) { } using pointer = T*; using const_pointer = const T*; T* get() { return &t; } @@ -90,8 +90,8 @@ namespace vcpkg template struct ExpectedHolder { - ExpectedHolder(T& t) : t(&t) {} - ExpectedHolder() : t(nullptr) {} + ExpectedHolder(T& t) : t(&t) { } + ExpectedHolder() : t(nullptr) { } using pointer = T*; using const_pointer = T*; T* get() { return t; } @@ -107,10 +107,10 @@ namespace vcpkg // Constructors are intentionally implicit - ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) {} - ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) {} + ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) { } + ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) { } - ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) {} + ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) { } template>> ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t)) { @@ -213,7 +213,7 @@ namespace vcpkg } else { - return U{std::move(error()), expected_right_tag}; + return U{std::move(*this).error(), expected_right_tag}; } } diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h index cb04192217..49a4730914 100644 --- a/toolsrc/include/vcpkg/base/files.h +++ b/toolsrc/include/vcpkg/base/files.h @@ -59,6 +59,17 @@ namespace fs perms m_permissions; }; + struct SystemHandle + { + using type = intptr_t; // HANDLE + type system_handle = -1; + + bool is_valid() const + { + return system_handle != -1; + } + }; + #else using stdfs::file_type; @@ -71,6 +82,17 @@ namespace fs using stdfs::file_status::type; }; + struct SystemHandle + { + using type = int; // file descriptor + type system_handle = -1; + + bool is_valid() const + { + return system_handle != -1; + } + }; + #endif inline bool is_symlink(file_status s) noexcept @@ -171,6 +193,9 @@ namespace vcpkg::Files virtual void current_path(const fs::path& path, std::error_code&) = 0; void current_path(const fs::path& path, LineInfo li); + virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code&) = 0; + virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code&) = 0; + virtual std::vector find_from_PATH(const std::string& name) const = 0; }; diff --git a/toolsrc/include/vcpkg/base/json.h b/toolsrc/include/vcpkg/base/json.h index 69502fedc2..ecb96cde14 100644 --- a/toolsrc/include/vcpkg/base/json.h +++ b/toolsrc/include/vcpkg/base/json.h @@ -109,11 +109,13 @@ namespace vcpkg::Json double number() const noexcept; StringView string() const noexcept; - const Array& array() const noexcept; - Array& array() noexcept; + const Array& array() const& noexcept; + Array& array() & noexcept; + Array&& array() && noexcept; - const Object& object() const noexcept; - Object& object() noexcept; + const Object& object() const& noexcept; + Object& object() & noexcept; + Object&& object() && noexcept; static Value null(std::nullptr_t) noexcept; static Value boolean(bool) noexcept; @@ -268,11 +270,141 @@ namespace vcpkg::Json underlying_t underlying_; }; - // currently, a hard assertion on file errors + struct ReaderError + { + virtual void add_missing_field(std::string&& type, std::string&& key) = 0; + virtual void add_expected_type(std::string&& key, std::string&& expected_type) = 0; + virtual void add_extra_fields(std::string&& type, std::vector&& fields) = 0; + virtual void add_mutually_exclusive_fields(std::string&& type, std::vector&& fields) = 0; + + virtual ~ReaderError() = default; + }; + + struct Reader + { + explicit Reader(ReaderError* err) : err(err) { } + + ReaderError& error() const { return *err; } + + private: + ReaderError* err; + + template + using VisitorType = typename std::remove_reference_t::type; + + template + Optional> internal_visit(const Value& value, StringView key, Visitor& visitor) + { + switch (value.kind()) + { + using VK = Json::ValueKind; + case VK::Null: return visitor.visit_null(*this, key); + case VK::Boolean: return visitor.visit_boolean(*this, key, value.boolean()); + case VK::Integer: return visitor.visit_integer(*this, key, value.integer()); + case VK::Number: return visitor.visit_number(*this, key, value.number()); + case VK::String: return visitor.visit_string(*this, key, value.string()); + case VK::Array: return visitor.visit_array(*this, key, value.array()); + case VK::Object: return visitor.visit_object(*this, key, value.object()); + } + + vcpkg::Checks::exit_fail(VCPKG_LINE_INFO); + } + + // returns whether the field was found, not whether it was valid + template + bool internal_field(const Object& obj, StringView key, VisitorType& place, Visitor& visitor) + { + auto value = obj.get(key); + if (!value) + { + return false; + } + + Optional> opt = internal_visit(*value, key, visitor); + + if (auto val = opt.get()) + { + place = std::move(*val); + } + else + { + err->add_expected_type(key.to_string(), visitor.type_name().to_string()); + } + + return true; + } + + public: + template + void required_object_field( + StringView type, const Object& obj, StringView key, VisitorType& place, Visitor&& visitor) + { + if (!internal_field(obj, key, place, visitor)) + { + err->add_missing_field(type.to_string(), key.to_string()); + } + } + + template + void optional_object_field(const Object& obj, StringView key, VisitorType& place, Visitor&& visitor) + { + internal_field(obj, key, place, visitor); + } + + template + Optional>> array_elements(const Array& arr, StringView key, Visitor&& visitor) + { + std::vector> result; + for (const auto& el : arr) + { + auto opt = internal_visit(el, key, visitor); + if (auto p = opt.get()) + { + result.push_back(std::move(*p)); + } + else + { + return nullopt; + } + } + return std::move(result); + } + }; + + // Warning: NEVER use this type except as a CRTP base + template + struct VisitorCrtpBase + { + // the following function must be defined by the Underlying class + // const char* type_name(); + + // We do this auto dance since function bodies are checked _after_ typedefs in the superclass, + // but function declarations are checked beforehand. Therefore, we can get C++ to use this typedef + // only once the function bodies are checked by returning `auto` and specifying the + // return type in the function body. + auto visit_null(Reader&, StringView) { return Optional(nullopt); } + auto visit_boolean(Reader&, StringView, bool) { return Optional(nullopt); } + auto visit_integer(Reader& r, StringView field_name, int64_t i) + { + return static_cast(*this).visit_number(r, field_name, static_cast(i)); + } + auto visit_number(Reader&, StringView, double) { return Optional(nullopt); } + auto visit_string(Reader&, StringView, StringView) { return Optional(nullopt); } + auto visit_array(Reader&, StringView, const Json::Array&) + { + return Optional(nullopt); + } + auto visit_object(Reader&, StringView, const Json::Object&) + { + return Optional(nullopt); + } + // we can't make the SMFs protected because of an issue with /permissive mode + }; + ExpectedT, std::unique_ptr> parse_file( const Files::Filesystem&, const fs::path&, std::error_code& ec) noexcept; ExpectedT, std::unique_ptr> parse( - StringView text, const fs::path& filepath = "") noexcept; + StringView text, const fs::path& filepath = {}) noexcept; std::string stringify(const Value&, JsonStyle style); std::string stringify(const Object&, JsonStyle style); diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h index 17bef76753..e88d1074fd 100644 --- a/toolsrc/include/vcpkg/base/strings.h +++ b/toolsrc/include/vcpkg/base/strings.h @@ -8,6 +8,10 @@ #include #include +#include +#include +#include + #include namespace vcpkg::Strings::details @@ -48,6 +52,7 @@ namespace vcpkg::Strings::details } inline void append_internal(std::string& into, const char* v) { into.append(v); } inline void append_internal(std::string& into, const std::string& s) { into.append(s); } + inline void append_internal(std::string& into, StringView s) { into.append(s.begin(), s.end()); } template().to_string(std::declval()))> void append_internal(std::string& into, const T& t) @@ -60,6 +65,11 @@ namespace vcpkg::Strings::details { to_string(into, t); } + + struct tolower_char + { + char operator()(char c) const { return (c < 'A' || c > 'Z') ? c : c - 'A' + 'a'; } + }; } namespace vcpkg::Strings @@ -117,6 +127,11 @@ namespace vcpkg::Strings bool case_insensitive_ascii_equals(StringView left, StringView right); + template + void ascii_to_lowercase(It first, It last) + { + std::transform(first, last, first, details::tolower_char{}); + } std::string ascii_to_lowercase(std::string&& s); std::string ascii_to_uppercase(std::string&& s); @@ -134,11 +149,11 @@ namespace vcpkg::Strings } std::string output; - output.append(transformer(*begin)); + append(output, transformer(*begin)); for (auto it = std::next(begin); it != end; ++it) { output.append(delimiter); - output.append(transformer(*it)); + append(output, transformer(*it)); } return output; @@ -147,8 +162,8 @@ namespace vcpkg::Strings template std::string join(const char* delimiter, const Container& v, Transformer transformer) { - const auto begin = v.begin(); - const auto end = v.end(); + const auto begin = std::begin(v); + const auto end = std::end(v); return join(delimiter, begin, end, transformer); } @@ -163,7 +178,7 @@ namespace vcpkg::Strings template std::string join(const char* delimiter, const Container& v) { - using Element = decltype(*v.begin()); + using Element = decltype(*std::begin(v)); return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); } @@ -173,7 +188,7 @@ namespace vcpkg::Strings void trim_all_and_remove_whitespace_strings(std::vector* strings); - std::vector split(const std::string& s, const char delimiter); + std::vector split(StringView s, const char delimiter); const char* find_first_of(StringView searched, StringView candidates); @@ -193,6 +208,77 @@ namespace vcpkg::Strings return ret; } + // Equivalent to one of the `::strto[T]` functions. Returns `nullopt` if there is an error. + template + Optional strto(CStringView sv); + + template<> + inline Optional strto(CStringView sv) + { + char* endptr = nullptr; + double res = strtod(sv.c_str(), &endptr); + if (endptr == sv.c_str()) + { + // no digits + return nullopt; + } + // else, we may have HUGE_VAL but we expect the caller to deal with that + return res; + } + + template<> + inline Optional strto(CStringView sv) + { + char* endptr = nullptr; + long res = strtol(sv.c_str(), &endptr, 10); + if (endptr == sv.c_str()) + { + // no digits + return nullopt; + } + if (errno == ERANGE) + { + // out of bounds + return nullopt; + } + + return res; + } + + template<> + inline Optional strto(CStringView sv) + { + char* endptr = nullptr; + long long res = strtoll(sv.c_str(), &endptr, 10); + if (endptr == sv.c_str()) + { + // no digits + return nullopt; + } + if (errno == ERANGE) + { + // out of bounds + return nullopt; + } + + return res; + } + + template<> + inline Optional strto(CStringView sv) + { + auto res = strto(sv); + if (auto r = res.get()) + { + if (*r < INT_MIN || *r > INT_MAX) + { + return nullopt; + } + return static_cast(*r); + } + return nullopt; + } + const char* search(StringView haystack, StringView needle); bool contains(StringView haystack, StringView needle); diff --git a/toolsrc/include/vcpkg/base/stringview.h b/toolsrc/include/vcpkg/base/stringview.h index 1bb8fba6b8..aee70d697e 100644 --- a/toolsrc/include/vcpkg/base/stringview.h +++ b/toolsrc/include/vcpkg/base/stringview.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -30,8 +31,8 @@ namespace vcpkg { } - constexpr StringView(const char* ptr, size_t size) : m_ptr(ptr), m_size(size) {} - constexpr StringView(const char* b, const char* e) : m_ptr(b), m_size(static_cast(e - b)) {} + constexpr StringView(const char* ptr, size_t size) : m_ptr(ptr), m_size(size) { } + constexpr StringView(const char* b, const char* e) : m_ptr(b), m_size(static_cast(e - b)) { } constexpr const char* begin() const { return m_ptr; } constexpr const char* end() const { return m_ptr + m_size; } @@ -42,6 +43,23 @@ namespace vcpkg std::string to_string() const; void to_string(std::string& out) const; + constexpr StringView substr(size_t pos, size_t count = std::numeric_limits::max()) const + { + if (pos > m_size) + { + return StringView(); + } + + if (count > m_size - pos) + { + return StringView(m_ptr + pos, m_size - pos); + } + + return StringView(m_ptr + pos, count); + } + + constexpr char byte_at_index(size_t pos) const { return m_ptr[pos]; } + private: const char* m_ptr = 0; size_t m_size = 0; @@ -49,4 +67,8 @@ namespace vcpkg bool operator==(StringView lhs, StringView rhs) noexcept; bool operator!=(StringView lhs, StringView rhs) noexcept; + bool operator<(StringView lhs, StringView rhs) noexcept; + bool operator>(StringView lhs, StringView rhs) noexcept; + bool operator<=(StringView lhs, StringView rhs) noexcept; + bool operator>=(StringView lhs, StringView rhs) noexcept; } diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h index d556a40c84..2d2e4cf200 100644 --- a/toolsrc/include/vcpkg/binaryparagraph.h +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -32,15 +32,19 @@ namespace vcpkg PackageSpec spec; std::string version; - std::string description; - std::string maintainer; + int port_version = 0; + std::vector description; + std::vector maintainers; std::string feature; std::vector default_features; - std::vector depends; + std::vector dependencies; std::string abi; Type type; }; + bool operator==(const BinaryParagraph&, const BinaryParagraph&); + bool operator!=(const BinaryParagraph&, const BinaryParagraph&); + struct BinaryControlFile { BinaryParagraph core_paragraph; diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index f6be93bb25..b73e91fe76 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -16,6 +16,12 @@ namespace vcpkg::Commands using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); using CommandTypeC = void (*)(const VcpkgCmdArguments& args, Files::Filesystem& fs); + enum class DryRun : bool + { + No, + Yes, + }; + namespace BuildExternal { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); @@ -86,11 +92,6 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Import - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - namespace Integrate { extern const CommandStructure COMMAND_STRUCTURE; @@ -146,9 +147,23 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } + namespace FormatManifest + { + extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + namespace SetInstalled { extern const CommandStructure COMMAND_STRUCTURE; + void perform_and_exit_ex(const VcpkgCmdArguments& args, + const VcpkgPaths& paths, + const PortFileProvider::PathsPortFileProvider& provider, + IBinaryProvider& binary_provider, + const CMakeVars::CMakeVarProvider& cmake_vars, + const std::vector& specs, + const Build::BuildPackageOptions& install_plan_options, + DryRun dry_run); void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet); } diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index 7b1696dc34..5e1c9f657a 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -162,5 +162,5 @@ namespace vcpkg::Dependencies void print_plan(const ActionPlan& action_plan, const bool is_recursive = true, - const fs::path& default_ports_dir = ""); + const fs::path& default_ports_dir = {}); } diff --git a/toolsrc/include/vcpkg/logicexpression.h b/toolsrc/include/vcpkg/logicexpression.h deleted file mode 100644 index 3a3d0debe8..0000000000 --- a/toolsrc/include/vcpkg/logicexpression.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace vcpkg -{ - struct ExpressionContext - { - // map of cmake variables and their values. - const std::unordered_map& cmake_context; - - // The legacy context is a string (typically the name of the triplet). - // An identifier was considered 'true' if it is a substring of this. - // It is now used for backwards compatability diagnostic messages and - // will be eventually removed. - const std::string& legacy_context; - }; - - // Evaluate simple vcpkg logic expressions. An identifier in the expression is considered 'true' - // if it is a substring of the evaluation_context (typically the name of the triplet) - ExpectedT evaluate_expression(const std::string& expression, const ExpressionContext& context); -} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h index 832da90ce2..89fb8a92f9 100644 --- a/toolsrc/include/vcpkg/metrics.h +++ b/toolsrc/include/vcpkg/metrics.h @@ -18,6 +18,7 @@ namespace vcpkg::Metrics void track_metric(const std::string& name, double value); void track_buildtime(const std::string& name, double value); void track_property(const std::string& name, const std::string& value); + void track_feature(const std::string& feature, bool value); bool metrics_enabled(); diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h index 9c90f3fa6f..8d055e88a7 100644 --- a/toolsrc/include/vcpkg/packagespec.h +++ b/toolsrc/include/vcpkg/packagespec.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace vcpkg::Parse @@ -20,7 +21,7 @@ namespace vcpkg struct PackageSpec { PackageSpec() noexcept = default; - PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) {} + PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) { } static std::vector to_package_specs(const std::vector& ports, Triplet triplet); @@ -53,7 +54,7 @@ namespace vcpkg /// struct FeatureSpec { - FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} + FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) { } const std::string& name() const { return m_spec.name(); } const std::string& feature() const { return m_feature; } @@ -123,10 +124,9 @@ namespace vcpkg struct Dependency { - Features depend; - std::string qualifier; - - static ExpectedS from_string(const std::string& input); + std::string name; + std::vector features; + PlatformExpression::Expr platform; }; struct ParsedQualifiedSpecifier @@ -134,7 +134,7 @@ namespace vcpkg std::string name; Optional> features; Optional triplet; - Optional qualifier; + Optional platform; }; Optional parse_feature_name(Parse::ParserBase& parser); diff --git a/toolsrc/include/vcpkg/paragraphparser.h b/toolsrc/include/vcpkg/paragraphparser.h index 699838fbdf..71d11ddd03 100644 --- a/toolsrc/include/vcpkg/paragraphparser.h +++ b/toolsrc/include/vcpkg/paragraphparser.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -14,9 +15,16 @@ namespace vcpkg::Parse struct ParseControlErrorInfo { std::string name; - std::vector missing_fields; - std::vector extra_fields; + std::map> missing_fields; + std::map> extra_fields; + std::map expected_types; + std::map> mutually_exclusive_fields; std::string error; + + bool has_error() const + { + return !missing_fields.empty() || !extra_fields.empty() || !expected_types.empty() || !error.empty(); + } }; template @@ -26,17 +34,23 @@ namespace vcpkg::Parse struct ParagraphParser { - ParagraphParser(Paragraph&& fields) : fields(std::move(fields)) {} + ParagraphParser(Paragraph&& fields) : fields(std::move(fields)) { } + std::string required_field(const std::string& fieldname); void required_field(const std::string& fieldname, std::string& out); - std::string optional_field(const std::string& fieldname); void required_field(const std::string& fieldname, std::pair out); + + std::string optional_field(const std::string& fieldname); void optional_field(const std::string& fieldname, std::pair out); + + void add_type_error(const std::string& fieldname, const char* type) { expected_types[fieldname] = type; } + std::unique_ptr error_info(const std::string& name) const; private: Paragraph&& fields; std::vector missing_fields; + std::map expected_types; }; ExpectedS> parse_default_features_list(const std::string& str, diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h index 02e87a76d9..8f1c09c5b0 100644 --- a/toolsrc/include/vcpkg/paragraphs.h +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -10,11 +10,16 @@ namespace vcpkg::Paragraphs { using Paragraph = Parse::Paragraph; + ExpectedS parse_single_paragraph(const std::string& str, const std::string& origin); ExpectedS get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); ExpectedS> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); ExpectedS> parse_paragraphs(const std::string& str, const std::string& origin); - Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); + bool is_port_directory(const Files::Filesystem& fs, const fs::path& path); + + Parse::ParseExpected try_load_manifest(const Files::Filesystem& fs, const std::string& port_name, const fs::path& path_to_manifest, std::error_code& ec); + + Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path); ExpectedS try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec); diff --git a/toolsrc/include/vcpkg/platform-expression.h b/toolsrc/include/vcpkg/platform-expression.h new file mode 100644 index 0000000000..d857d75dc6 --- /dev/null +++ b/toolsrc/include/vcpkg/platform-expression.h @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg::PlatformExpression +{ + // map of cmake variables and their values. + using Context = std::unordered_map; + + namespace detail + { + struct ExprImpl; + } + struct Expr + { + static Expr Identifier(StringView id); + static Expr Not(Expr&& e); + static Expr And(std::vector&& exprs); + static Expr Or(std::vector&& exprs); + + // The empty expression is always true + static Expr Empty() { return Expr(); } + + // since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file + Expr(); + Expr(const Expr&); + Expr(Expr&&); + Expr& operator=(const Expr& e); + Expr& operator=(Expr&&); + + explicit Expr(std::unique_ptr&& e); + ~Expr(); + + bool evaluate(const Context& context) const; + bool is_empty() const { return !static_cast(underlying_); } + + private: + std::unique_ptr underlying_; + }; + + // Note: for backwards compatibility, in CONTROL files, + // multiple binary operators are allowed to be next to one another; i.e. + // (windows & arm) = (windows && arm) = (windows &&& arm), etc. + enum class MultipleBinaryOperators + { + Deny, + Allow, + }; + + // platform expression parses the following : + // : + // + // + // + // : + // ( ) + // + // : + // A lowercase alpha-numeric string + // : + // + // ! + // + // + // & + // + // + // | + ExpectedS parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators); +} diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h index 36cdba5897..50abbc8ca9 100644 --- a/toolsrc/include/vcpkg/portfileprovider.h +++ b/toolsrc/include/vcpkg/portfileprovider.h @@ -26,7 +26,7 @@ namespace vcpkg::PortFileProvider struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider { explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, - const std::vector* ports_dirs_paths); + const std::vector& ports_dirs_paths); ExpectedS get_control_file(const std::string& src_name) const override; std::vector load_all_control_files() const override; diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h index 08c306abf1..4212258ab4 100644 --- a/toolsrc/include/vcpkg/sourceparagraph.h +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -1,13 +1,13 @@ #pragma once -#include #include +#include #include #include #include +#include #include #include -#include namespace vcpkg { @@ -28,14 +28,17 @@ namespace vcpkg static Type from_string(const std::string&); }; + bool operator==(const Type&, const Type&); + bool operator!=(const Type&, const Type&); + /// /// Port metadata of additional feature in a package (part of CONTROL file) /// struct FeatureParagraph { std::string name; - std::string description; - std::vector depends; + std::vector description; + std::vector dependencies; }; /// @@ -45,13 +48,17 @@ namespace vcpkg { std::string name; std::string version; - std::string description; - std::string maintainer; + int port_version = 0; + std::vector description; + std::vector maintainers; std::string homepage; - std::vector depends; + std::string documentation; + std::vector dependencies; std::vector default_features; + std::string license; // SPDX license expression + Type type; - std::string supports_expression; + PlatformExpression::Expr supports_expression; }; /// @@ -69,9 +76,13 @@ namespace vcpkg } } + static Parse::ParseExpected parse_manifest_file(const fs::path& path_to_manifest, + const Json::Object& object); + static Parse::ParseExpected parse_control_file( const fs::path& path_to_control, std::vector&& control_paragraphs); + // Always non-null in non-error cases std::unique_ptr core_paragraph; std::vector> feature_paragraphs; diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h index 1fda813165..8fd85b4e05 100644 --- a/toolsrc/include/vcpkg/statusparagraphs.h +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -35,8 +35,8 @@ namespace vcpkg /// Triplet /// Feature name /// Iterator for found spec - iterator find(const std::string& name, Triplet triplet, const std::string& feature = ""); - const_iterator find(const std::string& name, Triplet triplet, const std::string& feature = "") const; + iterator find(const std::string& name, Triplet triplet, const std::string& feature = {}); + const_iterator find(const std::string& name, Triplet triplet, const std::string& feature = {}) const; std::vector*> find_all(const std::string& name, Triplet triplet); diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 690245d084..d8dc94a377 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -106,32 +106,63 @@ namespace vcpkg static void append_common_options(HelpTableFormatter& target); + constexpr static StringLiteral VCPKG_ROOT_DIR_ENV = "VCPKG_ROOT"; + constexpr static StringLiteral VCPKG_ROOT_DIR_ARG = "vcpkg-root"; std::unique_ptr vcpkg_root_dir; + constexpr static StringLiteral MANIFEST_ROOT_DIR_ARG = "x-manifest-root"; + std::unique_ptr manifest_root_dir; + constexpr static StringLiteral BUILDTREES_ROOT_DIR_ARG = "x-buildtrees-root"; std::unique_ptr buildtrees_root_dir; + constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ENV = "VCPKG_DOWNLOADS"; + constexpr static StringLiteral DOWNLOADS_ROOT_DIR_ARG = "downloads-root"; std::unique_ptr downloads_root_dir; + constexpr static StringLiteral INSTALL_ROOT_DIR_ARG = "x-install-root"; std::unique_ptr install_root_dir; + constexpr static StringLiteral PACKAGES_ROOT_DIR_ARG = "x-packages-root"; std::unique_ptr packages_root_dir; + constexpr static StringLiteral SCRIPTS_ROOT_DIR_ARG = "x-scripts-root"; std::unique_ptr scripts_root_dir; + constexpr static StringLiteral DEFAULT_VISUAL_STUDIO_PATH_ENV = "VCPKG_VISUAL_STUDIO_PATH"; std::unique_ptr default_visual_studio_path; + constexpr static StringLiteral TRIPLET_ENV = "VCPKG_DEFAULT_TRIPLET"; + constexpr static StringLiteral TRIPLET_ARG = "triplet"; std::unique_ptr triplet; - std::unique_ptr> overlay_ports; - std::unique_ptr> overlay_triplets; + constexpr static StringLiteral OVERLAY_PORTS_ARG = "overlay-ports"; + std::vector overlay_ports; + constexpr static StringLiteral OVERLAY_TRIPLETS_ARG = "overlay-triplets"; + std::vector overlay_triplets; - std::vector binarysources; + constexpr static StringLiteral BINARY_SOURCES_ARG = "x-binarysource"; + std::vector binary_sources; + constexpr static StringLiteral DEBUG_SWITCH = "debug"; Optional debug = nullopt; + constexpr static StringLiteral SEND_METRICS_SWITCH = "sendmetrics"; Optional send_metrics = nullopt; // fully disable metrics -- both printing and sending + constexpr static StringLiteral DISABLE_METRICS_ENV = "VCPKG_DISABLE_METRICS"; + constexpr static StringLiteral DISABLE_METRICS_SWITCH = "disable-metrics"; Optional disable_metrics = nullopt; + constexpr static StringLiteral PRINT_METRICS_SWITCH = "printmetrics"; Optional print_metrics = nullopt; // feature flags + constexpr static StringLiteral FEATURE_FLAGS_ENV = "VCPKG_FEATURE_FLAGS"; + constexpr static StringLiteral FEATURE_FLAGS_ARG = "feature-flags"; + + constexpr static StringLiteral FEATURE_PACKAGES_SWITCH = "featurepackages"; Optional feature_packages = nullopt; + constexpr static StringLiteral BINARY_CACHING_FEATURE = "binarycaching"; + constexpr static StringLiteral BINARY_CACHING_SWITCH = "binarycaching"; Optional binary_caching = nullopt; + constexpr static StringLiteral COMPILER_TRACKING_FEATURE = "compilertracking"; Optional compiler_tracking = nullopt; + constexpr static StringLiteral MANIFEST_MODE_FEATURE = "manifests"; + Optional manifest_mode = nullopt; + bool binary_caching_enabled() const { return binary_caching.value_or(false); } bool compiler_tracking_enabled() const { return compiler_tracking.value_or(false); } @@ -142,6 +173,10 @@ namespace vcpkg void imbue_from_environment(); + void check_feature_flag_consistency() const; + + void track_feature_flag_metrics() const; + private: std::unordered_map>> optional_command_arguments; }; diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index c4c420820c..90ab3c58d5 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -67,11 +67,11 @@ namespace vcpkg std::string name; fs::path location; - TripletFile(const std::string& name, const fs::path& location) : name(name), location(location) {} + TripletFile(const std::string& name, const fs::path& location) : name(name), location(location) { } }; VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args); - ~VcpkgPaths() noexcept; + ~VcpkgPaths(); fs::path package_dir(const PackageSpec& spec) const; fs::path build_info_file_path(const PackageSpec& spec) const; @@ -84,7 +84,7 @@ namespace vcpkg fs::path original_cwd; fs::path root; - + fs::path manifest_root_dir; fs::path buildtrees; fs::path downloads; fs::path packages; @@ -120,6 +120,9 @@ namespace vcpkg const System::Environment& get_action_env(const Build::AbiInfo& abi_info) const; const std::string& get_triplet_info(const Build::AbiInfo& abi_info) const; + bool manifest_mode_enabled() const { return !manifest_root_dir.empty(); } + + void track_feature_flag_metrics() const; private: std::unique_ptr m_pimpl; diff --git a/toolsrc/src/vcpkg-fuzz/main.cpp b/toolsrc/src/vcpkg-fuzz/main.cpp index 881577654d..bbff0d98d9 100644 --- a/toolsrc/src/vcpkg-fuzz/main.cpp +++ b/toolsrc/src/vcpkg-fuzz/main.cpp @@ -2,6 +2,9 @@ #include #include #include +#include + +#include #include #include @@ -17,6 +20,7 @@ namespace None, Utf8Decoder, JsonParser, + PlatformExpr, }; struct FuzzArgs @@ -57,10 +61,14 @@ namespace { kind = FuzzKind::Utf8Decoder; } + else if (value == "platform-expr") + { + kind = FuzzKind::PlatformExpr; + } else { System::print2(System::Color::error, "Invalid kind: ", value, "\n"); - System::print2(System::Color::error, " Expected one of: utf-8, json\n\n"); + System::print2(System::Color::error, " Expected one of: utf-8, json, platform-expr\n\n"); print_help_and_exit(true); } } @@ -120,6 +128,44 @@ Options: return std::move(ss).str(); } + [[noreturn]] void fuzz_json_and_exit(StringView text) + { + auto res = Json::parse(text); + if (!res) + { + Checks::exit_with_message(VCPKG_LINE_INFO, res.error()->format()); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + [[noreturn]] void fuzz_utf8_and_exit(StringView text) + { + auto res = Unicode::Utf8Decoder(text.begin(), text.end()); + for (auto ch : res) + { + (void)ch; + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + [[noreturn]] void fuzz_platform_expr_and_exit(StringView text) + { + auto res1 = PlatformExpression::parse_platform_expression(text, PlatformExpression::MultipleBinaryOperators::Deny); + auto res2 = PlatformExpression::parse_platform_expression(text, PlatformExpression::MultipleBinaryOperators::Allow); + + if (!res1) + { + Checks::exit_with_message(VCPKG_LINE_INFO, res1.error()); + } + if (!res2) + { + Checks::exit_with_message(VCPKG_LINE_INFO, res2.error()); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } } int main(int argc, char** argv) @@ -132,13 +178,11 @@ int main(int argc, char** argv) } auto text = read_all_of_stdin(); - auto res = Json::parse(text); - if (!res) + switch (args.kind) { - System::print2(System::Color::error, res.error()->format()); - } - else - { - System::print2(System::Color::success, "success!"); + case FuzzKind::JsonParser: fuzz_json_and_exit(text); + case FuzzKind::Utf8Decoder: fuzz_utf8_and_exit(text); + case FuzzKind::PlatformExpr: fuzz_platform_expr_and_exit(text); + default: Checks::exit_fail(VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg-test/arguments.cpp b/toolsrc/src/vcpkg-test/arguments.cpp index 448a5035c3..3ce4c5a9bf 100644 --- a/toolsrc/src/vcpkg-test/arguments.cpp +++ b/toolsrc/src/vcpkg-test/arguments.cpp @@ -32,13 +32,13 @@ TEST_CASE ("VcpkgCmdArguments from lowercase argument sequence", "[arguments]") REQUIRE(v.print_metrics); REQUIRE(*v.print_metrics.get()); - REQUIRE(v.overlay_ports->size() == 2); - REQUIRE(v.overlay_ports->at(0) == "C:\\ports1"); - REQUIRE(v.overlay_ports->at(1) == "C:\\ports2"); + REQUIRE(v.overlay_ports.size() == 2); + REQUIRE(v.overlay_ports.at(0) == "C:\\ports1"); + REQUIRE(v.overlay_ports.at(1) == "C:\\ports2"); - REQUIRE(v.overlay_triplets->size() == 2); - REQUIRE(v.overlay_triplets->at(0) == "C:\\tripletsA"); - REQUIRE(v.overlay_triplets->at(1) == "C:\\tripletsB"); + REQUIRE(v.overlay_triplets.size() == 2); + REQUIRE(v.overlay_triplets.at(0) == "C:\\tripletsA"); + REQUIRE(v.overlay_triplets.at(1) == "C:\\tripletsB"); } TEST_CASE ("VcpkgCmdArguments from uppercase argument sequence", "[arguments]") @@ -64,13 +64,13 @@ TEST_CASE ("VcpkgCmdArguments from uppercase argument sequence", "[arguments]") REQUIRE(v.print_metrics); REQUIRE(*v.print_metrics.get()); - REQUIRE(v.overlay_ports->size() == 2); - REQUIRE(v.overlay_ports->at(0) == "C:\\ports1"); - REQUIRE(v.overlay_ports->at(1) == "C:\\ports2"); + REQUIRE(v.overlay_ports.size() == 2); + REQUIRE(v.overlay_ports.at(0) == "C:\\ports1"); + REQUIRE(v.overlay_ports.at(1) == "C:\\ports2"); - REQUIRE(v.overlay_triplets->size() == 2); - REQUIRE(v.overlay_triplets->at(0) == "C:\\tripletsA"); - REQUIRE(v.overlay_triplets->at(1) == "C:\\tripletsB"); + REQUIRE(v.overlay_triplets.size() == 2); + REQUIRE(v.overlay_triplets.at(0) == "C:\\tripletsA"); + REQUIRE(v.overlay_triplets.at(1) == "C:\\tripletsB"); } TEST_CASE ("VcpkgCmdArguments from argument sequence with valued options", "[arguments]") diff --git a/toolsrc/src/vcpkg-test/dependencies.cpp b/toolsrc/src/vcpkg-test/dependencies.cpp index c9eb0df354..4a4b1ac06e 100644 --- a/toolsrc/src/vcpkg-test/dependencies.cpp +++ b/toolsrc/src/vcpkg-test/dependencies.cpp @@ -14,8 +14,10 @@ TEST_CASE ("parse depends", "[dependencies]") REQUIRE(w); auto& v = *w.get(); REQUIRE(v.size() == 1); - REQUIRE(v.at(0).depend.name == "liba"); - REQUIRE(v.at(0).qualifier == "windows"); + REQUIRE(v.at(0).name == "liba"); + REQUIRE(v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}})); + REQUIRE(v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}})); + REQUIRE(!v.at(0).platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}})); } TEST_CASE ("filter depends", "[dependencies]") @@ -48,14 +50,17 @@ TEST_CASE ("parse feature depends", "[dependencies]") auto& v = *u_.get(); REQUIRE(v.size() == 2); auto&& a0 = v.at(0); - REQUIRE(a0.depend.name == "libwebp"); - REQUIRE(a0.depend.features.size() == 9); - REQUIRE(a0.qualifier.empty()); + REQUIRE(a0.name == "libwebp"); + REQUIRE(a0.features.size() == 9); + REQUIRE(a0.platform.is_empty()); auto&& a1 = v.at(1); - REQUIRE(a1.depend.name == "libwebp"); - REQUIRE(a1.depend.features.size() == 2); - REQUIRE(a1.qualifier == "!osx"); + REQUIRE(a1.name == "libwebp"); + REQUIRE(a1.features.size() == 2); + REQUIRE(!a1.platform.is_empty()); + REQUIRE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}})); + REQUIRE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}})); + REQUIRE_FALSE(a1.platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}})); } TEST_CASE ("qualified dependency", "[dependencies]") diff --git a/toolsrc/src/vcpkg-test/json.cpp b/toolsrc/src/vcpkg-test/json.cpp index a957618cb5..86335d468a 100644 --- a/toolsrc/src/vcpkg-test/json.cpp +++ b/toolsrc/src/vcpkg-test/json.cpp @@ -28,8 +28,8 @@ static std::string mystringify(const Value& val) { return Json::stringify(val, J TEST_CASE ("JSON stringify weird strings", "[json]") { vcpkg::StringView str = U8_STR("😀 😁 😂 🤣 😃 😄 😅 😆 😉"); - REQUIRE(mystringify(Value::string(str)) == ('"' + str.to_string() + '"')); - REQUIRE(mystringify(Value::string("\xED\xA0\x80")) == "\"\\ud800\""); // unpaired surrogate + REQUIRE(mystringify(Value::string(str)) == ('"' + str.to_string() + "\"\n")); + REQUIRE(mystringify(Value::string("\xED\xA0\x80")) == "\"\\ud800\"\n"); // unpaired surrogate } TEST_CASE ("JSON parse keywords", "[json]") diff --git a/toolsrc/src/vcpkg-test/manifests.cpp b/toolsrc/src/vcpkg-test/manifests.cpp new file mode 100644 index 0000000000..a6c661301c --- /dev/null +++ b/toolsrc/src/vcpkg-test/manifests.cpp @@ -0,0 +1,235 @@ +#include +#include + +#include +#include +#include +#include + +using namespace vcpkg; +using namespace vcpkg::Paragraphs; +using namespace vcpkg::Test; + +static Json::Object parse_json_object(StringView sv) +{ + auto json = Json::parse(sv); + // we're not testing json parsing here, so just fail on errors + if (auto r = json.get()) + { + return std::move(r->first.object()); + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, json.error()->format()); + } +} + +static Parse::ParseExpected test_parse_manifest(StringView sv, bool expect_fail = false) +{ + auto object = parse_json_object(sv); + auto res = SourceControlFile::parse_manifest_file(fs::u8path(""), object); + if (!res.has_value() && !expect_fail) + { + print_error_message(res.error()); + } + return res; +} + +TEST_CASE ("manifest construct minimum", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "zlib", + "version-string": "1.2.8" + })json"); + + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->name == "zlib"); + REQUIRE(pgh.core_paragraph->version == "1.2.8"); + REQUIRE(pgh.core_paragraph->maintainers.empty()); + REQUIRE(pgh.core_paragraph->description.empty()); + REQUIRE(pgh.core_paragraph->dependencies.empty()); +} + +TEST_CASE ("manifest construct maximum", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "s", + "version-string": "v", + "maintainers": ["m"], + "description": "d", + "dependencies": ["bd"], + "default-features": ["df"], + "features": [ + { + "name": "iroh", + "description": "zuko's uncle", + "dependencies": [ + { + "name": "tea" + }, + "firebending", + { + "name": "order.white-lotus", + "features": [ "the-ancient-ways" ], + "platform": "!(windows & arm)" + } + ] + }, + { + "name": "zuko", + "description": ["son of the fire lord", "firebending 師父"] + } + ] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->name == "s"); + REQUIRE(pgh.core_paragraph->version == "v"); + REQUIRE(pgh.core_paragraph->maintainers.size() == 1); + REQUIRE(pgh.core_paragraph->maintainers[0] == "m"); + REQUIRE(pgh.core_paragraph->description.size() == 1); + REQUIRE(pgh.core_paragraph->description[0] == "d"); + REQUIRE(pgh.core_paragraph->dependencies.size() == 1); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "bd"); + REQUIRE(pgh.core_paragraph->default_features.size() == 1); + REQUIRE(pgh.core_paragraph->default_features[0] == "df"); + + REQUIRE(pgh.feature_paragraphs.size() == 2); + + REQUIRE(pgh.feature_paragraphs[0]->name == "iroh"); + REQUIRE(pgh.feature_paragraphs[0]->description.size() == 1); + REQUIRE(pgh.feature_paragraphs[0]->description[0] == "zuko's uncle"); + REQUIRE(pgh.feature_paragraphs[0]->dependencies.size() == 3); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[0].name == "tea"); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[1].name == "firebending"); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].name == "order.white-lotus"); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].features.size() == 1); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].features[0] == "the-ancient-ways"); + REQUIRE_FALSE(pgh.feature_paragraphs[0]->dependencies[2].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "arm"}})); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}, {"VCPKG_TARGET_ARCHITECTURE", "x86"}})); + REQUIRE(pgh.feature_paragraphs[0]->dependencies[2].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}, {"VCPKG_TARGET_ARCHITECTURE", "x86"}})); + + REQUIRE(pgh.feature_paragraphs[1]->name == "zuko"); + REQUIRE(pgh.feature_paragraphs[1]->description.size() == 2); + REQUIRE(pgh.feature_paragraphs[1]->description[0] == "son of the fire lord"); + REQUIRE(pgh.feature_paragraphs[1]->description[1] == "firebending 師父"); +} + +TEST_CASE ("SourceParagraph manifest two dependencies", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "zlib", + "version-string": "1.2.8", + "dependencies": ["z", "openssl"] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->dependencies.size() == 2); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "z"); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "openssl"); +} + +TEST_CASE ("SourceParagraph manifest three dependencies", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "zlib", + "version-string": "1.2.8", + "dependencies": ["z", "openssl", "xyz"] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->dependencies.size() == 3); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "z"); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "openssl"); + REQUIRE(pgh.core_paragraph->dependencies[2].name == "xyz"); +} + +TEST_CASE ("SourceParagraph manifest construct qualified dependencies", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "zlib", + "version-string": "1.2.8", + "dependencies": [ + { + "name": "liba", + "platform": "windows" + }, + { + "name": "libb", + "platform": "uwp" + } + ] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->name == "zlib"); + REQUIRE(pgh.core_paragraph->version == "1.2.8"); + REQUIRE(pgh.core_paragraph->maintainers.empty()); + REQUIRE(pgh.core_paragraph->description.empty()); + REQUIRE(pgh.core_paragraph->dependencies.size() == 2); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "liba"); + REQUIRE(pgh.core_paragraph->dependencies[0].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}})); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "libb"); + REQUIRE(pgh.core_paragraph->dependencies[1].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}})); +} + +TEST_CASE ("SourceParagraph manifest default features", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "a", + "version-string": "1.0", + "default-features": ["a1"] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->default_features.size() == 1); + REQUIRE(pgh.core_paragraph->default_features[0] == "a1"); +} + +TEST_CASE ("SourceParagraph manifest description paragraph", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "a", + "version-string": "1.0", + "description": ["line 1", "line 2", "line 3"] + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->description.size() == 3); + REQUIRE(pgh.core_paragraph->description[0] == "line 1"); + REQUIRE(pgh.core_paragraph->description[1] == "line 2"); + REQUIRE(pgh.core_paragraph->description[2] == "line 3"); +} + +TEST_CASE ("SourceParagraph manifest supports", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "a", + "version-string": "1.0", + "supports": "!(windows | osx)" + })json"); + REQUIRE(m_pgh.has_value()); + auto& pgh = **m_pgh.get(); + + REQUIRE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Linux"}})); + REQUIRE_FALSE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}})); + REQUIRE_FALSE(pgh.core_paragraph->supports_expression.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "Darwin"}})); +} + +TEST_CASE ("SourceParagraph manifest empty supports", "[manifests]") +{ + auto m_pgh = test_parse_manifest(R"json({ + "name": "a", + "version-string": "1.0", + "supports": "" + })json", true); + REQUIRE_FALSE(m_pgh.has_value()); +} diff --git a/toolsrc/src/vcpkg-test/paragraph.cpp b/toolsrc/src/vcpkg-test/paragraph.cpp index 678064f1cc..6c2103d5f3 100644 --- a/toolsrc/src/vcpkg-test/paragraph.cpp +++ b/toolsrc/src/vcpkg-test/paragraph.cpp @@ -8,28 +8,28 @@ namespace Strings = vcpkg::Strings; using vcpkg::Parse::Paragraph; -namespace { - -auto test_parse_control_file(const std::vector>& v) +namespace { - std::vector pghs; - for (auto&& p : v) + auto test_parse_control_file(const std::vector>& v) { - pghs.emplace_back(); - for (auto&& kv : p) - pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); + std::vector pghs; + for (auto&& p : v) + { + pghs.emplace_back(); + for (auto&& kv : p) + pghs.back().emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); + } + return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs)); } - return vcpkg::SourceControlFile::parse_control_file("", std::move(pghs)); -} -auto test_make_binary_paragraph(const std::unordered_map& v) -{ - Paragraph pgh; - for (auto&& kv : v) - pgh.emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); + auto test_make_binary_paragraph(const std::unordered_map& v) + { + Paragraph pgh; + for (auto&& kv : v) + pgh.emplace(kv.first, std::make_pair(kv.second, vcpkg::Parse::TextRowCol{})); - return vcpkg::BinaryParagraph(std::move(pgh)); -} + return vcpkg::BinaryParagraph(std::move(pgh)); + } } @@ -45,9 +45,9 @@ TEST_CASE ("SourceParagraph construct minimum", "[paragraph]") REQUIRE(pgh.core_paragraph->name == "zlib"); REQUIRE(pgh.core_paragraph->version == "1.2.8"); - REQUIRE(pgh.core_paragraph->maintainer == ""); - REQUIRE(pgh.core_paragraph->description == ""); - REQUIRE(pgh.core_paragraph->depends.size() == 0); + REQUIRE(pgh.core_paragraph->maintainers.empty()); + REQUIRE(pgh.core_paragraph->description.empty()); + REQUIRE(pgh.core_paragraph->dependencies.size() == 0); } TEST_CASE ("SourceParagraph construct maximum", "[paragraph]") @@ -65,15 +65,17 @@ TEST_CASE ("SourceParagraph construct maximum", "[paragraph]") REQUIRE(pgh.core_paragraph->name == "s"); REQUIRE(pgh.core_paragraph->version == "v"); - REQUIRE(pgh.core_paragraph->maintainer == "m"); - REQUIRE(pgh.core_paragraph->description == "d"); - REQUIRE(pgh.core_paragraph->depends.size() == 1); - REQUIRE(pgh.core_paragraph->depends[0].depend.name == "bd"); + REQUIRE(pgh.core_paragraph->maintainers.size() == 1); + REQUIRE(pgh.core_paragraph->maintainers[0] == "m"); + REQUIRE(pgh.core_paragraph->description.size() == 1); + REQUIRE(pgh.core_paragraph->description[0] == "d"); + REQUIRE(pgh.core_paragraph->dependencies.size() == 1); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "bd"); REQUIRE(pgh.core_paragraph->default_features.size() == 1); REQUIRE(pgh.core_paragraph->default_features[0] == "df"); } -TEST_CASE ("SourceParagraph two depends", "[paragraph]") +TEST_CASE ("SourceParagraph two dependencies", "[paragraph]") { auto m_pgh = test_parse_control_file({{ {"Source", "zlib"}, @@ -83,12 +85,12 @@ TEST_CASE ("SourceParagraph two depends", "[paragraph]") REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); - REQUIRE(pgh.core_paragraph->depends.size() == 2); - REQUIRE(pgh.core_paragraph->depends[0].depend.name == "z"); - REQUIRE(pgh.core_paragraph->depends[1].depend.name == "openssl"); + REQUIRE(pgh.core_paragraph->dependencies.size() == 2); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "z"); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "openssl"); } -TEST_CASE ("SourceParagraph three depends", "[paragraph]") +TEST_CASE ("SourceParagraph three dependencies", "[paragraph]") { auto m_pgh = test_parse_control_file({{ {"Source", "zlib"}, @@ -98,13 +100,13 @@ TEST_CASE ("SourceParagraph three depends", "[paragraph]") REQUIRE(m_pgh.has_value()); auto& pgh = **m_pgh.get(); - REQUIRE(pgh.core_paragraph->depends.size() == 3); - REQUIRE(pgh.core_paragraph->depends[0].depend.name == "z"); - REQUIRE(pgh.core_paragraph->depends[1].depend.name == "openssl"); - REQUIRE(pgh.core_paragraph->depends[2].depend.name == "xyz"); + REQUIRE(pgh.core_paragraph->dependencies.size() == 3); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "z"); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "openssl"); + REQUIRE(pgh.core_paragraph->dependencies[2].name == "xyz"); } -TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]") +TEST_CASE ("SourceParagraph construct qualified dependencies", "[paragraph]") { auto m_pgh = test_parse_control_file({{ {"Source", "zlib"}, @@ -116,13 +118,13 @@ TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]") REQUIRE(pgh.core_paragraph->name == "zlib"); REQUIRE(pgh.core_paragraph->version == "1.2.8"); - REQUIRE(pgh.core_paragraph->maintainer == ""); - REQUIRE(pgh.core_paragraph->description == ""); - REQUIRE(pgh.core_paragraph->depends.size() == 2); - REQUIRE(pgh.core_paragraph->depends[0].depend.name == "liba"); - REQUIRE(pgh.core_paragraph->depends[0].qualifier == "windows"); - REQUIRE(pgh.core_paragraph->depends[1].depend.name == "libb"); - REQUIRE(pgh.core_paragraph->depends[1].qualifier == "uwp"); + REQUIRE(pgh.core_paragraph->maintainers.empty()); + REQUIRE(pgh.core_paragraph->description.empty()); + REQUIRE(pgh.core_paragraph->dependencies.size() == 2); + REQUIRE(pgh.core_paragraph->dependencies[0].name == "liba"); + REQUIRE(pgh.core_paragraph->dependencies[0].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", ""}})); + REQUIRE(pgh.core_paragraph->dependencies[1].name == "libb"); + REQUIRE(pgh.core_paragraph->dependencies[1].platform.evaluate({{"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}})); } TEST_CASE ("SourceParagraph default features", "[paragraph]") @@ -150,10 +152,10 @@ TEST_CASE ("BinaryParagraph construct minimum", "[paragraph]") REQUIRE(pgh.spec.name() == "zlib"); REQUIRE(pgh.version == "1.2.8"); - REQUIRE(pgh.maintainer == ""); - REQUIRE(pgh.description == ""); + REQUIRE(pgh.maintainers.empty()); + REQUIRE(pgh.description.empty()); REQUIRE(pgh.spec.triplet().canonical_name() == "x86-windows"); - REQUIRE(pgh.depends.size() == 0); + REQUIRE(pgh.dependencies.size() == 0); } TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]") @@ -170,13 +172,15 @@ TEST_CASE ("BinaryParagraph construct maximum", "[paragraph]") REQUIRE(pgh.spec.name() == "s"); REQUIRE(pgh.version == "v"); - REQUIRE(pgh.maintainer == "m"); - REQUIRE(pgh.description == "d"); - REQUIRE(pgh.depends.size() == 1); - REQUIRE(pgh.depends[0] == "bd"); + REQUIRE(pgh.maintainers.size() == 1); + REQUIRE(pgh.maintainers[0] == "m"); + REQUIRE(pgh.description.size() == 1); + REQUIRE(pgh.description[0] == "d"); + REQUIRE(pgh.dependencies.size() == 1); + REQUIRE(pgh.dependencies[0] == "bd"); } -TEST_CASE ("BinaryParagraph three depends", "[paragraph]") +TEST_CASE ("BinaryParagraph three dependencies", "[paragraph]") { auto pgh = test_make_binary_paragraph({ {"Package", "zlib"}, @@ -186,10 +190,10 @@ TEST_CASE ("BinaryParagraph three depends", "[paragraph]") {"Depends", "a, b, c"}, }); - REQUIRE(pgh.depends.size() == 3); - REQUIRE(pgh.depends[0] == "a"); - REQUIRE(pgh.depends[1] == "b"); - REQUIRE(pgh.depends[2] == "c"); + REQUIRE(pgh.dependencies.size() == 3); + REQUIRE(pgh.dependencies[0] == "a"); + REQUIRE(pgh.dependencies[1] == "b"); + REQUIRE(pgh.dependencies[2] == "c"); } TEST_CASE ("BinaryParagraph abi", "[paragraph]") @@ -202,7 +206,7 @@ TEST_CASE ("BinaryParagraph abi", "[paragraph]") {"Abi", "abcd123"}, }); - REQUIRE(pgh.depends.size() == 0); + REQUIRE(pgh.dependencies.size() == 0); REQUIRE(pgh.abi == "abcd123"); } @@ -216,7 +220,7 @@ TEST_CASE ("BinaryParagraph default features", "[paragraph]") {"Default-Features", "a1"}, }); - REQUIRE(pgh.depends.size() == 0); + REQUIRE(pgh.dependencies.size() == 0); REQUIRE(pgh.default_features.size() == 1); REQUIRE(pgh.default_features[0] == "a1"); } @@ -300,8 +304,8 @@ TEST_CASE ("parse paragraphs empty fields", "[paragraph]") REQUIRE(pghs.size() == 1); REQUIRE(pghs[0].size() == 2); - REQUIRE(pghs[0]["f1"].first == ""); - REQUIRE(pghs[0]["f2"].first == ""); + REQUIRE(pghs[0]["f1"].first.empty()); + REQUIRE(pghs[0]["f2"].first.empty()); REQUIRE(pghs[0].size() == 2); } @@ -408,7 +412,7 @@ TEST_CASE ("BinaryParagraph serialize max", "[paragraph]") REQUIRE(pghs[0]["Version"].first == "1.2.8"); REQUIRE(pghs[0]["Architecture"].first == "x86-windows"); REQUIRE(pghs[0]["Multi-Arch"].first == "same"); - REQUIRE(pghs[0]["Description"].first == "first line\n second line"); + REQUIRE(pghs[0]["Description"].first == "first line\n second line"); REQUIRE(pghs[0]["Depends"].first == "dep"); REQUIRE(pghs[0]["Type"].first == "Port"); } diff --git a/toolsrc/src/vcpkg-test/plan.cpp b/toolsrc/src/vcpkg-test/plan.cpp index a39c2b4a47..b93ec54ce5 100644 --- a/toolsrc/src/vcpkg-test/plan.cpp +++ b/toolsrc/src/vcpkg-test/plan.cpp @@ -37,7 +37,7 @@ static void features_check(Dependencies::InstallPlanAction& plan, for (auto&& feature_name : expected_features) { // TODO: see if this can be simplified - if (feature_name == "core" || feature_name == "") + if (feature_name == "core" || feature_name.empty()) { REQUIRE((Util::find(feature_list, "core") != feature_list.end() || Util::find(feature_list, "") != feature_list.end())); diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 859fe99c51..9cd9640675 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -72,6 +72,8 @@ static void inner(vcpkg::Files::Filesystem& fs, const VcpkgCmdArguments& args) } const VcpkgPaths paths(fs, args); + paths.track_feature_flag_metrics(); + fs.current_path(paths.root, VCPKG_LINE_INFO); if (args.command == "install" || args.command == "remove" || args.command == "export" || args.command == "update") { @@ -231,10 +233,11 @@ int main(const int argc, const char* const* const argv) VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(fs, argc, argv); args.imbue_from_environment(); + args.check_feature_flag_consistency(); + if (const auto p = args.disable_metrics.get()) Metrics::g_metrics.lock()->set_disabled(*p); if (const auto p = args.print_metrics.get()) Metrics::g_metrics.lock()->set_print_metrics(*p); if (const auto p = args.send_metrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); - if (const auto p = args.disable_metrics.get()) Metrics::g_metrics.lock()->set_disabled(*p); if (const auto p = args.debug.get()) Debug::g_debugging = *p; if (args.send_metrics.has_value() && !Metrics::g_metrics.lock()->metrics_enabled()) @@ -248,6 +251,8 @@ int main(const int argc, const char* const* const argv) "Warning: passed either --printmetrics or --no-printmetrics, but metrics are disabled.\n"); } + args.track_feature_flag_metrics(); + if (Debug::g_debugging) { inner(fs, args); diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 74ad046ae8..1ec9a19e4a 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -10,6 +10,7 @@ #if !defined(_WIN32) #include +#include #include #endif @@ -839,6 +840,97 @@ namespace vcpkg::Files fs::stdfs::current_path(path, ec); } + virtual fs::SystemHandle try_take_exclusive_file_lock(const fs::path& path, std::error_code& ec) override + { + fs::SystemHandle res; + + const auto system_file_name = path.native(); +#if defined(WIN32) + constexpr static auto busy_error = ERROR_BUSY; + const auto system_try_take_file_lock = [&] { + auto handle = CreateFileW( + system_file_name.c_str(), + GENERIC_READ, + 0 /* no sharing */, + nullptr /* no security attributes */, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + nullptr /* no template file */); + if (handle == INVALID_HANDLE_VALUE) + { + const auto err = GetLastError(); + if (err != ERROR_SHARING_VIOLATION) + { + ec.assign(err, std::system_category()); + } + return false; + } + + res.system_handle = reinterpret_cast(handle); + return true; + }; +#else // ^^^ WIN32 / !WIN32 vvv + constexpr static auto busy_error = EBUSY; + int fd = open(system_file_name.c_str(), 0); + if (fd < 0) + { + ec.assign(errno, std::system_category()); + return res; + } + const auto system_try_take_file_lock = [&] { + if (flock(fd, LOCK_EX | LOCK_NB) != 0) + { + if (errno != EWOULDBLOCK) + { + ec.assign(errno, std::system_category()); + } + return false; + } + + res.system_handle = fd; + return true; + }; +#endif + + if (system_try_take_file_lock() || ec) + { + return res; + } + + System::printf("Waiting to take filesystem lock on %s...\n", path.u8string()); + auto wait = std::chrono::milliseconds(100); + // waits, at most, a second and a half. + while (wait < std::chrono::milliseconds(1000)) + { + std::this_thread::sleep_for(wait); + if (system_try_take_file_lock() || ec) + { + return res; + } + wait *= 2; + } + +#if !defined(WIN32) + close(fd); +#endif + ec.assign(busy_error, std::system_category()); + return res; + } + virtual void unlock_file_lock(fs::SystemHandle handle, std::error_code& ec) override + { +#if defined(WIN32) + if (CloseHandle(reinterpret_cast(handle.system_handle)) == 0) + { + ec.assign(GetLastError(), std::system_category()); + } +#else + if (flock(handle.system_handle, LOCK_UN) != 0 || close(handle.system_handle) != 0) + { + ec.assign(errno, std::system_category()); + } +#endif + } + virtual std::vector find_from_PATH(const std::string& name) const override { #if defined(_WIN32) diff --git a/toolsrc/src/vcpkg/base/json.cpp b/toolsrc/src/vcpkg/base/json.cpp index 3d6bfc1d2f..0972915eba 100644 --- a/toolsrc/src/vcpkg/base/json.cpp +++ b/toolsrc/src/vcpkg/base/json.cpp @@ -144,27 +144,35 @@ namespace vcpkg::Json return underlying_->string; } - const Array& Value::array() const noexcept + const Array& Value::array() const& noexcept { vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array()); return underlying_->array; } - Array& Value::array() noexcept + Array& Value::array() & noexcept { vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_array()); return underlying_->array; } + Array&& Value::array() && noexcept + { + return std::move(this->array()); + } - const Object& Value::object() const noexcept + const Object& Value::object() const& noexcept { vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object()); return underlying_->object; } - Object& Value::object() noexcept + Object& Value::object() & noexcept { vcpkg::Checks::check_exit(VCPKG_LINE_INFO, is_object()); return underlying_->object; } + Object&& Value::object() && noexcept + { + return std::move(this->object()); + } Value::Value() noexcept = default; Value::Value(Value&&) noexcept = default; @@ -601,35 +609,39 @@ namespace vcpkg::Json } } -#ifdef _MSC_VER -#define SCANF sscanf_s -#else -#define SCANF sscanf -#endif - - // TODO: switch to `from_chars` once we are able to remove support for old compilers if (floating) { - double res; - if (SCANF(number_to_parse.c_str(), "%lf", &res) != 1) + auto opt = Strings::strto(number_to_parse); + if (auto res = opt.get()) + { + if (std::abs(*res) < INFINITY) + { + return Value::number(*res); + } + else + { + add_error(Strings::format("Floating point constant too big: %s", number_to_parse)); + } + } + else { add_error(Strings::format("Invalid floating point constant: %s", number_to_parse)); - return Value(); } - return Value::number(res); } else { - int64_t res; - if (SCANF(number_to_parse.c_str(), "%" SCNd64, &res) != 1) + auto opt = Strings::strto(number_to_parse); + if (auto res = opt.get()) + { + return Value::integer(*res); + } + else { add_error(Strings::format("Invalid integer constant: %s", number_to_parse)); - return Value(); } - return Value::integer(res); } -#undef SCANF + return Value(); } Value parse_keyword() noexcept @@ -960,12 +972,15 @@ namespace vcpkg::Json for (auto code_point : Unicode::Utf8Decoder(sv.begin(), sv.end())) { // a. If C is listed in the "Code Point" column of Table 66, then - const auto match = std::find_if(begin(escape_sequences), end(escape_sequences), [code_point](const std::pair& attempt) { - return attempt.first == code_point; - }); + const auto match = std::find_if(begin(escape_sequences), + end(escape_sequences), + [code_point](const std::pair& attempt) { + return attempt.first == code_point; + }); // i. Set product to the string-concatenation of product and the escape sequence for C as // specified in the "Escape Sequence" column of the corresponding row. - if (match != end(escape_sequences)) { + if (match != end(escape_sequences)) + { buffer.append(match->second); continue; } @@ -1086,18 +1101,21 @@ namespace vcpkg::Json { std::string res; Stringifier{style, res}.stringify(value, 0); + res.push_back('\n'); return res; } std::string stringify(const Object& obj, JsonStyle style) { std::string res; Stringifier{style, res}.stringify_object(obj, 0); + res.push_back('\n'); return res; } std::string stringify(const Array& arr, JsonStyle style) { std::string res; Stringifier{style, res}.stringify_array(arr, 0); + res.push_back('\n'); return res; } // } auto stringify() diff --git a/toolsrc/src/vcpkg/base/parse.cpp b/toolsrc/src/vcpkg/base/parse.cpp index 0d2c5f8fc3..8e6b767d79 100644 --- a/toolsrc/src/vcpkg/base/parse.cpp +++ b/toolsrc/src/vcpkg/base/parse.cpp @@ -144,6 +144,13 @@ namespace vcpkg::Parse optional_field(fieldname, {out, ignore}); return out; } + std::string ParagraphParser::required_field(const std::string& fieldname) + { + std::string out; + TextRowCol ignore; + optional_field(fieldname, {out, ignore}); + return out; + } std::unique_ptr ParagraphParser::error_info(const std::string& name) const { @@ -151,8 +158,9 @@ namespace vcpkg::Parse { auto err = std::make_unique(); err->name = name; - err->extra_fields = Util::extract_keys(fields); - err->missing_fields = std::move(missing_fields); + err->extra_fields["CONTROL"] = Util::extract_keys(fields); + err->missing_fields["CONTROL"] = std::move(missing_fields); + err->expected_types = std::move(expected_types); return err; } return nullptr; @@ -214,7 +222,7 @@ namespace vcpkg::Parse parser.add_error("triplet specifier not allowed in this context", loc); return nullopt; } - return Dependency{{pqs.name, pqs.features.value_or({})}, pqs.qualifier.value_or({})}; + return Dependency{pqs.name, pqs.features.value_or({}), pqs.platform.value_or({})}; }); }); if (!opt) return {parser.get_error()->format(), expected_right_tag}; diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index e267d68643..44fc3ebd11 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -10,10 +10,9 @@ namespace vcpkg::Strings::details static bool is_space(const char c) { return std::isspace(static_cast(c)) != 0; } // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() - static char tolower_char(const char c) { return (c < 'A' || c > 'Z') ? c : c - 'A' + 'a'; } static char toupper_char(const char c) { return (c < 'a' || c > 'z') ? c : c - 'a' + 'A'; } - static bool icase_eq(char a, char b) { return tolower_char(a) == tolower_char(b); } + static bool icase_eq(char a, char b) { return tolower_char{}(a) == tolower_char{}(b); } #if defined(_WIN32) static _locale_t& c_locale() @@ -102,7 +101,7 @@ bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) std::string Strings::ascii_to_lowercase(std::string&& s) { - std::transform(s.begin(), s.end(), s.begin(), &details::tolower_char); + Strings::ascii_to_lowercase(s.begin(), s.end()); return std::move(s); } @@ -157,7 +156,7 @@ void Strings::trim_all_and_remove_whitespace_strings(std::vector* s Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); } -std::vector Strings::split(const std::string& s, const char delimiter) +std::vector Strings::split(StringView s, const char delimiter) { std::vector output; auto first = s.begin(); diff --git a/toolsrc/src/vcpkg/base/stringview.cpp b/toolsrc/src/vcpkg/base/stringview.cpp index 6b159db482..326b0219ce 100644 --- a/toolsrc/src/vcpkg/base/stringview.cpp +++ b/toolsrc/src/vcpkg/base/stringview.cpp @@ -71,7 +71,7 @@ namespace vcpkg return result.front(); } - StringView::StringView(const std::string& s) : m_ptr(s.data()), m_size(s.size()) {} + StringView::StringView(const std::string& s) : m_ptr(s.data()), m_size(s.size()) { } std::string StringView::to_string() const { return std::string(m_ptr, m_size); } void StringView::to_string(std::string& s) const { s.append(m_ptr, m_size); } @@ -82,4 +82,13 @@ namespace vcpkg } bool operator!=(StringView lhs, StringView rhs) noexcept { return !(lhs == rhs); } + + bool operator<(StringView lhs, StringView rhs) noexcept + { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + bool operator>(StringView lhs, StringView rhs) noexcept { return rhs < lhs; } + bool operator<=(StringView lhs, StringView rhs) noexcept { return !(rhs < lhs); } + bool operator>=(StringView lhs, StringView rhs) noexcept { return !(lhs < rhs); } } diff --git a/toolsrc/src/vcpkg/binarycaching.cpp b/toolsrc/src/vcpkg/binarycaching.cpp index 13dd920c6b..5bebc4fb86 100644 --- a/toolsrc/src/vcpkg/binarycaching.cpp +++ b/toolsrc/src/vcpkg/binarycaching.cpp @@ -1048,7 +1048,7 @@ std::string vcpkg::generate_nuspec(const VcpkgPaths& paths, auto& version = scf.core_paragraph->version; std::string description = Strings::concat("NOT FOR DIRECT USE. Automatically generated cache package.\n\n", - scf.core_paragraph->description, + Strings::join("\n ", scf.core_paragraph->description), "\n\nVersion: ", version, "\nTriplet/Compiler hash: ", diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp index 305ae2ae90..0b0819fd71 100644 --- a/toolsrc/src/vcpkg/binaryparagraph.cpp +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace vcpkg { @@ -13,6 +14,7 @@ namespace vcpkg { static const std::string PACKAGE = "Package"; static const std::string VERSION = "Version"; + static const std::string PORT_VERSION = "Port-Version"; static const std::string ARCHITECTURE = "Architecture"; static const std::string MULTI_ARCH = "Multi-Arch"; } @@ -24,7 +26,7 @@ namespace vcpkg static const std::string DESCRIPTION = "Description"; static const std::string MAINTAINER = "Maintainer"; static const std::string DEPENDS = "Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string DEFAULT_FEATURES = "Default-Features"; static const std::string TYPE = "Type"; } @@ -48,15 +50,38 @@ namespace vcpkg this->version = parser.optional_field(Fields::VERSION); this->feature = parser.optional_field(Fields::FEATURE); - this->description = parser.optional_field(Fields::DESCRIPTION); - this->maintainer = parser.optional_field(Fields::MAINTAINER); + auto pv_str = parser.optional_field(Fields::PORT_VERSION); + this->port_version = 0; + if (!pv_str.empty()) + { + auto pv_opt = Strings::strto(pv_str); + if (auto pv = pv_opt.get()) + { + this->port_version = *pv; + } + else + { + parser.add_type_error(Fields::PORT_VERSION, "a non-negative integer"); + } + } + + this->description = Strings::split(parser.optional_field(Fields::DESCRIPTION), '\n'); + for (auto& desc : this->description) + { + desc = Strings::trim(std::move(desc)); + } + this->maintainers = Strings::split(parser.optional_field(Fields::MAINTAINER), '\n'); + for (auto& maintainer : this->maintainers) + { + maintainer = Strings::trim(std::move(maintainer)); + } this->abi = parser.optional_field(Fields::ABI); std::string multi_arch; parser.required_field(Fields::MULTI_ARCH, multi_arch); - this->depends = Util::fmap( + this->dependencies = Util::fmap( parse_qualified_specifier_list(parser.optional_field(Fields::DEPENDS)).value_or_exit(VCPKG_LINE_INFO), [](const ParsedQualifiedSpecifier& dep) { // for compatibility with previous vcpkg versions, we discard all irrelevant information @@ -64,7 +89,7 @@ namespace vcpkg }); if (!this->is_feature()) { - this->default_features = parse_default_features_list(parser.optional_field(Fields::DEFAULTFEATURES)) + this->default_features = parse_default_features_list(parser.optional_field(Fields::DEFAULT_FEATURES)) .value_or_exit(VCPKG_LINE_INFO); } @@ -87,16 +112,17 @@ namespace vcpkg const std::vector& deps) : spec(spgh.name, triplet) , version(spgh.version) + , port_version(spgh.port_version) , description(spgh.description) - , maintainer(spgh.maintainer) + , maintainers(spgh.maintainers) , feature() , default_features(spgh.default_features) - , depends() + , dependencies() , abi(abi_tag) , type(spgh.type) { - this->depends = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); }); - Util::sort_unique_erase(this->depends); + this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); }); + Util::sort_unique_erase(this->dependencies); } BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, @@ -105,16 +131,17 @@ namespace vcpkg const std ::vector& deps) : spec(spgh.name, triplet) , version() + , port_version() , description(fpgh.description) - , maintainer() + , maintainers() , feature(fpgh.name) , default_features() - , depends() + , dependencies() , abi() , type(spgh.type) { - this->depends = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); }); - Util::sort_unique_erase(this->depends); + this->dependencies = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.spec().name(); }); + Util::sort_unique_erase(this->dependencies); } std::string BinaryParagraph::displayname() const @@ -131,29 +158,157 @@ namespace vcpkg return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet()); } - void serialize(const BinaryParagraph& pgh, std::string& out_str) + bool operator==(const BinaryParagraph& lhs, const BinaryParagraph& rhs) { - out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); - if (!pgh.version.empty()) - out_str.append("Version: ").append(pgh.version).push_back('\n'); - else if (pgh.is_feature()) - out_str.append("Feature: ").append(pgh.feature).push_back('\n'); - if (!pgh.depends.empty()) + if (lhs.spec != rhs.spec) return false; + if (lhs.version != rhs.version) return false; + if (lhs.port_version != rhs.port_version) return false; + if (lhs.description != rhs.description) return false; + if (lhs.maintainers != rhs.maintainers) return false; + if (lhs.feature != rhs.feature) return false; + if (lhs.default_features != rhs.default_features) return false; + if (lhs.dependencies != rhs.dependencies) return false; + if (lhs.abi != rhs.abi) return false; + if (lhs.type != rhs.type) return false; + + return true; + } + + bool operator!=(const BinaryParagraph& lhs, const BinaryParagraph& rhs) { return !(lhs == rhs); } + + static void serialize_string(StringView name, const std::string& field, std::string& out_str) + { + if (field.empty()) { - out_str.append("Depends: "); - out_str.append(Strings::join(", ", pgh.depends)); - out_str.push_back('\n'); + return; } - out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n'); - out_str.append("Multi-Arch: same\n"); + out_str.append(name.begin(), name.end()).append(": ").append(field).push_back('\n'); + } + static void serialize_array(StringView name, + const std::vector& array, + std::string& out_str, + const char* joiner = ", ") + { + if (array.empty()) + { + return; + } - if (!pgh.maintainer.empty()) out_str.append("Maintainer: ").append(pgh.maintainer).push_back('\n'); - if (!pgh.abi.empty()) out_str.append("Abi: ").append(pgh.abi).push_back('\n'); - if (!pgh.description.empty()) out_str.append("Description: ").append(pgh.description).push_back('\n'); + out_str.append(name.begin(), name.end()).append(": "); + out_str.append(Strings::join(joiner, array)); + out_str.push_back('\n'); + } + static void serialize_paragraph(StringView name, const std::vector& array, std::string& out_str) + { + serialize_array(name, array, out_str, "\n "); + } - out_str.append("Type: ").append(Type::to_string(pgh.type)).push_back('\n'); - if (!pgh.default_features.empty()) - out_str.append("Default-Features: ").append(Strings::join(", ", pgh.default_features)).push_back('\n'); + void serialize(const BinaryParagraph& pgh, std::string& out_str) + { + const size_t initial_end = out_str.size(); + + serialize_string(Fields::PACKAGE, pgh.spec.name(), out_str); + + serialize_string(Fields::VERSION, pgh.version, out_str); + if (pgh.port_version != 0) + { + out_str.append(Fields::PORT_VERSION).append(": ").append(std::to_string(pgh.port_version)).push_back('\n'); + } + + if (pgh.is_feature()) + { + serialize_string(Fields::FEATURE, pgh.feature, out_str); + } + + if (!pgh.dependencies.empty()) + { + serialize_array(Fields::DEPENDS, pgh.dependencies, out_str); + } + + serialize_string(Fields::ARCHITECTURE, pgh.spec.triplet().to_string(), out_str); + serialize_string(Fields::MULTI_ARCH, "same", out_str); + + serialize_paragraph(Fields::MAINTAINER, pgh.maintainers, out_str); + + serialize_string(Fields::ABI, pgh.abi, out_str); + + serialize_paragraph(Fields::DESCRIPTION, pgh.description, out_str); + + serialize_string(Fields::TYPE, Type::to_string(pgh.type), out_str); + serialize_array(Fields::DEFAULT_FEATURES, pgh.default_features, out_str); + + // sanity check the serialized data + const auto my_paragraph = out_str.substr(initial_end); + auto parsed_paragraph = Paragraphs::parse_single_paragraph( + out_str.substr(initial_end), "vcpkg::serialize(const BinaryParagraph&, std::string&)"); + if (!parsed_paragraph.has_value()) + { + Checks::exit_with_message(VCPKG_LINE_INFO, + R"([sanity check] Failed to parse a serialized binary paragraph. +Please open an issue at https://github.com/microsoft/vcpkg, with the following output: + Error: %s + +=== Serialized BinaryParagraph === +%s + )", + parsed_paragraph.error(), + my_paragraph); + } + + auto binary_paragraph = BinaryParagraph(*parsed_paragraph.get()); + if (binary_paragraph != pgh) + { + const auto& join_str = R"(", ")"; + Checks::exit_with_message( + VCPKG_LINE_INFO, + R"([sanity check] The serialized binary paragraph was different from the original binary paragraph. +Please open an issue at https://github.com/microsoft/vcpkg, with the following output: + +=== Original BinaryParagraph === +spec: "%s" +version: "%s" +port_version: %d +description: ["%s"] +maintainers: ["%s"] +feature: "%s" +default_features: ["%s"] +dependencies: ["%s"] +abi: "%s" +type: %s + +=== Serialized BinaryParagraph === +spec: "%s" +version: "%s" +port_version: %d +description: ["%s"] +maintainers: ["%s"] +feature: "%s" +default_features: ["%s"] +dependencies: ["%s"] +abi: "%s" +type: %s +)", + pgh.spec.to_string(), + pgh.version, + pgh.port_version, + Strings::join(join_str, pgh.description), + Strings::join(join_str, pgh.maintainers), + pgh.feature, + Strings::join(join_str, pgh.default_features), + Strings::join(join_str, pgh.dependencies), + pgh.abi, + Type::to_string(pgh.type), + binary_paragraph.spec.to_string(), + binary_paragraph.version, + binary_paragraph.port_version, + Strings::join(join_str, binary_paragraph.description), + Strings::join(join_str, binary_paragraph.maintainers), + binary_paragraph.feature, + Strings::join(join_str, binary_paragraph.default_features), + Strings::join(join_str, binary_paragraph.dependencies), + binary_paragraph.abi, + Type::to_string(binary_paragraph.type)); + } } } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7a74f3e83f..5e2f8778b7 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -153,14 +153,14 @@ namespace vcpkg::Build std::string first_arg = args.command_arguments.at(0); auto binaryprovider = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); const FullPackageSpec spec = Input::check_and_get_full_package_spec( std::move(first_arg), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); - PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PathsPortFileProvider provider(paths, args.overlay_ports); const auto port_name = spec.package_spec.name(); const auto* scfl = provider.get_control_file(port_name).get(); diff --git a/toolsrc/src/vcpkg/buildenvironment.cpp b/toolsrc/src/vcpkg/buildenvironment.cpp index ea3be7bc80..be61ba37cc 100644 --- a/toolsrc/src/vcpkg/buildenvironment.cpp +++ b/toolsrc/src/vcpkg/buildenvironment.cpp @@ -14,6 +14,7 @@ namespace vcpkg local_variables.emplace_back("BUILDTREES_DIR", paths.buildtrees); local_variables.emplace_back("_VCPKG_INSTALLED_DIR", paths.installed); local_variables.emplace_back("DOWNLOADS", paths.downloads); + local_variables.emplace_back("VCPKG_MANIFEST_INSTALL", "OFF"); return System::make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE), cmake_script, local_variables); } } diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index b25b5e4bf2..5609e28f8c 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -22,16 +22,16 @@ namespace vcpkg::Commands::BuildExternal const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); auto binaryprovider = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); const FullPackageSpec spec = Input::check_and_get_full_package_spec( std::string(args.command_arguments.at(0)), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); - auto overlays = args.overlay_ports ? *args.overlay_ports : std::vector(); + auto overlays = args.overlay_ports; overlays.insert(overlays.begin(), args.command_arguments.at(1)); - PortFileProvider::PathsPortFileProvider provider(paths, &overlays); + PortFileProvider::PathsPortFileProvider provider(paths, overlays); auto maybe_scfl = provider.get_control_file(spec.package_spec.name()); Checks::check_exit( diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index efc7bbc154..df69d2e128 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -171,7 +171,7 @@ namespace vcpkg::Commands::CI } std::string traits_block; - if (test.abi_tag != "") + if (!test.abi_tag.empty()) { traits_block += Strings::format(R"()", test.abi_tag); } @@ -226,26 +226,11 @@ namespace vcpkg::Commands::CI const InstallPlanAction* install_plan) { auto&& scfl = install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO); - const std::string& supports_expression = scfl.source_control_file->core_paragraph->supports_expression; - if (supports_expression.empty()) - { - return true; // default to 'supported' - } + const auto& supports_expression = scfl.source_control_file->core_paragraph->supports_expression; + PlatformExpression::Context context = + var_provider.get_tag_vars(install_plan->spec).value_or_exit(VCPKG_LINE_INFO); - ExpressionContext context = {var_provider.get_tag_vars(install_plan->spec).value_or_exit(VCPKG_LINE_INFO), - install_plan->spec.triplet().canonical_name()}; - auto maybe_result = evaluate_expression(supports_expression, context); - if (auto b = maybe_result.get()) - return *b; - else - { - System::print2(System::Color::error, - "Error: while processing ", - install_plan->spec.to_string(), - "\n", - maybe_result.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } + return supports_expression.evaluate(context); } static std::unique_ptr find_unknown_ports_for_ci( @@ -272,13 +257,13 @@ namespace vcpkg::Commands::CI }; std::vector packages_with_qualified_deps; - auto has_qualifier = [](Dependency const& dep) { return !dep.qualifier.empty(); }; + auto has_qualifier = [](Dependency const& dep) { return !dep.platform.is_empty(); }; for (auto&& spec : specs) { auto&& scfl = provider.get_control_file(spec.package_spec.name()).value_or_exit(VCPKG_LINE_INFO); - if (Util::any_of(scfl.source_control_file->core_paragraph->depends, has_qualifier) || + if (Util::any_of(scfl.source_control_file->core_paragraph->dependencies, has_qualifier) || Util::any_of(scfl.source_control_file->feature_paragraphs, - [&](auto&& pgh) { return Util::any_of(pgh->depends, has_qualifier); })) + [&](auto&& pgh) { return Util::any_of(pgh->dependencies, has_qualifier); })) { packages_with_qualified_deps.push_back(spec.package_spec); } @@ -385,7 +370,7 @@ namespace vcpkg::Commands::CI if (args.binary_caching_enabled()) { binaryproviderStorage = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); } IBinaryProvider& binaryprovider = binaryproviderStorage ? *binaryproviderStorage : null_binary_provider(); @@ -412,7 +397,7 @@ namespace vcpkg::Commands::CI StatusParagraphs status_db = database_load_check(paths); - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index f09f5e4f88..be6d553047 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -42,7 +42,6 @@ namespace vcpkg::Commands {"update", &Update::perform_and_exit}, {"edit", &Edit::perform_and_exit}, {"create", &Create::perform_and_exit}, - {"import", &Import::perform_and_exit}, {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, {"autocomplete", &Autocomplete::perform_and_exit}, @@ -51,6 +50,7 @@ namespace vcpkg::Commands {"x-ci-clean", &CIClean::perform_and_exit}, {"x-history", &PortHistory::perform_and_exit}, {"x-vsinstances", &X_VSInstances::perform_and_exit}, + {"x-format-manifest", &FormatManifest::perform_and_exit}, }; return t; } @@ -89,8 +89,7 @@ namespace vcpkg::Commands::Fetch namespace vcpkg::Commands::Hash { const CommandStructure COMMAND_STRUCTURE = { - Strings::format("The argument should be a file path\n%s", - create_example_string("hash boost_1_62_0.tar.bz2")), + Strings::format("The argument should be a file path\n%s", create_example_string("hash boost_1_62_0.tar.bz2")), 1, 2, {}, diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 32f467d414..c78c694f63 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -251,7 +251,7 @@ namespace vcpkg::Commands::DependInfo Input::check_triplet(spec.package_spec.triplet(), paths); } - PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PathsPortFileProvider provider(paths, args.overlay_ports); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index b361d6ff11..8cf264d173 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -39,7 +39,7 @@ namespace vcpkg::Commands::Env const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index db0987512d..ede5240392 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -94,7 +94,7 @@ namespace vcpkg::Export::IFW package_xml_file_path.generic_u8string()); auto deps = Strings::join( - ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + ",", binary_paragraph.dependencies, [](const std::string& dep) { return "packages." + dep + ":"; }); if (!deps.empty()) deps = "\n " + deps + ""; @@ -175,7 +175,7 @@ namespace vcpkg::Export::IFW )###", action.spec.name(), - safe_rich_from_plain_text(binary_paragraph.description), + safe_rich_from_plain_text(Strings::join("\n", binary_paragraph.description)), binary_paragraph.version, create_release_date()), VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.format-manifest.cpp b/toolsrc/src/vcpkg/commands.format-manifest.cpp new file mode 100644 index 0000000000..62e03dbcf1 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.format-manifest.cpp @@ -0,0 +1,100 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::FormatManifest +{ + + static constexpr StringLiteral OPTION_ALL = "--all"; + + const CommandSwitch FORMAT_SWITCHES[] = { + { OPTION_ALL, "Format all ports' manifest files." } + }; + + const CommandStructure COMMAND_STRUCTURE = { + create_example_string(R"###(x-format-manifest --all)###"), + 0, + SIZE_MAX, + { + FORMAT_SWITCHES, + {}, + {} + }, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE); + + std::vector files_to_format; + + auto& fs = paths.get_filesystem(); + bool has_error = false; + + if (Util::Sets::contains(parsed_args.switches, OPTION_ALL)) + { + for (const auto& dir : fs::directory_iterator(paths.ports)) + { + auto manifest_path = dir.path() / fs::u8path("vcpkg.json"); + if (fs.exists(manifest_path)) + { + files_to_format.push_back(std::move(manifest_path)); + } + } + } + + for (const auto& arg : args.command_arguments) + { + auto path = fs::u8path(arg); + if (path.is_relative()) + { + path = paths.original_cwd / path; + } + files_to_format.push_back(std::move(path)); + } + + for (const auto& path : files_to_format) + { + std::error_code ec; + Debug::print("Formatting ", path.u8string(), "\n"); + auto parsed_json_opt = Json::parse_file(fs, path, ec); + if (ec) + { + System::printf(System::Color::error, "Failed to read %s: %s\n", path.u8string(), ec.message()); + has_error = true; + } + + if (auto pr = parsed_json_opt.get()) + { + fs.write_contents(path, Json::stringify(pr->first, Json::JsonStyle{}), ec); + } + else + { + System::printf(System::Color::error, "Failed to parse %s: %s\n", path.u8string(), parsed_json_opt.error()->format()); + has_error = true; + } + + if (ec) + { + System::printf(System::Color::error, "Failed to write %s: %s\n", path.u8string(), ec.message()); + has_error = true; + } + } + + if (has_error) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + else + { + System::print2("Succeeded in formatting the manifest files.\n"); + Checks::exit_success(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp deleted file mode 100644 index 9d8e4b4b1d..0000000000 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "pch.h" - -#include -#include -#include -#include -#include - -namespace vcpkg::Commands::Import -{ - struct Binaries - { - std::vector dlls; - std::vector libs; - }; - - static void check_is_directory(const LineInfo& line_info, const Files::Filesystem& fs, const fs::path& dirpath) - { - Checks::check_exit(line_info, fs.is_directory(dirpath), "The path %s is not a directory", dirpath.string()); - } - - static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) - { - auto files = fs.get_files_recursive(path); - - check_is_directory(VCPKG_LINE_INFO, fs, path); - - Binaries binaries; - for (auto&& file : files) - { - if (fs.is_directory(file)) continue; - const auto ext = file.extension(); - if (ext == ".dll") - binaries.dlls.push_back(std::move(file)); - else if (ext == ".lib") - binaries.libs.push_back(std::move(file)); - } - return binaries; - } - - static void copy_files_into_directory(Files::Filesystem& fs, - const std::vector& files, - const fs::path& destination_folder) - { - std::error_code ec; - fs.create_directory(destination_folder, ec); - - for (auto const& src_path : files) - { - const fs::path dest_path = destination_folder / src_path.filename(); - fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); - } - } - - static void place_library_files_in(Files::Filesystem& fs, - const fs::path& include_directory, - const fs::path& project_directory, - const fs::path& destination_path) - { - check_is_directory(VCPKG_LINE_INFO, fs, include_directory); - check_is_directory(VCPKG_LINE_INFO, fs, project_directory); - check_is_directory(VCPKG_LINE_INFO, fs, destination_path); - const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); - const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); - - const fs::path destination_include_directory = destination_path / "include"; - fs.copy(include_directory, - destination_include_directory, - fs::copy_options::recursive | fs::copy_options::overwrite_existing); - - copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); - copy_files_into_directory(fs, release_binaries.libs, destination_path / "lib"); - - std::error_code ec; - fs.create_directory(destination_path / "debug", ec); - copy_files_into_directory(fs, debug_binaries.dlls, destination_path / "debug" / "bin"); - copy_files_into_directory(fs, debug_binaries.libs, destination_path / "debug" / "lib"); - } - - static void do_import(const VcpkgPaths& paths, - const fs::path& include_directory, - const fs::path& project_directory, - const BinaryParagraph& control_file_data) - { - auto& fs = paths.get_filesystem(); - const fs::path library_destination_path = paths.package_dir(control_file_data.spec); - std::error_code ec; - fs.create_directory(library_destination_path, ec); - place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path); - - const fs::path control_file_path = library_destination_path / "CONTROL"; - fs.write_contents(control_file_path, Strings::serialize(control_file_data), VCPKG_LINE_INFO); - } - - const CommandStructure COMMAND_STRUCTURE = { - create_example_string(R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"), - 3, - 3, - {}, - nullptr, - }; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); - - const fs::path control_file_path(args.command_arguments[0]); - const fs::path include_directory(args.command_arguments[1]); - const fs::path project_directory(args.command_arguments[2]); - - const auto pghs = Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path); - Checks::check_exit(VCPKG_LINE_INFO, - pghs.get() != nullptr, - "Invalid control file %s for package", - control_file_path.generic_u8string(), - "\n", - pghs.error()); - - StatusParagraph spgh; - spgh.package = BinaryParagraph(*pghs.get()); - auto& control_file_data = spgh.package; - - do_import(paths, include_directory, project_directory, control_file_data); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp index c837dc395d..e95b02623b 100644 --- a/toolsrc/src/vcpkg/commands.list.cpp +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -14,14 +14,22 @@ namespace vcpkg::Commands::List { if (full_desc) { - System::printf("%-50s %-16s %s\n", pgh.package.displayname(), pgh.package.version, pgh.package.description); + System::printf("%-50s %-16s %s\n", + pgh.package.displayname(), + pgh.package.version, + Strings::join("\n ", pgh.package.description)); } else { + std::string description; + if (!pgh.package.description.empty()) + { + description = pgh.package.description[0]; + } System::printf("%-50s %-16s %s\n", vcpkg::shorten_text(pgh.package.displayname(), 50), vcpkg::shorten_text(pgh.package.version, 16), - vcpkg::shorten_text(pgh.package.description, 51)); + vcpkg::shorten_text(description, 51)); } } diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index ebaa3ce43f..c234c3ab96 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -20,15 +20,22 @@ namespace vcpkg::Commands::Search { if (full_desc) { - System::printf( - "%-20s %-16s %s\n", source_paragraph.name, source_paragraph.version, source_paragraph.description); + System::printf("%-20s %-16s %s\n", + source_paragraph.name, + source_paragraph.version, + Strings::join("\n ", source_paragraph.description)); } else { + std::string description; + if (!source_paragraph.description.empty()) + { + description = source_paragraph.description[0]; + } System::printf("%-20s %-16s %s\n", vcpkg::shorten_text(source_paragraph.name, 20), vcpkg::shorten_text(source_paragraph.version, 16), - vcpkg::shorten_text(source_paragraph.description, 81)); + vcpkg::shorten_text(description, 81)); } } @@ -37,13 +44,17 @@ namespace vcpkg::Commands::Search auto full_feature_name = Strings::concat(name, "[", feature_paragraph.name, "]"); if (full_desc) { - System::printf("%-37s %s\n", full_feature_name, feature_paragraph.description); + System::printf("%-37s %s\n", full_feature_name, Strings::join("\n ", feature_paragraph.description)); } else { - System::printf("%-37s %s\n", - vcpkg::shorten_text(full_feature_name, 37), - vcpkg::shorten_text(feature_paragraph.description, 81)); + std::string description; + if (!feature_paragraph.description.empty()) + { + description = feature_paragraph.description[0]; + } + System::printf( + "%-37s %s\n", vcpkg::shorten_text(full_feature_name, 37), vcpkg::shorten_text(description, 81)); } } @@ -66,7 +77,7 @@ namespace vcpkg::Commands::Search const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC); - PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PathsPortFileProvider provider(paths, args.overlay_ports); auto source_paragraphs = Util::fmap(provider.load_all_control_files(), [](auto&& port) -> const SourceControlFile* { return port->source_control_file.get(); }); @@ -84,24 +95,40 @@ namespace vcpkg::Commands::Search } else { - const auto& icontains = Strings::case_insensitive_ascii_contains; - // At this point there is 1 argument auto&& args_zero = args.command_arguments[0]; + const auto contained_in = [&args_zero](const auto& s) { + return Strings::case_insensitive_ascii_contains(s, args_zero); + }; for (const auto& source_control_file : source_paragraphs) { auto&& sp = *source_control_file->core_paragraph; - const bool contains_name = icontains(sp.name, args_zero); - if (contains_name || icontains(sp.description, args_zero)) + bool found_match = contained_in(sp.name); + if (!found_match) + { + found_match = std::any_of(sp.description.begin(), sp.description.end(), contained_in); + } + + if (found_match) { do_print(sp, full_description); } for (auto&& feature_paragraph : source_control_file->feature_paragraphs) { - if (contains_name || icontains(feature_paragraph->name, args_zero) || - icontains(feature_paragraph->description, args_zero)) + bool found_match_for_feature = found_match; + if (!found_match_for_feature) + { + found_match_for_feature = contained_in(feature_paragraph->name); + } + if (!found_match_for_feature) + { + found_match_for_feature = std::any_of( + feature_paragraph->description.begin(), feature_paragraph->description.end(), contained_in); + } + + if (found_match_for_feature) { do_print(sp.name, *feature_paragraph, full_description); } diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp index 5a473b4eeb..f52e4942b7 100644 --- a/toolsrc/src/vcpkg/commands.setinstalled.cpp +++ b/toolsrc/src/vcpkg/commands.setinstalled.cpp @@ -27,52 +27,27 @@ namespace vcpkg::Commands::SetInstalled nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) + void perform_and_exit_ex(const VcpkgCmdArguments& args, + const VcpkgPaths& paths, + const PortFileProvider::PathsPortFileProvider& provider, + IBinaryProvider& binary_provider, + const CMakeVars::CMakeVarProvider& cmake_vars, + const std::vector& specs, + const Build::BuildPackageOptions& install_plan_options, + DryRun dry_run) { - // input sanitization - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec( - std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); - }); - - for (auto&& spec : specs) - { - Input::check_triplet(spec.package_spec.triplet(), paths); - } - - auto binaryprovider = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); - - const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); - - const Build::BuildPackageOptions install_plan_options = { - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::OnlyDownloads::NO, - Build::CleanBuildtrees::YES, - Build::CleanPackages::YES, - Build::CleanDownloads::YES, - Build::DownloadTool::BUILT_IN, - Build::FailOnTombstone::NO, - }; - - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); - auto cmake_vars = CMakeVars::make_triplet_cmake_var_provider(paths); - // We have a set of user-requested specs. // We need to know all the specs which are required to fulfill dependencies for those specs. // Therefore, we see what we would install into an empty installed tree, so we can use the existing code. - auto action_plan = Dependencies::create_feature_install_plan(provider, *cmake_vars, specs, {}); + auto action_plan = Dependencies::create_feature_install_plan(provider, cmake_vars, specs, {}); for (auto&& action : action_plan.install_actions) { action.build_options = install_plan_options; } - cmake_vars->load_tag_vars(action_plan, provider); - Build::compute_all_abis(paths, action_plan, *cmake_vars, {}); + cmake_vars.load_tag_vars(action_plan, provider); + Build::compute_all_abis(paths, action_plan, cmake_vars, {}); std::set all_abis; @@ -116,7 +91,7 @@ namespace vcpkg::Commands::SetInstalled Dependencies::print_plan(action_plan, true, paths.ports); - if (dry_run) + if (dry_run == DryRun::Yes) { Checks::exit_success(VCPKG_LINE_INFO); } @@ -125,12 +100,55 @@ namespace vcpkg::Commands::SetInstalled Install::KeepGoing::NO, paths, status_db, - args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(), - *cmake_vars); + args.binary_caching_enabled() ? binary_provider : null_binary_provider(), + cmake_vars); System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); Checks::exit_success(VCPKG_LINE_INFO); } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) + { + // input sanitization + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec( + std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.package_spec.triplet(), paths); + } + + auto binary_provider = + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); + + const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); + + const Build::BuildPackageOptions install_plan_options = { + Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::OnlyDownloads::NO, + Build::CleanBuildtrees::YES, + Build::CleanPackages::YES, + Build::CleanDownloads::YES, + Build::DownloadTool::BUILT_IN, + Build::FailOnTombstone::NO, + }; + + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); + auto cmake_vars = CMakeVars::make_triplet_cmake_var_provider(paths); + + perform_and_exit_ex(args, + paths, + provider, + *binary_provider, + *cmake_vars, + specs, + install_plan_options, + dry_run ? DryRun::Yes : DryRun::No); + } } diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index 919f07e918..89466ab60a 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -43,12 +43,12 @@ namespace vcpkg::Commands::Upgrade const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); auto binaryprovider = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); StatusParagraphs status_db = database_load_check(paths); // Load ports from ports dirs - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 53db3b6d75..ee28343b61 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -53,7 +53,7 @@ namespace vcpkg::Dependencies { } - Cluster(const PackageSpec& spec, const SourceControlFileLocation& scfl) : m_spec(spec), m_scfl(scfl) {} + Cluster(const PackageSpec& spec, const SourceControlFileLocation& scfl) : m_spec(spec), m_scfl(scfl) { } bool has_feature_installed(const std::string& feature) const { @@ -124,12 +124,11 @@ namespace vcpkg::Dependencies bool requires_qualified_resolution = false; for (const Dependency& dep : *qualified_deps) { - if (dep.qualifier.empty()) + if (dep.platform.is_empty()) { - Util::Vectors::append( - &dep_list, - FullPackageSpec({dep.depend.name, m_spec.triplet()}, dep.depend.features) - .to_feature_specs({"default"}, {"default"})); + Util::Vectors::append(&dep_list, + FullPackageSpec({dep.name, m_spec.triplet()}, dep.features) + .to_feature_specs({"default"}, {"default"})); } else { @@ -684,7 +683,7 @@ namespace vcpkg::Dependencies const std::vector* paragraph_depends = nullptr; if (spec.feature() == "core") { - paragraph_depends = &clust.m_scfl.source_control_file->core_paragraph->depends; + paragraph_depends = &clust.m_scfl.source_control_file->core_paragraph->dependencies; } else if (spec.feature() == "default") { @@ -697,12 +696,12 @@ namespace vcpkg::Dependencies "Package %s does not have a %s feature", spec.name(), spec.feature()); - paragraph_depends = &maybe_paragraph.value_or_exit(VCPKG_LINE_INFO).depends; + paragraph_depends = &maybe_paragraph.value_or_exit(VCPKG_LINE_INFO).dependencies; } // And it has at least one qualified dependency if (paragraph_depends && - Util::any_of(*paragraph_depends, [](auto&& dep) { return !dep.qualifier.empty(); })) + Util::any_of(*paragraph_depends, [](auto&& dep) { return !dep.platform.is_empty(); })) { // Add it to the next batch run qualified_dependencies.emplace_back(spec); @@ -795,7 +794,7 @@ namespace vcpkg::Dependencies { struct BaseEdgeProvider : Graphs::AdjacencyProvider { - BaseEdgeProvider(const ClusterGraph& parent) : m_parent(parent) {} + BaseEdgeProvider(const ClusterGraph& parent) : m_parent(parent) { } std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); } const Cluster* load_vertex_data(const PackageSpec& spec) const override diff --git a/toolsrc/src/vcpkg/export.chocolatey.cpp b/toolsrc/src/vcpkg/export.chocolatey.cpp index 8d98a4d3f7..26af98c615 100644 --- a/toolsrc/src/vcpkg/export.chocolatey.cpp +++ b/toolsrc/src/vcpkg/export.chocolatey.cpp @@ -19,7 +19,7 @@ namespace vcpkg::Export::Chocolatey static constexpr auto CONTENT_TEMPLATE = R"()"; std::string nuspec_dependencies; - for (const std::string& depend : binary_paragraph.depends) + for (const std::string& depend : binary_paragraph.dependencies) { auto found = packages_version.find(depend); if (found == packages_version.end()) @@ -68,8 +68,8 @@ namespace vcpkg::Export::Chocolatey Strings::replace_all(std::move(nuspec_file_content), "@PACKAGE_VERSION@", package_version->second); nuspec_file_content = Strings::replace_all( std::move(nuspec_file_content), "@PACKAGE_MAINTAINER@", chocolatey_options.maybe_maintainer.value_or("")); - nuspec_file_content = - Strings::replace_all(std::move(nuspec_file_content), "@PACKAGE_DESCRIPTION@", binary_paragraph.description); + nuspec_file_content = Strings::replace_all( + std::move(nuspec_file_content), "@PACKAGE_DESCRIPTION@", Strings::join("\n", binary_paragraph.description)); nuspec_file_content = Strings::replace_all(std::move(nuspec_file_content), "@EXPORTED_ROOT_DIR@", exported_root_dir); nuspec_file_content = Strings::replace_all(std::move(nuspec_file_content), diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 205fcd31eb..138c03b3f5 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -589,13 +589,17 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) { + if (paths.manifest_mode_enabled()) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "vcpkg export does not support manifest mode, in order to allow for future design considerations. You may use export in classic mode by running vcpkg outside of a manifest-based project."); + } const StatusParagraphs status_db = database_load_check(paths); const auto opts = handle_export_command_arguments(args, default_triplet, status_db); for (auto&& spec : opts.specs) Input::check_triplet(spec.triplet(), paths); // Load ports from ports dirs - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); // create the plan std::vector export_plan = Dependencies::create_export_plan(opts.specs, status_db); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 30c997498d..5750469add 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -84,9 +84,10 @@ namespace vcpkg::Install const std::string filename = file.filename().generic_u8string(); if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename, "CONTROL") || + Strings::case_insensitive_ascii_equals(filename, "vcpkg.json") || Strings::case_insensitive_ascii_equals(filename, "BUILD_INFO"))) { - // Do not copy the control file + // Do not copy the control file or manifest file continue; } @@ -530,6 +531,14 @@ namespace vcpkg::Install &get_all_port_names, }; + const CommandStructure MANIFEST_COMMAND_STRUCTURE = { + create_example_string("install --triplet x64-windows"), + 0, + 0, + {INSTALL_SWITCHES, INSTALL_SETTINGS}, + nullptr, + }; + static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths) { static const std::regex cmake_library_regex(R"(\badd_library\(([^\$\s\)]+)\s)", @@ -645,20 +654,10 @@ namespace vcpkg::Install void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) { // input sanitization - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + const ParsedArguments options = args.parse_arguments(paths.manifest_mode_enabled() ? MANIFEST_COMMAND_STRUCTURE : COMMAND_STRUCTURE); auto binaryprovider = - create_binary_provider_from_configs(paths, args.binarysources).value_or_exit(VCPKG_LINE_INFO); - - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec( - std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); - }); - - for (auto&& spec : specs) - { - Input::check_triplet(spec.package_spec.triplet(), paths); - } + create_binary_provider_from_configs(paths, args.binary_sources).value_or_exit(VCPKG_LINE_INFO); const bool dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); const bool use_head_version = Util::Sets::contains(options.switches, (OPTION_USE_HEAD_VERSION)); @@ -672,10 +671,6 @@ namespace vcpkg::Install auto& fs = paths.get_filesystem(); - // create the plan - System::print2("Computing installation plan...\n"); - StatusParagraphs status_db = database_load_check(paths); - Build::DownloadTool download_tool = Build::DownloadTool::BUILT_IN; if (use_aria2) download_tool = Build::DownloadTool::ARIA2; @@ -690,11 +685,54 @@ namespace vcpkg::Install Build::FailOnTombstone::NO, }; - //// Load ports from ports dirs - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; + if (paths.manifest_mode_enabled()) + { + std::error_code ec; + const auto path_to_manifest = paths.manifest_root_dir / "vcpkg.json"; + auto res = Paragraphs::try_load_manifest(paths.get_filesystem(), "user manifest", path_to_manifest, ec); + + if (ec) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "Failed to load manifest file (%s): %s\n", + path_to_manifest.u8string(), ec.message()); + } + + std::vector specs; + if (auto val = res.get()) + { + for (auto& dep : (*val)->core_paragraph->dependencies) + { + specs.push_back(Input::check_and_get_full_package_spec( + std::move(dep.name), default_triplet, COMMAND_STRUCTURE.example_text)); + } + } + else + { + print_error_message(res.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + Commands::SetInstalled::perform_and_exit_ex(args, paths, provider, *binaryprovider, var_provider, specs, install_plan_options, dry_run ? Commands::DryRun::Yes : Commands::DryRun::No); + } + + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec( + std::string(arg), default_triplet, COMMAND_STRUCTURE.example_text); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.package_spec.triplet(), paths); + } + + // create the plan + System::print2("Computing installation plan...\n"); + StatusParagraphs status_db = database_load_check(paths); + // Note: action_plan will hold raw pointers to SourceControlFileLocations from this map auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db); diff --git a/toolsrc/src/vcpkg/logicexpression.cpp b/toolsrc/src/vcpkg/logicexpression.cpp deleted file mode 100644 index 5f3a25e8e9..0000000000 --- a/toolsrc/src/vcpkg/logicexpression.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#include "pch.h" - -#include -#include -#include -#include - -#include -#include - -namespace vcpkg -{ - using vcpkg::Parse::ParseError; - - enum class Identifier - { - invalid, // not a recognized identifier - x64, - x86, - arm, - arm64, - - windows, - linux, - osx, - uwp, - android, - emscripten, - wasm32, - - static_link, - }; - - // logic expression supports the following : - // primary-expression: - // ( logic-expression ) - // identifier - // identifier: - // alpha-numeric string of characters - // logic-expression: <- this is the entry point - // not-expression - // not-expression | logic-expression - // not-expression & logic-expression - // not-expression: - // ! primary-expression - // primary-expression - // - // | and & have equal precidence and cannot be used together at the same nesting level - // for example a|b&c is not allowd but (a|b)&c and a|(b&c) are allowed. - class ExpressionParser : public Parse::ParserBase - { - public: - ExpressionParser(const std::string& str, const ExpressionContext& context) : - Parse::ParserBase(str, "CONTROL"), evaluation_context(context) - { - { - auto override_vars = evaluation_context.cmake_context.find("VCPKG_DEP_INFO_OVERRIDE_VARS"); - if (override_vars != evaluation_context.cmake_context.end()) - { - auto cmake_list = Strings::split(override_vars->second, ';'); - for (auto& override_id : cmake_list) - { - if (!override_id.empty()) - { - if (override_id[0] == '!') - { - context_override.insert({override_id.substr(1), false}); - } - else - { - context_override.insert({override_id, true}); - } - } - } - } - } - skip_whitespace(); - - final_result = logic_expression(); - - if (!at_eof()) - { - add_error("invalid logic expression, unexpected character"); - } - } - - bool get_result() const { return final_result; } - - private: - const ExpressionContext& evaluation_context; - std::map context_override; - - bool final_result; - - static bool is_identifier_char(char32_t ch) - { - return is_upper_alpha(ch) || is_lower_alpha(ch) || is_ascii_digit(ch) || ch == '-'; - } - - // Legacy evaluation only searches for substrings. Use this only for diagnostic purposes. - bool evaluate_identifier_legacy(const std::string name) const - { - return evaluation_context.legacy_context.find(name) != std::string::npos; - } - - static Identifier string2identifier(const std::string& name) - { - static const std::map id_map = { - {"x64", Identifier::x64}, - {"x86", Identifier::x86}, - {"arm", Identifier::arm}, - {"arm64", Identifier::arm64}, - {"windows", Identifier::windows}, - {"linux", Identifier::linux}, - {"osx", Identifier::osx}, - {"uwp", Identifier::uwp}, - {"android", Identifier::android}, - {"emscripten", Identifier::emscripten}, - {"wasm32", Identifier::wasm32}, - {"static", Identifier::static_link}, - }; - - auto id_pair = id_map.find(name); - - if (id_pair == id_map.end()) - { - return Identifier::invalid; - } - - return id_pair->second; - } - - bool true_if_exists_and_equal(const std::string& variable_name, const std::string& value) - { - auto iter = evaluation_context.cmake_context.find(variable_name); - if (iter == evaluation_context.cmake_context.end()) - { - return false; - } - return iter->second == value; - } - - // If an identifier is on the explicit override list, return the override value - // Otherwise fall back to the built in logic to evaluate - // All unrecognized identifiers are an error - bool evaluate_identifier_cmake(const std::string name, const SourceLoc& loc) - { - auto id = string2identifier(name); - - switch (id) - { - case Identifier::invalid: - // Point out in the diagnostic that they should add to the override list because that is what - // most users should do, however it is also valid to update the built in identifiers to recognize - // the name. - add_error("Unrecognized identifer name. Add to override list in triplet file.", loc); - break; - - case Identifier::x64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x64"); - case Identifier::x86: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x86"); - case Identifier::arm: - // For backwards compatability arm is also true for arm64. - // This is because it previously was only checking for a substring. - return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm") || - true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64"); - case Identifier::arm64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64"); - case Identifier::windows: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "") || true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"); - case Identifier::linux: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Linux"); - case Identifier::osx: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Darwin"); - case Identifier::uwp: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"); - case Identifier::android: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Android"); - case Identifier::emscripten: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Emscripten"); - case Identifier::wasm32: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "wasm32"); - case Identifier::static_link: return true_if_exists_and_equal("VCPKG_LIBRARY_LINKAGE", "static"); - } - - return evaluation_context.legacy_context.find(name) != std::string::npos; - } - - bool evaluate_identifier(const std::string name, const SourceLoc& loc) - { - if (!context_override.empty()) - { - auto override_id = context_override.find(name); - if (override_id != context_override.end()) - { - return override_id->second; - } - // Fall through to use the cmake logic if the id does not have an override - } - - bool legacy = evaluate_identifier_legacy(name); - bool cmake = evaluate_identifier_cmake(name, loc); - if (legacy != cmake) - { - // Legacy evaluation only used the name of the triplet, now we use the actual - // cmake variables. This has the potential to break custom triplets. - // For now just print a message, this will need to change once we start introducing - // new variables that did not exist previously (such as host-*) - System::print2("Warning: qualifier has changed meaning recently:\n ", name, '\n'); - } - return cmake; - } - - // identifier: - // alpha-numeric string of characters - bool identifier_expression() - { - auto start_loc = cur_loc(); - std::string name = match_zero_or_more(is_identifier_char).to_string(); - - if (name.empty()) - { - add_error("unexpected character in logic expression"); - return false; - } - - bool result = evaluate_identifier(name, start_loc); - skip_whitespace(); - return result; - } - - // not-expression: - // ! primary-expression - // primary-expression - bool not_expression() - { - if (cur() == '!') - { - next(); - skip_whitespace(); - return !primary_expression(); - } - - return primary_expression(); - } - - template - bool logic_expression_helper(bool seed) - { - do - { - // Support chains of the operator to avoid breaking backwards compatability - while (next() == oper) - { - }; - skip_whitespace(); - seed = operation(not_expression(), seed); - - } while (cur() == oper); - - if (cur() == other) - { - add_error("mixing & and | is not allowed, use () to specify order of operations"); - } - - skip_whitespace(); - return seed; - } - static bool and_helper(bool left, bool right) { return left && right; } - static bool or_helper(bool left, bool right) { return left || right; } - - // logic-expression: <- entry point - // not-expression - // not-expression | logic-expression - // not-expression & logic-expression - bool logic_expression() - { - auto result = not_expression(); - - switch (cur()) - { - case '|': - { - return logic_expression_helper<'|', '&', or_helper>(result); - } - case '&': - { - return logic_expression_helper<'&', '|', and_helper>(result); - } - default: return result; - } - } - - // primary-expression: - // ( logic-expression ) - // identifier - bool primary_expression() - { - if (cur() == '(') - { - next(); - skip_whitespace(); - bool result = logic_expression(); - if (cur() != ')') - { - add_error("missing closing )"); - return result; - } - next(); - skip_whitespace(); - return result; - } - - return identifier_expression(); - } - }; - - ExpectedT evaluate_expression(const std::string& expression, const ExpressionContext& context) - { - ExpressionParser parser(expression, context); - - if (auto err = parser.get_error()) - { - return err->format(); - } - - return parser.get_result(); - } -} diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index e2661d98a9..7920cd7a5d 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -153,6 +153,8 @@ namespace vcpkg::Metrics Json::Array buildtime_names; Json::Array buildtime_times; + Json::Object feature_flags; + void track_property(const std::string& name, const std::string& value) { properties.insert_or_replace(name, Json::Value::string(value)); @@ -168,6 +170,10 @@ namespace vcpkg::Metrics buildtime_names.push_back(Json::Value::string(name)); buildtime_times.push_back(Json::Value::number(value)); } + void track_feature(const std::string& name, bool value) + { + feature_flags.insert(name, Json::Value::boolean(value)); + } std::string format_event_data_template() const { @@ -226,6 +232,7 @@ namespace vcpkg::Metrics base_data.insert("name", Json::Value::string("commandline_test7")); base_data.insert("properties", Json::Value::object(std::move(props_plus_buildtimes))); base_data.insert("measurements", Json::Value::object(measurements.clone())); + base_data.insert("feature-flags", Json::Value::object(feature_flags.clone())); } return Json::stringify(arr, vcpkg::Json::JsonStyle()); @@ -356,6 +363,15 @@ namespace vcpkg::Metrics g_metricmessage.track_property(name, value); } + void Metrics::track_feature(const std::string& name, bool value) + { + if (!metrics_enabled()) + { + return; + } + g_metricmessage.track_feature(name, value); + } + void Metrics::upload(const std::string& payload) { if (!metrics_enabled()) diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp index 0f3bfd8800..f828068795 100644 --- a/toolsrc/src/vcpkg/packagespec.cpp +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -64,7 +64,8 @@ namespace vcpkg { return parse_qualified_specifier(spec_as_string) .then([&](ParsedQualifiedSpecifier&& p) -> ExpectedS { - if (p.qualifier) return "Error: qualifier not allowed in this context: " + spec_as_string + "\n"; + if (p.platform) + return "Error: platform specifier not allowed in this context: " + spec_as_string + "\n"; auto triplet = p.triplet ? Triplet::from_canonical_name(std::move(*p.triplet.get())) : default_triplet; return FullPackageSpec({p.name, triplet}, p.features.value_or({})); }); @@ -97,7 +98,7 @@ namespace vcpkg { return parse_qualified_specifier(name).then([&](ParsedQualifiedSpecifier&& pqs) -> ExpectedS { if (pqs.triplet) return "Error: triplet not allowed in this context: " + name + "\n"; - if (pqs.qualifier) return "Error: qualifier not allowed in this context: " + name + "\n"; + if (pqs.platform) return "Error: platform specifier not allowed in this context: " + name + "\n"; return Features{pqs.name, pqs.features.value_or({})}; }); } @@ -107,8 +108,10 @@ namespace vcpkg return Parse::ParserBase::is_lower_alpha(ch) || Parse::ParserBase::is_ascii_digit(ch) || ch == '-'; } - static bool is_feature_name_char(char32_t ch) { - // TODO: we do not intend underscores to be valid, however there is currently a feature using them (libwebp[vwebp_sdl]). + static bool is_feature_name_char(char32_t ch) + { + // TODO: we do not intend underscores to be valid, however there is currently a feature using them + // (libwebp[vwebp_sdl]). // TODO: we need to rename this feature, then remove underscores from this list. return is_package_name_char(ch) || ch == '_'; } @@ -127,11 +130,15 @@ namespace vcpkg using Parse::ParserBase; auto ret = parser.match_zero_or_more(is_feature_name_char).to_string(); auto ch = parser.cur(); - if (ParserBase::is_upper_alpha(ch) || ch == '_') + + // ignores the feature name vwebp_sdl as a back-compat thing + const bool has_underscore = std::find(ret.begin(), ret.end(), '_') != ret.end() && ret != "vwebp_sdl"; + if (has_underscore || ParserBase::is_upper_alpha(ch)) { parser.add_error("invalid character in feature name (must be lowercase, digits, '-')"); return nullopt; } + if (ret.empty()) { parser.add_error("expected feature name (must be lowercase, digits, '-')"); @@ -224,6 +231,7 @@ namespace vcpkg if (ch == '(') { auto loc = parser.cur_loc(); + std::string platform_string; int depth = 1; while (depth > 0 && (ch = parser.next()) != 0) { @@ -232,12 +240,19 @@ namespace vcpkg } if (depth > 0) { - parser.add_error("unmatched open braces in qualifier", loc); + parser.add_error("unmatched open braces in platform specifier", loc); return nullopt; } - ret.qualifier = std::string( - (++loc.it).pointer_to_current(), - parser.it().pointer_to_current()); + platform_string.append((++loc.it).pointer_to_current(), parser.it().pointer_to_current()); + auto platform_opt = PlatformExpression::parse_platform_expression(platform_string, PlatformExpression::MultipleBinaryOperators::Allow); + if (auto platform = platform_opt.get()) + { + ret.platform = std::move(*platform); + } + else + { + parser.add_error(platform_opt.error(), loc); + } parser.next(); } // This makes the behavior of the parser more consistent -- otherwise, it will skip tabs and spaces only if diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index 7032620a10..458950eead 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -67,7 +67,7 @@ namespace vcpkg::Paragraphs } public: - PghParser(StringView text, StringView origin) : Parse::ParserBase(text, origin) {} + PghParser(StringView text, StringView origin) : Parse::ParserBase(text, origin) { } ExpectedS> get_paragraphs() { @@ -86,7 +86,7 @@ namespace vcpkg::Paragraphs } }; - static ExpectedS parse_single_paragraph(const std::string& str, const std::string& origin) + ExpectedS parse_single_paragraph(const std::string& str, const std::string& origin) { auto pghs = PghParser(str, origin).get_paragraphs(); @@ -128,16 +128,67 @@ namespace vcpkg::Paragraphs return PghParser(str, origin).get_paragraphs(); } + bool is_port_directory(const Files::Filesystem& fs, const fs::path& path) + { + return fs.exists(path / fs::u8path("CONTROL")) || fs.exists(path / fs::u8path("vcpkg.json")); + } + + ParseExpected try_load_manifest(const Files::Filesystem& fs, const std::string& port_name, const fs::path& path_to_manifest, std::error_code& ec) + { + auto error_info = std::make_unique(); + auto res = Json::parse_file(fs, path_to_manifest, ec); + if (ec) return error_info; + + if (auto val = res.get()) + { + if (val->first.is_object()) + { + return SourceControlFile::parse_manifest_file(path_to_manifest, val->first.object()); + } + else + { + error_info->name = port_name; + error_info->error = "Manifest files must have a top-level object"; + return error_info; + } + } + else + { + error_info->name = port_name; + error_info->error = res.error()->format(); + return error_info; + } + } + ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) { - const auto path_to_control = path / "CONTROL"; + const auto path_to_manifest = path / fs::u8path("vcpkg.json"); + const auto path_to_control = path / fs::u8path("CONTROL"); + if (fs.exists(path_to_manifest)) { + vcpkg::Checks::check_exit( + VCPKG_LINE_INFO, + !fs.exists(path_to_control), + "Found both manifest and CONTROL file in port %s; please rename one or the other", + path.u8string()); + + std::error_code ec; + auto res = try_load_manifest(fs, path.filename().u8string(), path_to_manifest, ec); + if (ec) + { + auto error_info = std::make_unique(); + error_info->name = path.filename().u8string(); + error_info->error = Strings::format("Failed to load manifest file for port: %s\n", path_to_manifest.u8string(), ec.message()); + } + + return res; + } ExpectedS> pghs = get_paragraphs(fs, path_to_control); if (auto vector_pghs = pghs.get()) { return SourceControlFile::parse_control_file(path_to_control, std::move(*vector_pghs)); } auto error_info = std::make_unique(); - error_info->name = path.filename().generic_u8string(); + error_info->name = path.filename().u8string(); error_info->error = pghs.error(); return error_info; } diff --git a/toolsrc/src/vcpkg/platform-expression.cpp b/toolsrc/src/vcpkg/platform-expression.cpp new file mode 100644 index 0000000000..35cfd4cbc1 --- /dev/null +++ b/toolsrc/src/vcpkg/platform-expression.cpp @@ -0,0 +1,471 @@ +#include "pch.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace vcpkg::PlatformExpression +{ + using vcpkg::Parse::ParseError; + + enum class Identifier + { + invalid = -1, // not a recognized identifier + x86, + x64, + arm, + arm64, + wasm32, + + windows, + linux, + osx, + uwp, + android, + emscripten, + + static_link, + }; + + static Identifier string2identifier(StringView name) + { + static const std::map id_map = { + {"x86", Identifier::x86}, + {"x64", Identifier::x64}, + {"arm", Identifier::arm}, + {"arm64", Identifier::arm64}, + {"wasm32", Identifier::wasm32}, + {"windows", Identifier::windows}, + {"linux", Identifier::linux}, + {"osx", Identifier::osx}, + {"uwp", Identifier::uwp}, + {"android", Identifier::android}, + {"emscripten", Identifier::emscripten}, + {"static", Identifier::static_link}, + }; + + auto id_pair = id_map.find(name); + + if (id_pair == id_map.end()) + { + return Identifier::invalid; + } + + return id_pair->second; + } + + namespace detail + { + struct ExprIdentifier + { + std::string identifier; + }; + struct ExprNot + { + std::unique_ptr expr; + }; + struct ExprAnd + { + std::vector exprs; + }; + struct ExprOr + { + std::vector exprs; + }; + + struct ExprImpl + { + std::variant underlying; + + explicit ExprImpl(ExprIdentifier e) : underlying(std::move(e)) { } + explicit ExprImpl(ExprNot e) : underlying(std::move(e)) { } + explicit ExprImpl(ExprAnd e) : underlying(std::move(e)) { } + explicit ExprImpl(ExprOr e) : underlying(std::move(e)) { } + + ExprImpl clone() const + { + struct Visitor + { + ExprImpl operator()(const ExprIdentifier& e) { return ExprImpl(e); } + ExprImpl operator()(const ExprNot& e) + { + return ExprImpl(ExprNot{std::make_unique(e.expr->clone())}); + } + ExprImpl operator()(const ExprAnd& e) + { + ExprAnd res; + for (const auto& expr : e.exprs) + { + res.exprs.push_back(expr.clone()); + } + return ExprImpl(std::move(res)); + } + ExprImpl operator()(const ExprOr& e) + { + ExprOr res; + for (const auto& expr : e.exprs) + { + res.exprs.push_back(expr.clone()); + } + return ExprImpl(std::move(res)); + } + }; + return std::visit(Visitor{}, underlying); + } + }; + + class ExpressionParser : public Parse::ParserBase + { + public: + ExpressionParser(StringView str, MultipleBinaryOperators multiple_binary_operators) : Parse::ParserBase(str, "CONTROL"), multiple_binary_operators(multiple_binary_operators) { } + + MultipleBinaryOperators multiple_binary_operators; + + bool allow_multiple_binary_operators() const + { + return multiple_binary_operators == MultipleBinaryOperators::Allow; + } + + PlatformExpression::Expr parse() + { + skip_whitespace(); + + auto res = expr(); + + if (!at_eof()) + { + add_error("invalid logic expression, unexpected character"); + } + + return Expr(std::make_unique(std::move(res))); + } + + private: + // + // + // & + // + // + // | + + static bool is_identifier_char(char32_t ch) + { + return is_lower_alpha(ch) || is_ascii_digit(ch); + } + + // : + // + // + // + ExprImpl expr() + { + auto result = expr_not(); + + switch (cur()) + { + case '|': + { + ExprOr e; + e.exprs.push_back(std::move(result)); + return expr_binary<'|', '&'>(std::move(e)); + } + case '&': + { + ExprAnd e; + e.exprs.push_back(std::move(result)); + return expr_binary<'&', '|'>(std::move(e)); + } + default: return result; + } + } + + // : + // ( ) + // + ExprImpl expr_simple() + { + if (cur() == '(') + { + next(); + skip_whitespace(); + auto result = expr(); + if (cur() != ')') + { + add_error("missing closing )"); + return result; + } + next(); + skip_whitespace(); + return result; + } + + return expr_identifier(); + } + + // : + // A lowercase alpha-numeric string + ExprImpl expr_identifier() + { + std::string name = match_zero_or_more(is_identifier_char).to_string(); + + if (name.empty()) + { + add_error("unexpected character in logic expression"); + } + + skip_whitespace(); + return ExprImpl{ExprIdentifier{name}}; + } + + // : + // + // ! + ExprImpl expr_not() + { + if (cur() == '!') + { + next(); + skip_whitespace(); + return ExprImpl(ExprNot{std::make_unique(expr_simple())}); + } + + return expr_simple(); + } + + template + ExprImpl expr_binary(ExprKind&& seed) + { + do + { + // Support chains of the operator to avoid breaking backwards compatibility + do + { + next(); + } while (allow_multiple_binary_operators() && cur() == oper); + + skip_whitespace(); + seed.exprs.push_back(expr_not()); + } while (cur() == oper); + + if (cur() == other) + { + add_error("mixing & and | is not allowed; use () to specify order of operations"); + } + + skip_whitespace(); + return ExprImpl(std::move(seed)); + } + }; + } + + using namespace detail; + + Expr::Expr() = default; + Expr::Expr(Expr&& other) = default; + Expr& Expr::operator=(Expr&& other) = default; + + Expr::Expr(const Expr& other) + { + if (other.underlying_) + { + underlying_ = std::make_unique(other.underlying_->clone()); + } + } + Expr& Expr::operator=(const Expr& other) + { + if (other.underlying_) + { + if (this->underlying_) + { + *this->underlying_ = other.underlying_->clone(); + } + else + { + this->underlying_ = std::make_unique(other.underlying_->clone()); + } + } + else + { + this->underlying_.reset(); + } + + return *this; + } + + Expr::Expr(std::unique_ptr&& e) : underlying_(std::move(e)) { } + Expr::~Expr() = default; + + Expr Expr::Identifier(StringView id) + { + return Expr(std::make_unique(ExprImpl{ExprIdentifier{id.to_string()}})); + } + Expr Expr::Not(Expr&& e) { return Expr(std::make_unique(ExprImpl{ExprNot{std::move(e.underlying_)}})); } + Expr Expr::And(std::vector&& exprs) + { + std::vector impls; + for (auto& e : exprs) + { + impls.push_back(std::move(*e.underlying_)); + } + return Expr(std::make_unique(ExprAnd{std::move(impls)})); + } + Expr Expr::Or(std::vector&& exprs) + { + std::vector impls; + for (auto& e : exprs) + { + impls.push_back(std::move(*e.underlying_)); + } + return Expr(std::make_unique(ExprOr{std::move(impls)})); + } + + bool Expr::evaluate(const Context& context) const + { + if (!underlying_) + { + return true; // empty expression is always true + } + + std::map override_ctxt; + { + auto override_vars = context.find("VCPKG_DEP_INFO_OVERRIDE_VARS"); + if (override_vars != context.end()) + { + auto cmake_list = Strings::split(override_vars->second, ';'); + for (auto& override_id : cmake_list) + { + if (!override_id.empty()) + { + if (override_id[0] == '!') + { + override_ctxt.insert({override_id.substr(1), false}); + } + else + { + override_ctxt.insert({override_id, true}); + } + } + } + } + } + + struct Visitor + { + const Context& context; + const std::map& override_ctxt; + + bool true_if_exists_and_equal(const std::string& variable_name, const std::string& value) const + { + auto iter = context.find(variable_name); + if (iter == context.end()) + { + return false; + } + return iter->second == value; + } + + bool visit(const ExprImpl& e) const { return std::visit(*this, e.underlying); } + + bool operator()(const ExprIdentifier& expr) const + { + if (!override_ctxt.empty()) + { + auto override_id = override_ctxt.find(expr.identifier); + if (override_id != override_ctxt.end()) + { + return override_id->second; + } + // Fall through to use the cmake logic if the id does not have an override + } + + auto id = string2identifier(expr.identifier); + switch (id) + { + case Identifier::invalid: + // Point out in the diagnostic that they should add to the override list because that is what + // most users should do, however it is also valid to update the built in identifiers to + // recognize the name. + System::printf(System::Color::error, + "Error: Unrecognized identifer name %s. Add to override list in triplet file.\n", + expr.identifier); + return false; + case Identifier::x64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x64"); + case Identifier::x86: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "x86"); + case Identifier::arm: + // For backwards compatability arm is also true for arm64. + // This is because it previously was only checking for a substring. + return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm") || + true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64"); + case Identifier::arm64: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "arm64"); + case Identifier::windows: + return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "") || + true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"); + case Identifier::linux: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Linux"); + case Identifier::osx: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Darwin"); + case Identifier::uwp: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"); + case Identifier::android: return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Android"); + case Identifier::emscripten: + return true_if_exists_and_equal("VCPKG_CMAKE_SYSTEM_NAME", "Emscripten"); + case Identifier::wasm32: return true_if_exists_and_equal("VCPKG_TARGET_ARCHITECTURE", "wasm32"); + case Identifier::static_link: return true_if_exists_and_equal("VCPKG_LIBRARY_LINKAGE", "static"); + default: + Checks::exit_with_message( + VCPKG_LINE_INFO, + "vcpkg bug: string2identifier returned a value that we don't recognize: %d\n", + static_cast(id)); + } + } + + bool operator()(const ExprNot& expr) const { + bool res = visit(*expr.expr); + return !res; + } + + bool operator()(const ExprAnd& expr) const + { + bool valid = true; + + // we want to print errors in all expressions, so we check all of the expressions all the time + for (const auto& e : expr.exprs) + { + valid &= visit(e); + } + + return valid; + } + + bool operator()(const ExprOr& expr) const + { + bool valid = false; + // we want to print errors in all expressions, so we check all of the expressions all the time + for (const auto& e : expr.exprs) + { + valid |= visit(e); + } + return valid; + } + }; + + return Visitor{context, override_ctxt}.visit(*underlying_); + } + + ExpectedS parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators) + { + auto parser = ExpressionParser(expression, multiple_binary_operators); + auto res = parser.parse(); + + if (auto p = parser.extract_error()) + { + return p->format(); + } + else + { + return res; + } + } +} diff --git a/toolsrc/src/vcpkg/portfileprovider.cpp b/toolsrc/src/vcpkg/portfileprovider.cpp index 6500f70a60..f0533f08d5 100644 --- a/toolsrc/src/vcpkg/portfileprovider.cpp +++ b/toolsrc/src/vcpkg/portfileprovider.cpp @@ -25,40 +25,35 @@ namespace vcpkg::PortFileProvider } PathsPortFileProvider::PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, - const std::vector* ports_dirs_paths) + const std::vector& ports_dirs_paths) : filesystem(paths.get_filesystem()) { auto& fs = paths.get_filesystem(); - if (ports_dirs_paths) + for (auto&& overlay_path : ports_dirs_paths) { - for (auto&& overlay_path : *ports_dirs_paths) + if (!overlay_path.empty()) { - if (!overlay_path.empty()) + auto overlay = fs::u8path(overlay_path); + if (overlay.is_absolute()) { - auto overlay = fs::u8path(overlay_path); - if (overlay.is_absolute()) - { - overlay = fs.canonical(VCPKG_LINE_INFO, overlay); - } - else - { - overlay = fs.canonical(VCPKG_LINE_INFO, paths.original_cwd / overlay); - } - - Debug::print("Using overlay: ", overlay.u8string(), "\n"); - - Checks::check_exit(VCPKG_LINE_INFO, - filesystem.exists(overlay), - "Error: Path \"%s\" does not exist", - overlay.string()); - - Checks::check_exit(VCPKG_LINE_INFO, - fs::is_directory(fs.status(VCPKG_LINE_INFO, overlay)), - "Error: Path \"%s\" must be a directory", - overlay.string()); - - ports_dirs.emplace_back(overlay); + overlay = fs.canonical(VCPKG_LINE_INFO, overlay); } + else + { + overlay = fs.canonical(VCPKG_LINE_INFO, paths.original_cwd / overlay); + } + + Debug::print("Using overlay: ", overlay.u8string(), "\n"); + + Checks::check_exit( + VCPKG_LINE_INFO, filesystem.exists(overlay), "Error: Path \"%s\" does not exist", overlay.string()); + + Checks::check_exit(VCPKG_LINE_INFO, + fs::is_directory(fs.status(VCPKG_LINE_INFO, overlay)), + "Error: Path \"%s\" must be a directory", + overlay.string()); + + ports_dirs.emplace_back(overlay); } } ports_dirs.emplace_back(paths.ports); @@ -75,7 +70,7 @@ namespace vcpkg::PortFileProvider for (auto&& ports_dir : ports_dirs) { // Try loading individual port - if (filesystem.exists(ports_dir / "CONTROL")) + if (Paragraphs::is_port_directory(filesystem, ports_dir)) { auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir); if (auto scf = maybe_scf.get()) @@ -94,10 +89,14 @@ namespace vcpkg::PortFileProvider Checks::exit_with_message( VCPKG_LINE_INFO, "Error: Failed to load port from %s", spec, ports_dir.u8string()); } + + continue; } - else if (filesystem.exists(ports_dir / spec / "CONTROL")) + + auto ports_spec = ports_dir / spec; + if (Paragraphs::is_port_directory(filesystem, ports_spec)) { - auto found_scf = Paragraphs::try_load_port(filesystem, ports_dir / spec); + auto found_scf = Paragraphs::try_load_port(filesystem, ports_spec); if (auto scf = found_scf.get()) { if (scf->get()->core_paragraph->name == spec) @@ -133,7 +132,7 @@ namespace vcpkg::PortFileProvider for (auto&& ports_dir : ports_dirs) { // Try loading individual port - if (filesystem.exists(ports_dir / "CONTROL")) + if (Paragraphs::is_port_directory(filesystem, ports_dir)) { auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir); if (auto scf = maybe_scf.get()) diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 9b4dc86e0b..23f9d0097c 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -215,6 +215,10 @@ namespace vcpkg::Remove void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) { + if (paths.manifest_mode_enabled()) + { + Checks::exit_with_message(VCPKG_LINE_INFO, "vcpkg remove does not support manifest mode. In order to remove dependencies, you will need to edit your manifest (vcpkg.json)."); + } const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); StatusParagraphs status_db = database_load_check(paths); @@ -228,7 +232,7 @@ namespace vcpkg::Remove } // Load ports from ports dirs - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); specs = Util::fmap(Update::find_outdated_packages(provider, status_db), [](auto&& outdated) { return outdated.spec; }); diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index b5e0ebe314..74ef2f9e13 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include +#include #include #include #include @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -18,28 +19,71 @@ namespace vcpkg namespace SourceParagraphFields { static const std::string BUILD_DEPENDS = "Build-Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string DEFAULT_FEATURES = "Default-Features"; static const std::string DESCRIPTION = "Description"; static const std::string FEATURE = "Feature"; - static const std::string MAINTAINER = "Maintainer"; - static const std::string SOURCE = "Source"; + static const std::string MAINTAINERS = "Maintainer"; + static const std::string NAME = "Source"; static const std::string VERSION = "Version"; + static const std::string PORT_VERSION = "Port-Version"; static const std::string HOMEPAGE = "Homepage"; static const std::string TYPE = "Type"; static const std::string SUPPORTS = "Supports"; } - static Span get_list_of_valid_fields() + namespace ManifestFields { - static const std::string valid_fields[] = { - SourceParagraphFields::SOURCE, + constexpr static StringLiteral NAME = "name"; + constexpr static StringLiteral VERSION = "version-string"; + + constexpr static StringLiteral PORT_VERSION = "port-version"; + constexpr static StringLiteral MAINTAINERS = "maintainers"; + constexpr static StringLiteral DESCRIPTION = "description"; + constexpr static StringLiteral HOMEPAGE = "homepage"; + constexpr static StringLiteral DOCUMENTATION = "documentation"; + constexpr static StringLiteral LICENSE = "license"; + constexpr static StringLiteral DEPENDENCIES = "dependencies"; + constexpr static StringLiteral DEV_DEPENDENCIES = "dev-dependencies"; + constexpr static StringLiteral FEATURES = "features"; + constexpr static StringLiteral DEFAULT_FEATURES = "default-features"; + constexpr static StringLiteral SUPPORTS = "supports"; + } + + static Span get_list_of_valid_fields() + { + static const StringView valid_fields[] = { + SourceParagraphFields::NAME, SourceParagraphFields::VERSION, + SourceParagraphFields::PORT_VERSION, SourceParagraphFields::DESCRIPTION, - SourceParagraphFields::MAINTAINER, + SourceParagraphFields::MAINTAINERS, SourceParagraphFields::BUILD_DEPENDS, SourceParagraphFields::HOMEPAGE, SourceParagraphFields::TYPE, SourceParagraphFields::SUPPORTS, + SourceParagraphFields::DEFAULT_FEATURES, + }; + + return valid_fields; + } + + static Span get_list_of_manifest_fields() + { + constexpr static StringView valid_fields[] = { + ManifestFields::NAME, + ManifestFields::VERSION, + + ManifestFields::PORT_VERSION, + ManifestFields::MAINTAINERS, + ManifestFields::DESCRIPTION, + ManifestFields::HOMEPAGE, + ManifestFields::DOCUMENTATION, + ManifestFields::LICENSE, + ManifestFields::DEPENDENCIES, + ManifestFields::DEV_DEPENDENCIES, + ManifestFields::FEATURES, + ManifestFields::DEFAULT_FEATURES, + ManifestFields::SUPPORTS, }; return valid_fields; @@ -65,22 +109,29 @@ namespace vcpkg if (!error_info->extra_fields.empty()) { System::print2(System::Color::error, - "Error: There are invalid fields in the control file of ", + "Error: There are invalid fields in the control or manifest file of ", error_info->name, '\n'); - System::print2("The following fields were not expected:\n\n ", - Strings::join("\n ", error_info->extra_fields), - "\n\n"); + System::print2("The following fields were not expected:\n"); + + for (const auto& pr : error_info->extra_fields) + { + System::print2(" In ", pr.first, ": ", Strings::join(", ", pr.second), "\n"); + } have_remaining_fields = true; } } if (have_remaining_fields) { - System::print2("This is the list of valid fields (case-sensitive): \n\n ", + System::print2("This is the list of valid fields for CONTROL files (case-sensitive): \n\n ", Strings::join("\n ", get_list_of_valid_fields()), "\n\n"); - System::print2("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n\n"); + System::print2("And this is the list of valid fields for manifest files: \n\n ", + Strings::join("\n ", get_list_of_manifest_fields()), + "\n\n"); + System::print2("You may need to update the vcpkg binary; try running bootstrap-vcpkg.bat or " + "bootstrap-vcpkg.sh to update.\n\n"); } for (auto&& error_info : error_info_list) @@ -91,9 +142,29 @@ namespace vcpkg "Error: There are missing fields in the control file of ", error_info->name, '\n'); - System::print2("The following fields were missing:\n\n ", - Strings::join("\n ", error_info->missing_fields), - "\n\n"); + System::print2("The following fields were missing:\n"); + for (const auto& pr : error_info->missing_fields) + { + System::print2(" In ", pr.first, ": ", Strings::join(", ", pr.second), "\n"); + } + } + } + + for (auto&& error_info : error_info_list) + { + if (!error_info->expected_types.empty()) + { + System::print2(System::Color::error, + "Error: There are invalid field types in the CONTROL or manifest file of ", + error_info->name, + '\n'); + System::print2("The following fields had the wrong types:\n\n"); + + for (const auto& pr : error_info->expected_types) + { + System::printf(" %s was expected to be %s\n", pr.first, pr.second); + } + System::print2("\n"); } } } @@ -111,10 +182,27 @@ namespace vcpkg Type Type::from_string(const std::string& t) { if (t == "Alias") return Type{Type::ALIAS}; - if (t == "Port" || t == "") return Type{Type::PORT}; + if (t == "Port" || t.empty()) return Type{Type::PORT}; return Type{Type::UNKNOWN}; } + bool operator==(const Type& lhs, const Type& rhs) + { + return lhs.type == rhs.type; + } + bool operator!=(const Type& lhs, const Type& rhs) + { + return !(lhs == rhs); + } + + static void trim_all(std::vector& arr) + { + for (auto& el : arr) + { + el = Strings::trim(std::move(el)); + } + } + static ParseExpected parse_source_paragraph(const fs::path& path_to_control, Paragraph&& fields) { auto origin = path_to_control.u8string(); @@ -123,20 +211,52 @@ namespace vcpkg auto spgh = std::make_unique(); - parser.required_field(SourceParagraphFields::SOURCE, spgh->name); + parser.required_field(SourceParagraphFields::NAME, spgh->name); parser.required_field(SourceParagraphFields::VERSION, spgh->version); - spgh->description = parser.optional_field(SourceParagraphFields::DESCRIPTION); - spgh->maintainer = parser.optional_field(SourceParagraphFields::MAINTAINER); + auto pv_str = parser.optional_field(SourceParagraphFields::PORT_VERSION); + if (!pv_str.empty()) + { + auto pv_opt = Strings::strto(pv_str); + if (auto pv = pv_opt.get()) + { + spgh->port_version = *pv; + } + else + { + parser.add_type_error(SourceParagraphFields::PORT_VERSION, "a non-negative integer"); + } + } + + spgh->description = Strings::split(parser.optional_field(SourceParagraphFields::DESCRIPTION), '\n'); + trim_all(spgh->description); + + spgh->maintainers = Strings::split(parser.optional_field(SourceParagraphFields::MAINTAINERS), '\n'); + trim_all(spgh->maintainers); + spgh->homepage = parser.optional_field(SourceParagraphFields::HOMEPAGE); TextRowCol textrowcol; std::string buf; parser.optional_field(SourceParagraphFields::BUILD_DEPENDS, {buf, textrowcol}); - spgh->depends = parse_dependencies_list(buf, origin, textrowcol).value_or_exit(VCPKG_LINE_INFO); + spgh->dependencies = parse_dependencies_list(buf, origin, textrowcol).value_or_exit(VCPKG_LINE_INFO); buf.clear(); - parser.optional_field(SourceParagraphFields::DEFAULTFEATURES, {buf, textrowcol}); + parser.optional_field(SourceParagraphFields::DEFAULT_FEATURES, {buf, textrowcol}); spgh->default_features = parse_default_features_list(buf, origin, textrowcol).value_or_exit(VCPKG_LINE_INFO); - spgh->supports_expression = parser.optional_field(SourceParagraphFields::SUPPORTS); + + auto supports_expr = parser.optional_field(SourceParagraphFields::SUPPORTS); + if (!supports_expr.empty()) + { + auto maybe_expr = PlatformExpression::parse_platform_expression(supports_expr, PlatformExpression::MultipleBinaryOperators::Allow); + if (auto expr = maybe_expr.get()) + { + spgh->supports_expression = std::move(*expr); + } + else + { + parser.add_type_error(SourceParagraphFields::SUPPORTS, "a platform expression"); + } + } + spgh->type = Type::from_string(parser.optional_field(SourceParagraphFields::TYPE)); auto err = parser.error_info(spgh->name.empty() ? origin : spgh->name); if (err) @@ -153,10 +273,12 @@ namespace vcpkg auto fpgh = std::make_unique(); parser.required_field(SourceParagraphFields::FEATURE, fpgh->name); - parser.required_field(SourceParagraphFields::DESCRIPTION, fpgh->description); + fpgh->description = Strings::split(parser.required_field(SourceParagraphFields::DESCRIPTION), '\n'); + trim_all(fpgh->description); - fpgh->depends = parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS), origin) - .value_or_exit(VCPKG_LINE_INFO); + fpgh->dependencies = + parse_dependencies_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS), origin) + .value_or_exit(VCPKG_LINE_INFO); auto err = parser.error_info(fpgh->name.empty() ? origin : fpgh->name); if (err) @@ -197,6 +319,497 @@ namespace vcpkg return control_file; } + static std::vector invalid_json_fields(const Json::Object& obj, + Span known_fields) noexcept + { + const auto field_is_unknown = [known_fields](StringView sv) { + // allow directives + if (sv.size() != 0 && *sv.begin() == '$') + { + return false; + } + return std::find(known_fields.begin(), known_fields.end(), sv) == known_fields.end(); + }; + + std::vector res; + for (const auto& kv : obj) + { + if (field_is_unknown(kv.first)) + { + res.push_back(kv.first.to_string()); + } + } + + return res; + } + + struct StringField : Json::VisitorCrtpBase + { + using type = std::string; + StringView type_name() { return type_name_; } + + Optional visit_string(Json::Reader&, StringView, StringView sv) { return sv.to_string(); } + + explicit StringField(StringView type_name_) : type_name_(type_name_) { } + + private: + StringView type_name_; + }; + + struct BooleanField : Json::VisitorCrtpBase + { + using type = bool; + StringView type_name() { return "a boolean"; } + + Optional visit_bool(Json::Reader&, StringView, bool b) { return b; } + }; + + enum class AllowEmpty : bool + { + No, + Yes, + }; + + template + struct ArrayField : Json::VisitorCrtpBase> + { + using type = std::vector; + + StringView type_name() { return type_name_; } + + ArrayField(StringView type_name_, AllowEmpty allow_empty, T&& t = {}) : type_name_(type_name_), underlying_visitor_(static_cast(t)), allow_empty_(allow_empty) { } + + Optional visit_array(Json::Reader& r, StringView key, const Json::Array& arr) + { + if (allow_empty_ == AllowEmpty::No && arr.size() == 0) + { + return nullopt; + } + return r.array_elements(arr, key, underlying_visitor_); + } + + private: + StringView type_name_; + T underlying_visitor_; + AllowEmpty allow_empty_; + }; + + struct ParagraphField : Json::VisitorCrtpBase + { + using type = std::vector; + StringView type_name() { return "a string or array of strings"; } + + Optional> visit_string(Json::Reader&, StringView, StringView sv) + { + std::vector out; + out.push_back(sv.to_string()); + return out; + } + + Optional> visit_array(Json::Reader& r, StringView key, const Json::Array& arr) + { + return r.array_elements(arr, key, StringField{"a string"}); + } + }; + + struct IdentifierField : Json::VisitorCrtpBase + { + using type = std::string; + StringView type_name() { return "an identifier"; } + + // [a-z0-9]+(-[a-z0-9]+)*, plus not any of {prn, aux, nul, con, lpt[1-9], com[1-9], core, default} + static bool is_ident(StringView sv) + { + static const std::regex BASIC_IDENTIFIER = std::regex(R"([a-z0-9]+(-[a-z0-9]+)*)"); + + // we only check for lowercase in RESERVED since we already remove all + // strings with uppercase letters from the basic check + static const std::regex RESERVED = std::regex(R"(prn|aux|nul|con|(lpt|com)[1-9]|core|default)"); + + if (!std::regex_match(sv.begin(), sv.end(), BASIC_IDENTIFIER)) + { + return false; // we're not even in the shape of an identifier + } + + if (std::regex_match(sv.begin(), sv.end(), RESERVED)) + { + return false; // we're a reserved identifier + } + + return true; + } + + Optional visit_string(Json::Reader&, StringView, StringView sv) + { + if (is_ident(sv)) + { + return sv.to_string(); + } + else + { + return nullopt; + } + } + }; + + struct PackageNameField : Json::VisitorCrtpBase + { + using type = std::string; + StringView type_name() { return "a package name"; } + + static bool is_package_name(StringView sv) + { + if (sv.size() == 0) + { + return false; + } + + for (const auto& ident : Strings::split(sv, '.')) + { + if (!IdentifierField::is_ident(ident)) + { + return false; + } + } + + return true; + } + + Optional visit_string(Json::Reader&, StringView, StringView sv) + { + if (!is_package_name(sv)) + { + return nullopt; + } + return sv.to_string(); + } + }; + + // We "parse" this so that we can add actual license parsing at some point in the future + // without breaking anyone + struct LicenseExpressionField : Json::VisitorCrtpBase + { + using type = std::string; + StringView type_name() { return "an SPDX license expression"; } + + enum class Mode + { + ExpectExpression, + ExpectContinue, + ExpectException, + }; + + constexpr static StringView EXPRESSION_WORDS[] = { + "WITH", + "AND", + "OR", + }; + constexpr static StringView VALID_LICENSES[] = +#include "spdx-licenses.inc" + ; + + constexpr static StringView VALID_EXCEPTIONS[] = +#include "spdx-exceptions.inc" + ; + + Optional visit_string(Json::Reader&, StringView, StringView sv) + { + Mode mode = Mode::ExpectExpression; + size_t open_parens = 0; + std::string current_word; + + const auto check_current_word = [¤t_word, &mode] { + if (current_word.empty()) + { + return true; + } + + Span valid_ids; + bool case_sensitive = false; + switch (mode) + { + case Mode::ExpectExpression: + valid_ids = VALID_LICENSES; + mode = Mode::ExpectContinue; + // a single + is allowed on the end of licenses + if (current_word.back() == '+') + { + current_word.pop_back(); + } + break; + case Mode::ExpectContinue: + valid_ids = EXPRESSION_WORDS; + mode = Mode::ExpectExpression; + case_sensitive = true; + break; + case Mode::ExpectException: + valid_ids = VALID_EXCEPTIONS; + mode = Mode::ExpectContinue; + break; + } + + const auto equal = [&](StringView sv) { + if (case_sensitive) + { + return sv == current_word; + } + else + { + return Strings::case_insensitive_ascii_equals(sv, current_word); + } + }; + + if (std::find_if(valid_ids.begin(), valid_ids.end(), equal) == valid_ids.end()) + { + return false; + } + + if (current_word == "WITH") + { + mode = Mode::ExpectException; + } + + current_word.clear(); + return true; + }; + + for (const auto& ch : sv) + { + if (ch == ' ' || ch == '\t') + { + if (!check_current_word()) + { + return nullopt; + } + } + else if (ch == '(') + { + if (!check_current_word()) + { + return nullopt; + } + if (mode != Mode::ExpectExpression) + { + return nullopt; + } + ++open_parens; + } + else if (ch == ')') + { + if (!check_current_word()) + { + return nullopt; + } + if (mode != Mode::ExpectContinue) + { + return nullopt; + } + if (open_parens == 0) + { + return nullopt; + } + --open_parens; + } + else + { + current_word.push_back(ch); + } + } + + if (!check_current_word()) + { + return nullopt; + } + else + { + return sv.to_string(); + } + } + }; + + struct PlatformExprField : Json::VisitorCrtpBase + { + using type = PlatformExpression::Expr; + StringView type_name() { return "a platform expression"; } + + Optional visit_string(Json::Reader&, StringView, StringView sv) + { + auto opt = PlatformExpression::parse_platform_expression(sv, PlatformExpression::MultipleBinaryOperators::Deny); + if (auto res = opt.get()) + { + return std::move(*res); + } + else + { + Debug::print("Failed to parse platform expression: ", opt.error(), "\n"); + return nullopt; + } + } + }; + + struct DependencyField : Json::VisitorCrtpBase + { + using type = Dependency; + StringView type_name() { return "a dependency"; } + + constexpr static StringView NAME = "name"; + constexpr static StringView FEATURES = "features"; + constexpr static StringView DEFAULT_FEATURES = "default-features"; + constexpr static StringView PLATFORM = "platform"; + constexpr static StringView KNOWN_FIELDS[] = {NAME, FEATURES, DEFAULT_FEATURES, PLATFORM}; + + Optional visit_string(Json::Reader&, StringView, StringView sv) + { + if (!PackageNameField::is_package_name(sv)) + { + return nullopt; + } + + Dependency dep; + dep.name = sv.to_string(); + return dep; + } + + Optional visit_object(Json::Reader& r, StringView, const Json::Object& obj) + { + { + auto extra_fields = invalid_json_fields(obj, KNOWN_FIELDS); + if (!extra_fields.empty()) + { + r.error().add_extra_fields(type_name().to_string(), std::move(extra_fields)); + } + } + + Dependency dep; + r.required_object_field(type_name(), obj, NAME, dep.name, PackageNameField{}); + r.optional_object_field( + obj, FEATURES, dep.features, ArrayField{"an array of identifiers", AllowEmpty::Yes}); + + bool default_features = true; + r.optional_object_field(obj, DEFAULT_FEATURES, default_features, BooleanField{}); + if (!default_features) + { + dep.features.push_back("core"); + } + + r.optional_object_field(obj, PLATFORM, dep.platform, PlatformExprField{}); + + return dep; + } + }; + + struct FeatureField : Json::VisitorCrtpBase + { + using type = std::unique_ptr; + StringView type_name() { return "a feature"; } + + constexpr static StringView NAME = "name"; + constexpr static StringView DESCRIPTION = "description"; + constexpr static StringView DEPENDENCIES = "dependencies"; + + Optional> visit_object(Json::Reader& r, StringView, const Json::Object& obj) + { + auto feature = std::make_unique(); + + r.required_object_field(type_name(), obj, NAME, feature->name, IdentifierField{}); + r.required_object_field(type_name(), obj, DESCRIPTION, feature->description, ParagraphField{}); + r.optional_object_field(obj, + DEPENDENCIES, + feature->dependencies, + ArrayField{"an array of dependencies", AllowEmpty::Yes}); + + return std::move(feature); + } + }; + + Parse::ParseExpected SourceControlFile::parse_manifest_file(const fs::path& path_to_manifest, + const Json::Object& manifest) + { + struct JsonErr final : Json::ReaderError + { + ParseControlErrorInfo pcei; + + void add_missing_field(std::string&& type, std::string&& key) override + { + pcei.missing_fields[std::move(type)].push_back(std::move(key)); + } + void add_expected_type(std::string&& key, std::string&& expected_type) override + { + pcei.expected_types.emplace(std::move(key), std::move(expected_type)); + } + void add_extra_fields(std::string&& type, std::vector&& fields) override + { + if (!fields.empty()) + { + auto& fields_for_type = pcei.extra_fields[std::move(type)]; + fields_for_type.insert(fields_for_type.end(), fields.begin(), fields.end()); + } + } + void add_mutually_exclusive_fields(std::string&& type, std::vector&& fields) override + { + if (!fields.empty()) + { + auto& fields_for_type = pcei.mutually_exclusive_fields[std::move(type)]; + fields_for_type.insert(fields_for_type.end(), fields.begin(), fields.end()); + } + } + } err = {}; + auto visit = Json::Reader{&err}; + + err.pcei.name = path_to_manifest.u8string(); + { + auto extra_fields = invalid_json_fields(manifest, get_list_of_manifest_fields()); + if (!extra_fields.empty()) + { + err.pcei.extra_fields["manifest"] = std::move(extra_fields); + } + } + + auto control_file = std::make_unique(); + control_file->core_paragraph = std::make_unique(); + + auto& spgh = control_file->core_paragraph; + + constexpr static StringView type_name = "vcpkg.json"; + visit.required_object_field(type_name, manifest, ManifestFields::NAME, spgh->name, IdentifierField{}); + visit.required_object_field( + type_name, manifest, ManifestFields::VERSION, spgh->version, StringField{"a version"}); + visit.optional_object_field(manifest, ManifestFields::MAINTAINERS, spgh->maintainers, ParagraphField{}); + visit.optional_object_field(manifest, ManifestFields::DESCRIPTION, spgh->description, ParagraphField{}); + visit.optional_object_field(manifest, ManifestFields::HOMEPAGE, spgh->homepage, StringField{"a url"}); + visit.optional_object_field(manifest, ManifestFields::DOCUMENTATION, spgh->documentation, StringField{"a url"}); + visit.optional_object_field(manifest, ManifestFields::LICENSE, spgh->license, LicenseExpressionField{}); + visit.optional_object_field(manifest, + ManifestFields::DEPENDENCIES, + spgh->dependencies, + ArrayField{"an array of dependencies", AllowEmpty::Yes}); + + if (manifest.contains(ManifestFields::DEV_DEPENDENCIES)) + { + System::print2(System::Color::error, "dev_dependencies are not yet supported"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + visit.optional_object_field(manifest, ManifestFields::SUPPORTS, spgh->supports_expression, PlatformExprField{}); + + visit.optional_object_field(manifest, + ManifestFields::DEFAULT_FEATURES, + spgh->default_features, + ArrayField{"an array of identifiers", AllowEmpty::Yes}); + + visit.optional_object_field(manifest, + ManifestFields::FEATURES, + control_file->feature_paragraphs, + ArrayField{"an array of feature definitions", AllowEmpty::Yes}); + + if (err.pcei.has_error()) + { + return std::make_unique(std::move(err.pcei)); + } + + return std::move(control_file); + } + Optional SourceControlFile::find_feature(const std::string& featurename) const { auto it = Util::find_if(feature_paragraphs, @@ -211,10 +824,10 @@ namespace vcpkg { if (featurename == "core") { - return core_paragraph->depends; + return core_paragraph->dependencies; } else if (auto p_feature = find_feature(featurename).get()) - return p_feature->depends; + return p_feature->dependencies; else return nullopt; } @@ -226,11 +839,9 @@ namespace vcpkg std::vector ret; for (auto&& dep : deps) { - const auto& qualifier = dep.qualifier; - if (qualifier.empty() || - evaluate_expression(qualifier, {cmake_vars, t.canonical_name()}).value_or_exit(VCPKG_LINE_INFO)) + if (dep.platform.evaluate(cmake_vars)) { - ret.emplace_back(FullPackageSpec({dep.depend.name, t}, dep.depend.features)); + ret.emplace_back(FullPackageSpec({dep.name, t}, dep.features)); } } return ret; diff --git a/toolsrc/src/vcpkg/spdx-exceptions.inc b/toolsrc/src/vcpkg/spdx-exceptions.inc new file mode 100644 index 0000000000..c6ef04b702 --- /dev/null +++ b/toolsrc/src/vcpkg/spdx-exceptions.inc @@ -0,0 +1,45 @@ +// Data downloaded from https://raw.githubusercontent.com/spdx/license-list-data/a3cab5c04eaf399ea8ee07ac69c749a9ad6a3f17/json/exceptions.json +// Generated by scripts/Generate-SpdxLicenseList.ps1 +{ + "GCC-exception-2.0", + "openvpn-openssl-exception", + "Nokia-Qt-exception-1.1", + "GPL-3.0-linking-exception", + "Fawkes-Runtime-exception", + "u-boot-exception-2.0", + "PS-or-PDF-font-exception-20170817", + "gnu-javamail-exception", + "LGPL-3.0-linking-exception", + "DigiRule-FOSS-exception", + "LLVM-exception", + "Linux-syscall-note", + "GPL-3.0-linking-source-exception", + "Qwt-exception-1.0", + "389-exception", + "mif-exception", + "eCos-exception-2.0", + "CLISP-exception-2.0", + "Bison-exception-2.2", + "Libtool-exception", + "LZMA-exception", + "OpenJDK-assembly-exception-1.0", + "Font-exception-2.0", + "OCaml-LGPL-linking-exception", + "GCC-exception-3.1", + "Bootloader-exception", + "SHL-2.0", + "Classpath-exception-2.0", + "Swift-exception", + "Autoconf-exception-2.0", + "FLTK-exception", + "freertos-exception-2.0", + "Universal-FOSS-exception-1.0", + "WxWindows-exception-3.1", + "OCCT-exception-1.0", + "Autoconf-exception-3.0", + "i2p-gpl-java-exception", + "GPL-CC-1.0", + "Qt-LGPL-exception-1.1", + "SHL-2.1", + "Qt-GPL-exception-1.0", +} diff --git a/toolsrc/src/vcpkg/spdx-licenses.inc b/toolsrc/src/vcpkg/spdx-licenses.inc new file mode 100644 index 0000000000..ad3523934c --- /dev/null +++ b/toolsrc/src/vcpkg/spdx-licenses.inc @@ -0,0 +1,426 @@ +// Data downloaded from https://raw.githubusercontent.com/spdx/license-list-data/a3cab5c04eaf399ea8ee07ac69c749a9ad6a3f17/json/licenses.json +// Generated by scripts/Generate-SpdxLicenseList.ps1 +{ + "0BSD", + "AAL", + "ADSL", + "AFL-1.1", + "AFL-1.2", + "AFL-2.0", + "AFL-2.1", + "AFL-3.0", + "AGPL-1.0", + "AGPL-1.0-only", + "AGPL-1.0-or-later", + "AGPL-3.0", + "AGPL-3.0-only", + "AGPL-3.0-or-later", + "AMDPLPA", + "AML", + "AMPAS", + "ANTLR-PD", + "APAFML", + "APL-1.0", + "APSL-1.0", + "APSL-1.1", + "APSL-1.2", + "APSL-2.0", + "Abstyles", + "Adobe-2006", + "Adobe-Glyph", + "Afmparse", + "Aladdin", + "Apache-1.0", + "Apache-1.1", + "Apache-2.0", + "Artistic-1.0", + "Artistic-1.0-Perl", + "Artistic-1.0-cl8", + "Artistic-2.0", + "BSD-1-Clause", + "BSD-2-Clause", + "BSD-2-Clause-FreeBSD", + "BSD-2-Clause-NetBSD", + "BSD-2-Clause-Patent", + "BSD-3-Clause", + "BSD-3-Clause-Attribution", + "BSD-3-Clause-Clear", + "BSD-3-Clause-LBNL", + "BSD-3-Clause-No-Nuclear-License", + "BSD-3-Clause-No-Nuclear-License-2014", + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-3-Clause-Open-MPI", + "BSD-4-Clause", + "BSD-4-Clause-UC", + "BSD-Protection", + "BSD-Source-Code", + "BSL-1.0", + "Bahyph", + "Barr", + "Beerware", + "BitTorrent-1.0", + "BitTorrent-1.1", + "BlueOak-1.0.0", + "Borceux", + "CAL-1.0", + "CAL-1.0-Combined-Work-Exception", + "CATOSL-1.1", + "CC-BY-1.0", + "CC-BY-2.0", + "CC-BY-2.5", + "CC-BY-3.0", + "CC-BY-4.0", + "CC-BY-NC-1.0", + "CC-BY-NC-2.0", + "CC-BY-NC-2.5", + "CC-BY-NC-3.0", + "CC-BY-NC-4.0", + "CC-BY-NC-ND-1.0", + "CC-BY-NC-ND-2.0", + "CC-BY-NC-ND-2.5", + "CC-BY-NC-ND-3.0", + "CC-BY-NC-ND-4.0", + "CC-BY-NC-SA-1.0", + "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.5", + "CC-BY-NC-SA-3.0", + "CC-BY-NC-SA-4.0", + "CC-BY-ND-1.0", + "CC-BY-ND-2.0", + "CC-BY-ND-2.5", + "CC-BY-ND-3.0", + "CC-BY-ND-4.0", + "CC-BY-SA-1.0", + "CC-BY-SA-2.0", + "CC-BY-SA-2.5", + "CC-BY-SA-3.0", + "CC-BY-SA-4.0", + "CC-PDDC", + "CC0-1.0", + "CDDL-1.0", + "CDDL-1.1", + "CDLA-Permissive-1.0", + "CDLA-Sharing-1.0", + "CECILL-1.0", + "CECILL-1.1", + "CECILL-2.0", + "CECILL-2.1", + "CECILL-B", + "CECILL-C", + "CERN-OHL-1.1", + "CERN-OHL-1.2", + "CERN-OHL-P-2.0", + "CERN-OHL-S-2.0", + "CERN-OHL-W-2.0", + "CNRI-Jython", + "CNRI-Python", + "CNRI-Python-GPL-Compatible", + "CPAL-1.0", + "CPL-1.0", + "CPOL-1.02", + "CUA-OPL-1.0", + "Caldera", + "ClArtistic", + "Condor-1.1", + "Crossword", + "CrystalStacker", + "Cube", + "D-FSL-1.0", + "DOC", + "DSDP", + "Dotseqn", + "ECL-1.0", + "ECL-2.0", + "EFL-1.0", + "EFL-2.0", + "EPL-1.0", + "EPL-2.0", + "EUDatagrid", + "EUPL-1.0", + "EUPL-1.1", + "EUPL-1.2", + "Entessa", + "ErlPL-1.1", + "Eurosym", + "FSFAP", + "FSFUL", + "FSFULLR", + "FTL", + "Fair", + "Frameworx-1.0", + "FreeImage", + "GFDL-1.1", + "GFDL-1.1-only", + "GFDL-1.1-or-later", + "GFDL-1.2", + "GFDL-1.2-only", + "GFDL-1.2-or-later", + "GFDL-1.3", + "GFDL-1.3-only", + "GFDL-1.3-or-later", + "GL2PS", + "GPL-1.0", + "GPL-1.0+", + "GPL-1.0-only", + "GPL-1.0-or-later", + "GPL-2.0", + "GPL-2.0+", + "GPL-2.0-only", + "GPL-2.0-or-later", + "GPL-2.0-with-GCC-exception", + "GPL-2.0-with-autoconf-exception", + "GPL-2.0-with-bison-exception", + "GPL-2.0-with-classpath-exception", + "GPL-2.0-with-font-exception", + "GPL-3.0", + "GPL-3.0+", + "GPL-3.0-only", + "GPL-3.0-or-later", + "GPL-3.0-with-GCC-exception", + "GPL-3.0-with-autoconf-exception", + "Giftware", + "Glide", + "Glulxe", + "HPND", + "HPND-sell-variant", + "HaskellReport", + "Hippocratic-2.1", + "IBM-pibs", + "ICU", + "IJG", + "IPA", + "IPL-1.0", + "ISC", + "ImageMagick", + "Imlib2", + "Info-ZIP", + "Intel", + "Intel-ACPI", + "Interbase-1.0", + "JPNIC", + "JSON", + "JasPer-2.0", + "LAL-1.2", + "LAL-1.3", + "LGPL-2.0", + "LGPL-2.0+", + "LGPL-2.0-only", + "LGPL-2.0-or-later", + "LGPL-2.1", + "LGPL-2.1+", + "LGPL-2.1-only", + "LGPL-2.1-or-later", + "LGPL-3.0", + "LGPL-3.0+", + "LGPL-3.0-only", + "LGPL-3.0-or-later", + "LGPLLR", + "LPL-1.0", + "LPL-1.02", + "LPPL-1.0", + "LPPL-1.1", + "LPPL-1.2", + "LPPL-1.3a", + "LPPL-1.3c", + "Latex2e", + "Leptonica", + "LiLiQ-P-1.1", + "LiLiQ-R-1.1", + "LiLiQ-Rplus-1.1", + "Libpng", + "Linux-OpenIB", + "MIT", + "MIT-0", + "MIT-CMU", + "MIT-advertising", + "MIT-enna", + "MIT-feh", + "MITNFA", + "MPL-1.0", + "MPL-1.1", + "MPL-2.0", + "MPL-2.0-no-copyleft-exception", + "MS-PL", + "MS-RL", + "MTLL", + "MakeIndex", + "MirOS", + "Motosoto", + "MulanPSL-1.0", + "MulanPSL-2.0", + "Multics", + "Mup", + "NASA-1.3", + "NBPL-1.0", + "NCGL-UK-2.0", + "NCSA", + "NGPL", + "NLOD-1.0", + "NLPL", + "NOSL", + "NPL-1.0", + "NPL-1.1", + "NPOSL-3.0", + "NRL", + "NTP", + "NTP-0", + "Naumen", + "Net-SNMP", + "NetCDF", + "Newsletr", + "Nokia", + "Noweb", + "Nunit", + "O-UDA-1.0", + "OCCT-PL", + "OCLC-2.0", + "ODC-By-1.0", + "ODbL-1.0", + "OFL-1.0", + "OFL-1.0-RFN", + "OFL-1.0-no-RFN", + "OFL-1.1", + "OFL-1.1-RFN", + "OFL-1.1-no-RFN", + "OGC-1.0", + "OGL-Canada-2.0", + "OGL-UK-1.0", + "OGL-UK-2.0", + "OGL-UK-3.0", + "OGTSL", + "OLDAP-1.1", + "OLDAP-1.2", + "OLDAP-1.3", + "OLDAP-1.4", + "OLDAP-2.0", + "OLDAP-2.0.1", + "OLDAP-2.1", + "OLDAP-2.2", + "OLDAP-2.2.1", + "OLDAP-2.2.2", + "OLDAP-2.3", + "OLDAP-2.4", + "OLDAP-2.5", + "OLDAP-2.6", + "OLDAP-2.7", + "OLDAP-2.8", + "OML", + "OPL-1.0", + "OSET-PL-2.1", + "OSL-1.0", + "OSL-1.1", + "OSL-2.0", + "OSL-2.1", + "OSL-3.0", + "OpenSSL", + "PDDL-1.0", + "PHP-3.0", + "PHP-3.01", + "PSF-2.0", + "Parity-6.0.0", + "Parity-7.0.0", + "Plexus", + "PolyForm-Noncommercial-1.0.0", + "PolyForm-Small-Business-1.0.0", + "PostgreSQL", + "Python-2.0", + "QPL-1.0", + "Qhull", + "RHeCos-1.1", + "RPL-1.1", + "RPL-1.5", + "RPSL-1.0", + "RSA-MD", + "RSCPL", + "Rdisc", + "Ruby", + "SAX-PD", + "SCEA", + "SGI-B-1.0", + "SGI-B-1.1", + "SGI-B-2.0", + "SHL-0.5", + "SHL-0.51", + "SISSL", + "SISSL-1.2", + "SMLNJ", + "SMPPL", + "SNIA", + "SPL-1.0", + "SSH-OpenSSH", + "SSH-short", + "SSPL-1.0", + "SWL", + "Saxpath", + "Sendmail", + "Sendmail-8.23", + "SimPL-2.0", + "Sleepycat", + "Spencer-86", + "Spencer-94", + "Spencer-99", + "StandardML-NJ", + "SugarCRM-1.1.3", + "TAPR-OHL-1.0", + "TCL", + "TCP-wrappers", + "TMate", + "TORQUE-1.1", + "TOSL", + "TU-Berlin-1.0", + "TU-Berlin-2.0", + "UCL-1.0", + "UPL-1.0", + "Unicode-DFS-2015", + "Unicode-DFS-2016", + "Unicode-TOU", + "Unlicense", + "VOSTROM", + "VSL-1.0", + "Vim", + "W3C", + "W3C-19980720", + "W3C-20150513", + "WTFPL", + "Watcom-1.0", + "Wsuipa", + "X11", + "XFree86-1.1", + "XSkat", + "Xerox", + "Xnet", + "YPL-1.0", + "YPL-1.1", + "ZPL-1.1", + "ZPL-2.0", + "ZPL-2.1", + "Zed", + "Zend-2.0", + "Zimbra-1.3", + "Zimbra-1.4", + "Zlib", + "blessing", + "bzip2-1.0.5", + "bzip2-1.0.6", + "copyleft-next-0.3.0", + "copyleft-next-0.3.1", + "curl", + "diffmark", + "dvipdfm", + "eCos-2.0", + "eGenix", + "etalab-2.0", + "gSOAP-1.3b", + "gnuplot", + "iMatix", + "libpng-2.0", + "libselinux-1.0", + "libtiff", + "mpich2", + "psfrag", + "psutils", + "wxWindows", + "xinetd", + "xpp", + "zlib-acknowledgement", +} diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 2f29fb6c6d..3c6e5dc7a8 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -12,7 +12,7 @@ namespace vcpkg static const std::string STATUS = "Status"; } - StatusParagraph::StatusParagraph() noexcept : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} + StatusParagraph::StatusParagraph() noexcept : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) { } void serialize(const StatusParagraph& pgh, std::string& out_str) { @@ -92,10 +92,10 @@ namespace vcpkg std::map> deps; - deps.emplace("core", Util::fmap(core->package.depends, extract_deps)); + deps.emplace("core", Util::fmap(core->package.dependencies, extract_deps)); for (const StatusParagraph* const& feature : features) - deps.emplace(feature->package.feature, Util::fmap(feature->package.depends, extract_deps)); + deps.emplace(feature->package.feature, Util::fmap(feature->package.dependencies, extract_deps)); return deps; } @@ -106,11 +106,11 @@ namespace vcpkg // Todo: make this unneeded by collapsing all package dependencies into the core package std::vector deps; for (auto&& feature : features) - for (auto&& dep : feature->package.depends) + for (auto&& dep : feature->package.dependencies) deps.push_back(dep); // Add the core paragraph dependencies to the list - for (auto&& dep : core->package.depends) + for (auto&& dep : core->package.dependencies) deps.push_back(dep); Util::erase_remove_if(deps, [&](const std::string& pspec) { return pspec == spec().name(); }); diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp index 91058a473d..a4d4c2185c 100644 --- a/toolsrc/src/vcpkg/statusparagraphs.cpp +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -35,9 +35,12 @@ namespace vcpkg if (p->package.spec.name() == spec.name() && p->package.spec.triplet() == spec.triplet() && p->is_installed()) { - if (p->package.is_feature()) { + if (p->package.is_feature()) + { ipv.features.emplace_back(p.get()); - } else { + } + else + { Checks::check_exit(VCPKG_LINE_INFO, ipv.core == nullptr); ipv.core = p.get(); } @@ -55,8 +58,8 @@ namespace vcpkg { if (feature == "core") { - // The core feature maps to .feature == "" - return find(name, triplet, ""); + // The core feature maps to .feature is empty + return find(name, triplet, {}); } return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { const PackageSpec& spec = pgh->package.spec; diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index f657a4aefc..717a7dbcf8 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -392,7 +392,7 @@ git version 2.17.1.windows.2 struct IfwInstallerBaseProvider : ToolProvider { - std::string m_exe = ""; + std::string m_exe; std::string m_toolname = "installerbase"; virtual const std::string& tool_data_name() const override { return m_toolname; } diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 556f9125c2..aa8d654e3b 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -57,7 +57,7 @@ namespace vcpkg::Update const StatusParagraphs status_db = database_load_check(paths); - PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports); const auto outdated_packages = SortedVector(find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index fd044c2981..45db0c2e7c 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -8,14 +9,62 @@ namespace vcpkg { + static void set_from_feature_flag(const std::vector& flags, StringView flag, Optional& place) + { + if (!place.has_value()) + { + const auto not_flag = [flag](const std::string& el) { + return !el.empty() && el[0] == '-' && flag == StringView{el.data() + 1, el.data() + el.size()}; + }; + + if (std::find(flags.begin(), flags.end(), flag) != flags.end()) + { + place = true; + } + if (std::find_if(flags.begin(), flags.end(), not_flag) != flags.end()) + { + if (place.has_value()) + { + System::printf( + System::Color::error, "Error: both %s and -%s were specified as feature flags\n", flag, flag); + Metrics::g_metrics.lock()->track_property("error", "error feature flag +-" + flag.to_string()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + place = false; + } + } + } + + static void parse_feature_flags(const std::vector& flags, VcpkgCmdArguments& args) + { + // NOTE: when these features become default, switch the value_or(false) to value_or(true) + struct FeatureFlag + { + StringView flag_name; + Optional& local_option; + }; + + const FeatureFlag flag_descriptions[] = { + {VcpkgCmdArguments::BINARY_CACHING_FEATURE, args.binary_caching}, + {VcpkgCmdArguments::MANIFEST_MODE_FEATURE, args.manifest_mode}, + {VcpkgCmdArguments::COMPILER_TRACKING_FEATURE, args.compiler_tracking}, + }; + + for (const auto& desc : flag_descriptions) + { + set_from_feature_flag(flags, desc.flag_name, desc.local_option); + } + } + static void parse_value(const std::string* arg_begin, const std::string* arg_end, - const std::string& option_name, + StringView option_name, std::unique_ptr& option_field) { if (arg_begin == arg_end) { - System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); + System::print2(System::Color::error, "Error: expected value after --", option_name, '\n'); Metrics::g_metrics.lock()->track_property("error", "error option name"); print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); @@ -23,7 +72,7 @@ namespace vcpkg if (option_field != nullptr) { - System::print2(System::Color::error, "Error: ", option_name, " specified multiple times\n"); + System::print2(System::Color::error, "Error: --", option_name, " specified multiple times\n"); Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); @@ -32,22 +81,22 @@ namespace vcpkg option_field = std::make_unique(*arg_begin); } - static void parse_cojoined_value(std::string new_value, - const std::string& option_name, + static void parse_cojoined_value(StringView new_value, + StringView option_name, std::unique_ptr& option_field) { if (nullptr != option_field) { - System::printf(System::Color::error, "Error: %s specified multiple times\n", option_name); + System::printf(System::Color::error, "Error: --%s specified multiple times\n", option_name); Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } - option_field = std::make_unique(std::move(new_value)); + option_field = std::make_unique(new_value.begin(), new_value.end()); } - static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) + static void parse_switch(bool new_setting, StringView option_name, Optional& option_field) { if (option_field && option_field != new_setting) { @@ -59,30 +108,11 @@ namespace vcpkg option_field = new_setting; } - static void parse_cojoined_multivalue(std::string new_value, - const std::string& option_name, - std::unique_ptr>& option_field) - { - if (new_value.empty()) - { - System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); - Metrics::g_metrics.lock()->track_property("error", "error option name"); - print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (!option_field) - { - option_field = std::make_unique>(); - } - option_field->emplace_back(std::move(new_value)); - } - - static void parse_cojoined_multivalue(std::string new_value, - const std::string& option_name, + static void parse_cojoined_multivalue(StringView new_value, + StringView option_name, std::vector& option_field) { - if (new_value.empty()) + if (new_value.size() == 0) { System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); Metrics::g_metrics.lock()->track_property("error", "error option name"); @@ -90,7 +120,25 @@ namespace vcpkg Checks::exit_fail(VCPKG_LINE_INFO); } - option_field.emplace_back(std::move(new_value)); + option_field.emplace_back(new_value.begin(), new_value.end()); + } + + static void parse_cojoined_list_multivalue(StringView new_value, + StringView option_name, + std::vector& option_field) + { + if (new_value.size() == 0) + { + System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); + Metrics::g_metrics.lock()->track_property("error", "error option name"); + print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + for (const auto& v : Strings::split(new_value, ',')) + { + option_field.emplace_back(v.begin(), v.end()); + } } VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const Files::Filesystem& fs, @@ -127,186 +175,193 @@ namespace vcpkg return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); } + // returns true if this does parse this argument as this option + // REQUIRES: Strings::starts_with(argument, "--"); + template + static bool try_parse_argument_as_option(StringView option, StringView argument, T& place, F parser) + { + // remove the first two '-'s + const auto arg = argument.substr(2); + if (arg.size() <= option.size() + 1) + { + // it is impossible for this argument to be this option + return false; + } + + if (Strings::starts_with(arg, option) && arg.byte_at_index(option.size()) == '=') + { + parser(arg.substr(option.size() + 1), option, place); + return true; + } + + return false; + } + + // returns true if this does parse this argument as this option + // REQUIRES: Strings::starts_with(argument, "--"); + template + static bool try_parse_argument_as_switch(StringView option, StringView argument, T& place) + { + // remove the first two '-'s + const auto arg = argument.substr(2); + + if (arg == option) + { + parse_switch(true, option, place); + return true; + } + + if (Strings::starts_with(arg, "no-") && arg.substr(3) == option) + { + parse_switch(false, option, place); + return true; + } + + return false; + } + VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end) { VcpkgCmdArguments args; + std::vector feature_flags; - for (; arg_begin != arg_end; ++arg_begin) + for (auto it = arg_begin; it != arg_end; ++it) { - std::string arg = *arg_begin; + std::string arg = *it; if (arg.empty()) { continue; } - if (arg[0] == '-' && arg[1] != '-') + if (arg.size() >= 2 && arg[0] == '-' && arg[1] != '-') { Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); } - if (arg[0] == '-' && arg[1] == '-') + if (arg.size() < 2 || arg[0] != '-') { - // make argument case insensitive before the first = - auto& f = std::use_facet>(std::locale()); - auto first_eq = std::find(std::begin(arg), std::end(arg), '='); - f.tolower(&arg[0], &arg[0] + (first_eq - std::begin(arg))); - // command switch - if (arg == "--vcpkg-root") + if (args.command.empty()) { - ++arg_begin; - parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); - continue; - } - if (Strings::starts_with(arg, "--x-buildtrees-root=")) - { - parse_cojoined_value(arg.substr(sizeof("--x-buildtrees-root=") - 1), - "--x-buildtrees-root", - args.buildtrees_root_dir); - continue; - } - if (Strings::starts_with(arg, "--downloads-root=")) - { - parse_cojoined_value( - arg.substr(sizeof("--downloads-root=") - 1), "--downloads-root", args.downloads_root_dir); - continue; - } - if (Strings::starts_with(arg, "--x-install-root=")) - { - parse_cojoined_value( - arg.substr(sizeof("--x-install-root=") - 1), "--x-install-root=", args.install_root_dir); - continue; - } - if (Strings::starts_with(arg, "--x-packages-root=")) - { - parse_cojoined_value( - arg.substr(sizeof("--x-packages-root=") - 1), "--x-packages-root=", args.packages_root_dir); - continue; - } - if (Strings::starts_with(arg, "--x-scripts-root=")) - { - parse_cojoined_value( - arg.substr(sizeof("--x-scripts-root=") - 1), "--x-scripts-root", args.scripts_root_dir); - continue; - } - if (arg == "--triplet") - { - ++arg_begin; - parse_value(arg_begin, arg_end, "--triplet", args.triplet); - continue; - } - if (Strings::starts_with(arg, "--overlay-ports=")) - { - parse_cojoined_multivalue( - arg.substr(sizeof("--overlay-ports=") - 1), "--overlay-ports", args.overlay_ports); - continue; - } - if (Strings::starts_with(arg, "--overlay-triplets=")) - { - parse_cojoined_multivalue( - arg.substr(sizeof("--overlay-triplets=") - 1), "--overlay-triplets", args.overlay_triplets); - continue; - } - if (Strings::starts_with(arg, "--x-binarysource=")) - { - parse_cojoined_multivalue( - arg.substr(sizeof("--x-binarysource=") - 1), "--x-binarysource", args.binarysources); - continue; - } - if (arg == "--debug") - { - parse_switch(true, "debug", args.debug); - continue; - } - if (arg == "--sendmetrics") - { - parse_switch(true, "sendmetrics", args.send_metrics); - continue; - } - if (arg == "--printmetrics") - { - parse_switch(true, "printmetrics", args.print_metrics); - continue; - } - if (arg == "--disable-metrics") - { - parse_switch(true, "disable-metrics", args.disable_metrics); - continue; - } - if (arg == "--no-sendmetrics") - { - parse_switch(false, "no-sendmetrics", args.send_metrics); - continue; - } - if (arg == "--no-printmetrics") - { - parse_switch(false, "no-printmetrics", args.print_metrics); - continue; - } - if (arg == "--no-disable-metrics") - { - parse_switch(false, "no-disable-metrics", args.disable_metrics); - continue; - } - if (arg == "--featurepackages") - { - parse_switch(true, "featurepackages", args.feature_packages); - continue; - } - if (arg == "--no-featurepackages") - { - parse_switch(false, "featurepackages", args.feature_packages); - continue; - } - if (arg == "--binarycaching") - { - parse_switch(true, "binarycaching", args.binary_caching); - continue; - } - if (arg == "--no-binarycaching") - { - parse_switch(false, "no-binarycaching", args.binary_caching); - continue; - } - - const auto eq_pos = arg.find('='); - if (eq_pos != std::string::npos) - { - const auto& key = arg.substr(0, eq_pos); - const auto& value = arg.substr(eq_pos + 1); - - auto it = args.optional_command_arguments.find(key); - if (args.optional_command_arguments.end() == it) - { - args.optional_command_arguments.emplace(key, std::vector{value}); - } - else - { - if (auto* maybe_values = it->second.get()) - { - maybe_values->emplace_back(value); - } - } + args.command = std::move(arg); } else { - args.optional_command_arguments.emplace(arg, nullopt); + args.command_arguments.push_back(std::move(arg)); } continue; } - if (args.command.empty()) + // arg[0] == '-' && arg[1] == '-' + // make argument case insensitive before the first = + auto first_eq = std::find(std::begin(arg), std::end(arg), '='); + Strings::ascii_to_lowercase(std::begin(arg), first_eq); + + // command switch + if (arg.substr(2) == VCPKG_ROOT_DIR_ARG) { - args.command = arg; + ++it; + parse_value(it, arg_end, VCPKG_ROOT_DIR_ARG, args.vcpkg_root_dir); + continue; + } + if (arg.substr(2) == TRIPLET_ARG) + { + ++it; + parse_value(it, arg_end, TRIPLET_ARG, args.triplet); + continue; + } + + constexpr static std::pair VcpkgCmdArguments::*> + cojoined_values[] = { + {MANIFEST_ROOT_DIR_ARG, &VcpkgCmdArguments::manifest_root_dir}, + {BUILDTREES_ROOT_DIR_ARG, &VcpkgCmdArguments::buildtrees_root_dir}, + {DOWNLOADS_ROOT_DIR_ARG, &VcpkgCmdArguments::downloads_root_dir}, + {INSTALL_ROOT_DIR_ARG, &VcpkgCmdArguments::install_root_dir}, + {PACKAGES_ROOT_DIR_ARG, &VcpkgCmdArguments::packages_root_dir}, + {SCRIPTS_ROOT_DIR_ARG, &VcpkgCmdArguments::scripts_root_dir}, + }; + + constexpr static std::pair VcpkgCmdArguments::*> + cojoined_multivalues[] = { + {OVERLAY_PORTS_ARG, &VcpkgCmdArguments::overlay_ports}, + {OVERLAY_TRIPLETS_ARG, &VcpkgCmdArguments::overlay_triplets}, + {BINARY_SOURCES_ARG, &VcpkgCmdArguments::binary_sources}, + }; + + constexpr static std::pair VcpkgCmdArguments::*> switches[] = { + {DEBUG_SWITCH, &VcpkgCmdArguments::debug}, + {DISABLE_METRICS_SWITCH, &VcpkgCmdArguments::disable_metrics}, + {SEND_METRICS_SWITCH, &VcpkgCmdArguments::send_metrics}, + {PRINT_METRICS_SWITCH, &VcpkgCmdArguments::print_metrics}, + {FEATURE_PACKAGES_SWITCH, &VcpkgCmdArguments::feature_packages}, + {BINARY_CACHING_SWITCH, &VcpkgCmdArguments::binary_caching}, + }; + + bool found = false; + for (const auto& pr : cojoined_values) + { + if (try_parse_argument_as_option(pr.first, arg, args.*pr.second, parse_cojoined_value)) + { + found = true; + break; + } + } + if (found) continue; + + for (const auto& pr : cojoined_multivalues) + { + if (try_parse_argument_as_option(pr.first, arg, args.*pr.second, parse_cojoined_multivalue)) + { + found = true; + break; + } + } + if (found) continue; + + if (try_parse_argument_as_option(FEATURE_FLAGS_ARG, arg, feature_flags, parse_cojoined_list_multivalue)) + { + continue; + } + + for (const auto& pr : switches) + { + if (try_parse_argument_as_switch(pr.first, arg, args.*pr.second)) + { + found = true; + break; + } + } + if (found) continue; + + const auto eq_pos = arg.find('='); + if (eq_pos != std::string::npos) + { + const auto& key = arg.substr(0, eq_pos); + const auto& value = arg.substr(eq_pos + 1); + + auto key_it = args.optional_command_arguments.find(key); + if (key_it == args.optional_command_arguments.end()) + { + args.optional_command_arguments.emplace(key, std::vector{value}); + } + else + { + if (auto* maybe_values = key_it->second.get()) + { + maybe_values->emplace_back(value); + } + } } else { - args.command_arguments.push_back(arg); + args.optional_command_arguments.emplace(arg, nullopt); } } + parse_feature_flags(feature_flags, args); + return args; } @@ -523,48 +578,39 @@ namespace vcpkg void VcpkgCmdArguments::append_common_options(HelpTableFormatter& table) { - table.format("--triplet ", "Specify the target architecture triplet. See 'vcpkg help triplet'"); + constexpr static auto opt = [](StringView arg, StringView joiner, StringView value) { + return Strings::format("--%s%s%s", arg, joiner, value); + }; + + table.format(opt(TRIPLET_ARG, " ", ""), "Specify the target architecture triplet. See 'vcpkg help triplet'"); table.format("", "(default: " + format_environment_variable("VCPKG_DEFAULT_TRIPLET") + ')'); - table.format("--overlay-ports=", "Specify directories to be used when searching for ports"); - table.format("--overlay-triplets=", "Specify directories containing triplets files"); - table.format("--downloads-root=", "Specify the downloads root directory"); + table.format(opt(OVERLAY_PORTS_ARG, "=", ""), "Specify directories to be used when searching for ports"); + table.format(opt(OVERLAY_TRIPLETS_ARG, "=", ""), "Specify directories containing triplets files"); + table.format(opt(DOWNLOADS_ROOT_DIR_ARG, "=", ""), "Specify the downloads root directory"); table.format("", "(default: " + format_environment_variable("VCPKG_DOWNLOADS") + ')'); - table.format("--vcpkg-root ", "Specify the vcpkg root directory"); + table.format(opt(VCPKG_ROOT_DIR_ARG, " ", ""), "Specify the vcpkg root directory"); table.format("", "(default: " + format_environment_variable("VCPKG_ROOT") + ')'); - table.format("--x-buildtrees-root=", "(Experimental) Specify the buildtrees root directory"); - table.format("--x-install-root=", "(Experimental) Specify the install root directory"); - table.format("--x-packages-root=", "(Experimental) Specify the packages root directory"); - table.format("--x-scripts-root=", "(Experimental) Specify the scripts root directory"); + table.format(opt(BUILDTREES_ROOT_DIR_ARG, "=", ""), + "(Experimental) Specify the buildtrees root directory"); + table.format(opt(INSTALL_ROOT_DIR_ARG, "=", ""), "(Experimental) Specify the install root directory"); + table.format(opt(PACKAGES_ROOT_DIR_ARG, "=", ""), "(Experimental) Specify the packages root directory"); + table.format(opt(SCRIPTS_ROOT_DIR_ARG, "=", ""), "(Experimental) Specify the scripts root directory"); } void VcpkgCmdArguments::imbue_from_environment() { if (!disable_metrics) { - const auto vcpkg_disable_metrics_env = System::get_environment_variable("VCPKG_DISABLE_METRICS"); - if (vcpkg_disable_metrics_env) + const auto vcpkg_disable_metrics_env = System::get_environment_variable(DISABLE_METRICS_ENV); + if (vcpkg_disable_metrics_env.has_value()) { disable_metrics = true; } } - const auto vcpkg_feature_flags_env = System::get_environment_variable("VCPKG_FEATURE_FLAGS"); - if (const auto unpacked = vcpkg_feature_flags_env.get()) - { - auto flags = Strings::split(*unpacked, ','); - if (!binary_caching && Util::Vectors::contains(flags, "binarycaching")) - { - binary_caching = true; - } - if (Util::Vectors::contains(flags, "compilertracking")) - { - compiler_tracking = true; - } - } - if (!triplet) { - const auto vcpkg_default_triplet_env = System::get_environment_variable("VCPKG_DEFAULT_TRIPLET"); + const auto vcpkg_default_triplet_env = System::get_environment_variable(TRIPLET_ENV); if (const auto unpacked = vcpkg_default_triplet_env.get()) { triplet = std::make_unique(*unpacked); @@ -573,7 +619,7 @@ namespace vcpkg if (!vcpkg_root_dir) { - const auto vcpkg_root_env = System::get_environment_variable("VCPKG_ROOT"); + const auto vcpkg_root_env = System::get_environment_variable(VCPKG_ROOT_DIR_ENV); if (const auto unpacked = vcpkg_root_env.get()) { vcpkg_root_dir = std::make_unique(*unpacked); @@ -582,15 +628,22 @@ namespace vcpkg if (!downloads_root_dir) { - const auto vcpkg_downloads_env = vcpkg::System::get_environment_variable("VCPKG_DOWNLOADS"); + const auto vcpkg_downloads_env = vcpkg::System::get_environment_variable(DOWNLOADS_ROOT_DIR_ENV); if (const auto unpacked = vcpkg_downloads_env.get()) { downloads_root_dir = std::make_unique(*unpacked); } } + const auto vcpkg_feature_flags_env = System::get_environment_variable(FEATURE_FLAGS_ENV); + if (const auto v = vcpkg_feature_flags_env.get()) { - const auto vcpkg_visual_studio_path_env = System::get_environment_variable("VCPKG_VISUAL_STUDIO_PATH"); + auto flags = Strings::split(*v, ','); + parse_feature_flags(flags, *this); + } + + { + const auto vcpkg_visual_studio_path_env = System::get_environment_variable(DEFAULT_VISUAL_STUDIO_PATH_ENV); if (const auto unpacked = vcpkg_visual_studio_path_env.get()) { default_visual_studio_path = std::make_unique(*unpacked); @@ -598,6 +651,48 @@ namespace vcpkg } } + void VcpkgCmdArguments::check_feature_flag_consistency() const + { + struct + { + StringView flag; + StringView option; + bool is_inconsistent; + } possible_inconsistencies[] = { + {BINARY_CACHING_FEATURE, BINARY_SOURCES_ARG, !binary_sources.empty() && !binary_caching.value_or(true)}, + {MANIFEST_MODE_FEATURE, MANIFEST_ROOT_DIR_ARG, manifest_root_dir && !manifest_mode.value_or(true)}, + }; + for (const auto& el : possible_inconsistencies) + { + if (el.is_inconsistent) + { + System::printf(System::Color::warning, + "Warning: %s feature specifically turned off, but --%s was specified.\n", + el.flag, + el.option); + System::printf(System::Color::warning, "Warning: Defaulting to %s being on.\n", el.flag); + Metrics::g_metrics.lock()->track_property( + "warning", Strings::format("warning %s alongside %s", el.flag, el.option)); + } + } + } + + void VcpkgCmdArguments::track_feature_flag_metrics() const + { + struct + { + StringView flag; + bool enabled; + } flags[] = { + {BINARY_CACHING_FEATURE, binary_caching_enabled()} + }; + + for (const auto& flag : flags) + { + Metrics::g_metrics.lock()->track_feature(flag.flag.to_string(), flag.enabled); + } + } + std::string format_environment_variable(StringLiteral lit) { std::string result; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 0099854a9d..3d5a3bd6f2 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,20 @@ namespace return result; } + void uppercase_win32_drive_letter(fs::path& path) + { +#if defined(_WIN32) + const auto& nativePath = path.native(); + if (nativePath.size() > 2 && (nativePath[0] >= L'a' && nativePath[0] <= L'z') && nativePath[1] == L':') + { + auto uppercaseFirstLetter = std::move(path).native(); + uppercaseFirstLetter[0] = nativePath[0] - L'a' + L'A'; + path = uppercaseFirstLetter; + } +#endif + (void)path; + } + } // unnamed namespace namespace vcpkg @@ -84,11 +99,11 @@ namespace vcpkg std::unique_ptr m_tool_cache; Cache m_triplets_cache; Build::EnvCache m_env_cache; + + fs::SystemHandle file_lock_handle; }; } - VcpkgPaths::~VcpkgPaths() noexcept {} - VcpkgPaths::VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args) : m_pimpl(std::make_unique(filesystem, args.compiler_tracking_enabled())) { @@ -106,21 +121,73 @@ namespace vcpkg filesystem.canonical(VCPKG_LINE_INFO, System::get_exe_path_of_current_process()), ".vcpkg-root"); } } - -#if defined(_WIN32) - // fixup Windows drive letter to uppercase - const auto& nativeRoot = root.native(); - if (nativeRoot.size() > 2 && (nativeRoot[0] >= L'a' && nativeRoot[0] <= L'z') && nativeRoot[1] == L':') - { - auto uppercaseFirstLetter = nativeRoot; - uppercaseFirstLetter[0] = nativeRoot[0] - L'a' + L'A'; - root = uppercaseFirstLetter; - } -#endif // defined(_WIN32) - + uppercase_win32_drive_letter(root); Checks::check_exit(VCPKG_LINE_INFO, !root.empty(), "Error: Could not detect vcpkg-root."); Debug::print("Using vcpkg-root: ", root.u8string(), '\n'); + std::error_code ec; + const auto vcpkg_lock = root / ".vcpkg-root"; + m_pimpl->file_lock_handle = filesystem.try_take_exclusive_file_lock(vcpkg_lock, ec); + if (ec) + { + System::printf(System::Color::error, "Failed to take the filesystem lock on %s:\n", vcpkg_lock.u8string()); + System::printf(System::Color::error, " %s\n", ec.message()); + System::print2(System::Color::error, "Exiting now.\n"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (args.manifest_root_dir) + { + manifest_root_dir = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.manifest_root_dir)); + } + else + { + manifest_root_dir = filesystem.find_file_recursively_up(original_cwd, "vcpkg.json"); + } + uppercase_win32_drive_letter(manifest_root_dir); + + if (!manifest_root_dir.empty() && args.manifest_mode.value_or(true)) + { + Debug::print("Using manifest-root: ", root.u8string(), '\n'); + + installed = process_output_directory( + filesystem, manifest_root_dir, args.install_root_dir.get(), "vcpkg_installed", VCPKG_LINE_INFO); + } + else + { + // we ignore the manifest root dir if the user requests -manifest + if (!manifest_root_dir.empty() && !args.manifest_mode.has_value()) + { + System::print2(System::Color::warning, + "Warning: manifest-root detected at ", + manifest_root_dir.generic_u8string(), + ", but manifests are not enabled.\n"); + System::printf(System::Color::warning, + R"(If you wish to use manifest mode, you may do one of the following: + * Add the `%s` feature flag to the comma-separated environment + variable `%s`. + * Add the `%s` feature flag to the `--%s` option. + * Pass your manifest directory to the `--%s` option. +If you wish to silence this error and use classic mode, you can: + * Add the `-%s` feature flag to `%s`. + * Add the `-%s` feature flag to `--%s`. +)", + VcpkgCmdArguments::MANIFEST_MODE_FEATURE, + VcpkgCmdArguments::FEATURE_FLAGS_ENV, + VcpkgCmdArguments::MANIFEST_MODE_FEATURE, + VcpkgCmdArguments::FEATURE_FLAGS_ARG, + VcpkgCmdArguments::MANIFEST_ROOT_DIR_ARG, + VcpkgCmdArguments::MANIFEST_MODE_FEATURE, + VcpkgCmdArguments::FEATURE_FLAGS_ENV, + VcpkgCmdArguments::MANIFEST_MODE_FEATURE, + VcpkgCmdArguments::FEATURE_FLAGS_ARG); + } + + manifest_root_dir.clear(); + installed = + process_output_directory(filesystem, root, args.install_root_dir.get(), "installed", VCPKG_LINE_INFO); + } + buildtrees = process_output_directory(filesystem, root, args.buildtrees_root_dir.get(), "buildtrees", VCPKG_LINE_INFO); downloads = @@ -128,8 +195,6 @@ namespace vcpkg packages = process_output_directory(filesystem, root, args.packages_root_dir.get(), "packages", VCPKG_LINE_INFO); ports = filesystem.canonical(VCPKG_LINE_INFO, root / fs::u8path("ports")); - installed = - process_output_directory(filesystem, root, args.install_root_dir.get(), "installed", VCPKG_LINE_INFO); scripts = process_input_directory(filesystem, root, args.scripts_root_dir.get(), "scripts", VCPKG_LINE_INFO); prefab = root / fs::u8path("prefab"); @@ -155,13 +220,10 @@ namespace vcpkg ports_cmake = filesystem.canonical(VCPKG_LINE_INFO, scripts / fs::u8path("ports.cmake")); - if (args.overlay_triplets) + for (auto&& overlay_triplets_dir : args.overlay_triplets) { - for (auto&& overlay_triplets_dir : *args.overlay_triplets) - { - m_pimpl->triplets_dirs.emplace_back( - filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir))); - } + m_pimpl->triplets_dirs.emplace_back( + filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir))); } m_pimpl->triplets_dirs.emplace_back(triplets); m_pimpl->triplets_dirs.emplace_back(community_triplets); @@ -245,13 +307,13 @@ namespace vcpkg { static Toolset external_toolset = []() -> Toolset { Toolset ret; - ret.dumpbin = ""; + ret.dumpbin.clear(); ret.supported_architectures = { ToolsetArchOption{"", System::get_host_processor(), System::get_host_processor()}}; - ret.vcvarsall = ""; + ret.vcvarsall.clear(); ret.vcvarsall_options = {}; ret.version = "external"; - ret.visual_studio_root_path = ""; + ret.visual_studio_root_path.clear(); return ret; }(); return external_toolset; @@ -320,4 +382,30 @@ namespace vcpkg } Files::Filesystem& VcpkgPaths::get_filesystem() const { return *m_pimpl->fs_ptr; } + + void VcpkgPaths::track_feature_flag_metrics() const + { + struct + { + StringView flag; + bool enabled; + } flags[] = { + {VcpkgCmdArguments::MANIFEST_MODE_FEATURE, manifest_mode_enabled()} + }; + + for (const auto& flag : flags) + { + Metrics::g_metrics.lock()->track_feature(flag.flag.to_string(), flag.enabled); + } + } + + VcpkgPaths::~VcpkgPaths() + { + std::error_code ec; + m_pimpl->fs_ptr->unlock_file_lock(m_pimpl->file_lock_handle, ec); + if (ec) + { + Debug::print("Failed to unlock filesystem lock: ", ec.message(), '\n'); + } + } } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 66fa8a0baa..b955e43578 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -189,7 +189,7 @@ - + @@ -254,7 +254,7 @@ - + @@ -273,7 +273,7 @@ - + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 3b09b7ab1b..5c5beb5405 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -72,7 +72,7 @@ Source Files\vcpkg - + Source Files\vcpkg @@ -117,7 +117,7 @@ Source Files\vcpkg - + Source Files\vcpkg @@ -437,7 +437,7 @@ Header Files\vcpkg - + Header Files\vcpkg