aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Christensen <philc@microsoft.com>2020-02-03 14:22:52 -0800
committerGitHub <noreply@github.com>2020-02-03 14:22:52 -0800
commite62d1361288e83eba786395b60361ab35ba83800 (patch)
treea782ed37dc24eafa81f32082b602922f32d6cfec
parent586bee9bcd30993033a3590f7e84ef1b648cad10 (diff)
downloadvcpkg-e62d1361288e83eba786395b60361ab35ba83800.tar.gz
vcpkg-e62d1361288e83eba786395b60361ab35ba83800.zip
[vcpkg] Add Supports: field. Use contents of triplets instead of names for dependency resolution. (#8601)
* remove unfinished "supports" tag * extract "supports" from control files But do nothing with the value * Start `Supports` documentation * Use Supports in a bunch of control files I only tried matching the already existing logic in the portfile.cmake. * Cmake var provider (#8) * Cmake var provider (#9) * fix windows build (#10) * Add missing files to build * Fix test (#11) * adding hooks for cmake variables in expressions * Adding hooks for 'supports' in CI test * Fix test (#12) * Add overrides to evaluation environment * use "supported" tag in CI testing * cleanup comment * Fix issues with PR * [var_provider] Get library linkage variables from triplet * Fix compilation errors in tests * Add unimplemented functions * Fix unit tests part 1 * Fix issue when buildtrees dir does not exist * Change binary output hash * Fix handling of * feature * Add core feature when using * * Do not add Default-Features when installing 'core' * [vcpkg] WIP. 6 failing tests. * [vcpkg] WIP. 1 failing tests. * [vcpkg] WIP. 0 failing tests. * [vcpkg] Removed 'remove_graph'. 0 failing tests. * [vcpkg] Removed 'install_graph'. 0 failing tests. * [vcpkg] Remove AnyAction; replace with ActionPlan * [vcpkg] Minor cleanup. * [vcpkg][z3][qt5-connectivity][qt5-purchasing] Improve error messages while parsing. Fix a few trivial port issues. * [vcpkg] Work around ICE with MSVC v140 * [vcpkg] Add purge on fail to decompress for CI * [vcpkg] Fix parsing of nested parentheses in qualifiers * [vcpkg] Fix Linux builds (explicit qualification in declaration) * [vcpkg] Fix Build-Depends implying default features. Fix qualified dependencies regression. * [mmx] Add to skip list and full rebuild -- mmx causes problems by installing 'sched.h' * [libpqxx][mqtt-cpp] Prevent installing include/CMakeLists.txt * [cppitertools] Fix installed include namespace (should be include/cppitertools) * [libsoundio] Move headers into soundio/ subdirectory as per original cmake * [ci.baseline] Temporarily skip charls due to conflict with dcmtk * [vcpkg] Add restricted include files post build check -- bump global abi version * [libsoundio] Hotfix stray line in portfile * [vcpkg] Fix regression: CMake information was not being displayed for build-and-install actions * [jsonnet] Fix installation of internal headers; use system nlohmann-json * [grpc][upb] Teach grpc to use packaged upb. Add find_package(upb). Remove inappropriate upb features. * [zfp] Move problematic 'include/bitstream.h' to 'include/zfp/bitstream.h' * [x265] Bump control version to trigger rebuild after zfp conflict * [akali] Disable parallel configure * [dirent][dlfcn-win32][getopt-win32][pthreads] Grandfather into VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [ci.baseline] Update baseline for improved upb support * [tgui] Disable parallel configure * [libiconv] Enable VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [aws-sdk-cpp] Disable parallel configure * [vcpkg] Implement policy VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [aws-sdk-cpp] Fix amount of escaping semicolons -- Note: I do not know the root cause requiring this change * [libodb-sqlite] Fix configuring into source directory * [gettext] Grandfather into VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS * [libodb] DISABLE_PARALLEL_CONFIGURE * [vcpkg] Add 'config.h' and 'local.h' to restricted header list * [mcpp] Remove unused and problematic include 'config.h' from installed files * [teemo] Move installed headers into subdirectory to prevent conflicts with x265 * [ci.baseline] Update current OSX. Skip libmesh on all platforms due to heavy conflicts. * [vcpkg] Add 'slice.h' as a restricted header * [osg] Improve accuracy of dependencies (disable some, add some to Depends) * [vcpkg] Skip invoking a subprocess for 0 specs in load_tag_vars * [ci.baseline] Skip mongo-c-driver on osx due to flakiness * [teemo] Fix incorrect include file read * [osg] Fix dependency typo: glut -> freeglut * [vcpkg] Recover some lost performance with the addition of vcpkg_get_tags. A huge performance cost was loading the triplet files over and over; instead, we splice the sources into a macro and load it once, then just call that macro for each port. Remove use of hashing because we aren't cross-process-safe anyway (global static will do instead). * [vcpkg] Change Supports atom 'windows' to include UWP. Improve Supports field documentation. * [vcpkg] Add docs for VCPKG_ENV_PASSTHROUGH and VCPKG_DEP_INFO_OVERRIDE_VARS * Fix typo Co-authored-by: Curtis J Bezault <curtbezault@gmail.com> Co-authored-by: Victor Romero <romerosanchezv@gmail.com> Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
-rw-r--r--docs/maintainers/control-files.md54
-rw-r--r--docs/users/triplets.md32
-rw-r--r--ports/abseil/CONTROL1
-rw-r--r--ports/ace/CONTROL1
-rw-r--r--ports/activemq-cpp/CONTROL1
-rw-r--r--ports/akali/portfile.cmake3
-rw-r--r--ports/alac/CONTROL1
-rw-r--r--ports/aliyun-oss-c-sdk/CONTROL1
-rw-r--r--ports/ampl-mp/CONTROL1
-rw-r--r--ports/apr/CONTROL1
-rw-r--r--ports/arrow/CONTROL1
-rw-r--r--ports/aws-sdk-cpp/CONTROL2
-rw-r--r--ports/aws-sdk-cpp/portfile.cmake9
-rw-r--r--ports/azure-storage-cpp/CONTROL1
-rw-r--r--ports/benchmark/CONTROL1
-rw-r--r--ports/berkeleydb/CONTROL1
-rw-r--r--ports/c-ares/CONTROL1
-rw-r--r--ports/caffe2/CONTROL1
-rw-r--r--ports/capnproto/CONTROL1
-rw-r--r--ports/civetweb/CONTROL1
-rw-r--r--ports/coroutine/CONTROL1
-rw-r--r--ports/cpp-netlib/CONTROL1
-rw-r--r--ports/cppfs/CONTROL1
-rw-r--r--ports/cppitertools/CONTROL2
-rw-r--r--ports/cppitertools/portfile.cmake8
-rw-r--r--ports/cudnn/CONTROL1
-rw-r--r--ports/darknet/CONTROL1
-rw-r--r--ports/dirent/portfile.cmake3
-rw-r--r--ports/dlfcn-win32/portfile.cmake3
-rw-r--r--ports/dmlc/CONTROL1
-rw-r--r--ports/dpdk/CONTROL2
-rw-r--r--ports/easyhook/CONTROL3
-rw-r--r--ports/ebml/CONTROL1
-rw-r--r--ports/expat/CONTROL1
-rw-r--r--ports/field3d/CONTROL1
-rw-r--r--ports/folly/CONTROL1
-rw-r--r--ports/forge/CONTROL1
-rw-r--r--ports/getopt-win32/CONTROL1
-rw-r--r--ports/getopt-win32/portfile.cmake4
-rw-r--r--ports/getopt/CONTROL1
-rw-r--r--ports/gettext/portfile.cmake6
-rw-r--r--ports/gflags/CONTROL1
-rw-r--r--ports/glib/CONTROL1
-rw-r--r--ports/glibmm/CONTROL3
-rw-r--r--ports/gmmlib/CONTROL1
-rw-r--r--ports/googleapis/CONTROL1
-rw-r--r--ports/grpc/00008-uwp_upb_disable_C4146_error.patch31
-rw-r--r--ports/grpc/00009-use-system-upb.patch118
-rw-r--r--ports/grpc/CONTROL4
-rw-r--r--ports/grpc/portfile.cmake29
-rw-r--r--ports/gtkmm/CONTROL1
-rw-r--r--ports/hdf5/CONTROL3
-rw-r--r--ports/hwloc/CONTROL1
-rw-r--r--ports/icu/CONTROL1
-rw-r--r--ports/jinja2cpplight/CONTROL3
-rw-r--r--ports/jsonnet/0003-use-upstream-nlohmann-json.patch13
-rw-r--r--ports/jsonnet/002-fix-dependency-and-install.patch2
-rw-r--r--ports/jsonnet/CONTROL3
-rw-r--r--ports/jsonnet/portfile.cmake6
-rw-r--r--ports/kinectsdk1/CONTROL1
-rw-r--r--ports/kinectsdk2/CONTROL1
-rw-r--r--ports/lastools/CONTROL3
-rw-r--r--ports/leveldb/CONTROL1
-rw-r--r--ports/libarchive/CONTROL1
-rw-r--r--ports/libevent/CONTROL3
-rw-r--r--ports/libexif/CONTROL1
-rw-r--r--ports/libffi/CONTROL1
-rw-r--r--ports/libgit2/CONTROL1
-rw-r--r--ports/libiconv/portfile.cmake2
-rw-r--r--ports/libmysql/CONTROL1
-rw-r--r--ports/libodb-sqlite/CMakeLists.txt17
-rw-r--r--ports/libodb-sqlite/CONTROL2
-rw-r--r--ports/libodb/portfile.cmake1
-rw-r--r--ports/libopenmpt/CONTROL1
-rw-r--r--ports/libopusenc/CONTROL1
-rw-r--r--ports/libosip2/CONTROL3
-rw-r--r--ports/libp7-baical/CONTROL1
-rw-r--r--ports/libp7client/CONTROL1
-rw-r--r--ports/libpq/CONTROL3
-rw-r--r--ports/libpqxx/CMakeLists.txt1
-rw-r--r--ports/libpqxx/CONTROL4
-rw-r--r--ports/libpqxx/portfile.cmake4
-rw-r--r--ports/libressl/CONTROL1
-rw-r--r--ports/libsoundio/CONTROL3
-rw-r--r--ports/libsoundio/fix_cmakelists.patch233
-rw-r--r--ports/libsoundio/portfile.cmake16
-rw-r--r--ports/libssh/CONTROL1
-rw-r--r--ports/libusb-win32/CONTROL1
-rw-r--r--ports/libuuid/CONTROL1
-rw-r--r--ports/llgl/CONTROL1
-rw-r--r--ports/llvm/CONTROL3
-rw-r--r--ports/log4cpp/CONTROL2
-rw-r--r--ports/luajit/CONTROL1
-rw-r--r--ports/lzfse/CONTROL1
-rw-r--r--ports/marl/CONTROL1
-rw-r--r--ports/matroska/CONTROL1
-rw-r--r--ports/mcpp/CONTROL2
-rw-r--r--ports/mcpp/portfile.cmake1
-rw-r--r--ports/mdnsresponder/CONTROL1
-rw-r--r--ports/mecab/CONTROL1
-rw-r--r--ports/minhook/CONTROL3
-rw-r--r--ports/minifb/CONTROL1
-rw-r--r--ports/minizip/CONTROL1
-rw-r--r--ports/mongoose/CONTROL3
-rw-r--r--ports/monkeys-audio/CONTROL5
-rw-r--r--ports/mpir/CONTROL1
-rw-r--r--ports/mqtt-cpp/CONTROL4
-rw-r--r--ports/mqtt-cpp/portfile.cmake7
-rw-r--r--ports/ms-angle/CONTROL1
-rw-r--r--ports/msmpi/CONTROL1
-rw-r--r--ports/nano-signal-slot/CONTROL1
-rw-r--r--ports/nativefiledialog/CONTROL1
-rw-r--r--ports/networkdirect-sdk/CONTROL3
-rw-r--r--ports/openal-soft/CONTROL1
-rw-r--r--ports/openexr/CONTROL1
-rw-r--r--ports/openmpi/CONTROL1
-rw-r--r--ports/openni2/CONTROL1
-rw-r--r--ports/openssl-unix/CONTROL1
-rw-r--r--ports/openssl-uwp/CONTROL1
-rw-r--r--ports/openssl-windows/CONTROL1
-rw-r--r--ports/opentracing/CONTROL1
-rw-r--r--ports/openxr-loader/CONTROL1
-rw-r--r--ports/opusfile/CONTROL1
-rw-r--r--ports/osg/CONTROL4
-rw-r--r--ports/osg/portfile.cmake12
-rw-r--r--ports/pbc/CONTROL1
-rw-r--r--ports/physx/CONTROL7
-rw-r--r--ports/pistache/CONTROL3
-rw-r--r--ports/pmdk/CONTROL1
-rw-r--r--ports/portmidi/CONTROL1
-rw-r--r--ports/ptex/CONTROL1
-rw-r--r--ports/pthreads/CONTROL1
-rw-r--r--ports/pthreads/portfile.cmake12
-rw-r--r--ports/qt5-activeqt/CONTROL1
-rw-r--r--ports/qt5-connectivity/CONTROL2
-rw-r--r--ports/qt5-macextras/CONTROL1
-rw-r--r--ports/qt5-purchasing/CONTROL2
-rw-r--r--ports/qt5-winextras/CONTROL1
-rw-r--r--ports/rabit/CONTROL2
-rw-r--r--ports/raylib/CONTROL1
-rw-r--r--ports/readline/CONTROL1
-rw-r--r--ports/rhash/CONTROL1
-rw-r--r--ports/sciter/CONTROL1
-rw-r--r--ports/septag-sx/CONTROL1
-rw-r--r--ports/simdjson/CONTROL1
-rw-r--r--ports/soundtouch/CONTROL1
-rw-r--r--ports/spdk-dpdk/CONTROL2
-rw-r--r--ports/spdk-ipsec/CONTROL2
-rw-r--r--ports/spdk-isal/CONTROL2
-rw-r--r--ports/spdk/CONTROL3
-rw-r--r--ports/teemo/CONTROL2
-rw-r--r--ports/teemo/adjust-install-dir.patch22
-rw-r--r--ports/teemo/portfile.cmake7
-rw-r--r--ports/telnetpp/CONTROL1
-rw-r--r--ports/tensorflow-cc/CONTROL1
-rw-r--r--ports/tgui/portfile.cmake3
-rw-r--r--ports/tinkerforge/CONTROL1
-rw-r--r--ports/unicorn/CONTROL1
-rw-r--r--ports/upb/CONTROL11
-rw-r--r--ports/upb/add-cmake-install.patch60
-rw-r--r--ports/upb/fix-cmakelists.patch184
-rw-r--r--ports/upb/portfile.cmake26
-rw-r--r--ports/uvatlas/CONTROL3
-rw-r--r--ports/vectorclass/CONTROL1
-rw-r--r--ports/winreg/CONTROL3
-rw-r--r--ports/wintoast/CONTROL3
-rw-r--r--ports/x-plane/CONTROL1
-rw-r--r--ports/x265/CONTROL2
-rw-r--r--ports/yasm/CONTROL1
-rw-r--r--ports/yoga/CONTROL1
-rw-r--r--ports/z3/CONTROL3
-rw-r--r--ports/zfp/CONTROL2
-rw-r--r--ports/zfp/portfile.cmake6
-rw-r--r--scripts/ci.baseline.txt38
-rw-r--r--scripts/cmake/vcpkg_fixup_cmake_targets.cmake2
-rw-r--r--scripts/get_triplet_environment.cmake16
-rw-r--r--scripts/ports.cmake13
-rw-r--r--scripts/vcpkg_get_dep_info.cmake19
-rw-r--r--scripts/vcpkg_get_tags.cmake28
-rw-r--r--toolsrc/VERSION.txt2
-rw-r--r--toolsrc/include/vcpkg-test/mockcmakevarprovider.h38
-rw-r--r--toolsrc/include/vcpkg-test/util.h23
-rw-r--r--toolsrc/include/vcpkg/base/graphs.h47
-rw-r--r--toolsrc/include/vcpkg/base/span.h3
-rw-r--r--toolsrc/include/vcpkg/base/util.h14
-rw-r--r--toolsrc/include/vcpkg/binaryparagraph.h11
-rw-r--r--toolsrc/include/vcpkg/build.h36
-rw-r--r--toolsrc/include/vcpkg/cmakevars.h69
-rw-r--r--toolsrc/include/vcpkg/dependencies.h98
-rw-r--r--toolsrc/include/vcpkg/install.h14
-rw-r--r--toolsrc/include/vcpkg/logicexpression.h16
-rw-r--r--toolsrc/include/vcpkg/packagespec.h29
-rw-r--r--toolsrc/include/vcpkg/portfileprovider.h38
-rw-r--r--toolsrc/include/vcpkg/sourceparagraph.h88
-rw-r--r--toolsrc/include/vcpkg/statusparagraph.h1
-rw-r--r--toolsrc/include/vcpkg/update.h2
-rw-r--r--toolsrc/src/vcpkg-test/dependencies.cpp69
-rw-r--r--toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp28
-rw-r--r--toolsrc/src/vcpkg-test/paragraph.cpp96
-rw-r--r--toolsrc/src/vcpkg-test/plan.cpp727
-rw-r--r--toolsrc/src/vcpkg-test/specifier.cpp16
-rw-r--r--toolsrc/src/vcpkg-test/supports.cpp79
-rw-r--r--toolsrc/src/vcpkg-test/update.cpp16
-rw-r--r--toolsrc/src/vcpkg-test/util.cpp42
-rw-r--r--toolsrc/src/vcpkg/base/machinetype.cpp2
-rw-r--r--toolsrc/src/vcpkg/base/system.cpp6
-rw-r--r--toolsrc/src/vcpkg/binaryparagraph.cpp31
-rw-r--r--toolsrc/src/vcpkg/build.cpp393
-rw-r--r--toolsrc/src/vcpkg/cmakevars.cpp259
-rw-r--r--toolsrc/src/vcpkg/commands.autocomplete.cpp2
-rw-r--r--toolsrc/src/vcpkg/commands.buildexternal.cpp8
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp313
-rw-r--r--toolsrc/src/vcpkg/commands.dependinfo.cpp29
-rw-r--r--toolsrc/src/vcpkg/commands.env.cpp11
-rw-r--r--toolsrc/src/vcpkg/commands.search.cpp2
-rw-r--r--toolsrc/src/vcpkg/commands.upgrade.cpp31
-rw-r--r--toolsrc/src/vcpkg/dependencies.cpp1075
-rw-r--r--toolsrc/src/vcpkg/export.cpp10
-rw-r--r--toolsrc/src/vcpkg/install.cpp137
-rw-r--r--toolsrc/src/vcpkg/logicexpression.cpp196
-rw-r--r--toolsrc/src/vcpkg/packagespec.cpp44
-rw-r--r--toolsrc/src/vcpkg/paragraphs.cpp5
-rw-r--r--toolsrc/src/vcpkg/portfileprovider.cpp151
-rw-r--r--toolsrc/src/vcpkg/postbuildlint.cpp104
-rw-r--r--toolsrc/src/vcpkg/remove.cpp2
-rw-r--r--toolsrc/src/vcpkg/sourceparagraph.cpp179
-rw-r--r--toolsrc/src/vcpkg/statusparagraph.cpp28
-rw-r--r--toolsrc/src/vcpkg/statusparagraphs.cpp2
-rw-r--r--toolsrc/src/vcpkg/update.cpp4
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj4
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj.filters6
-rw-r--r--toolsrc/vcpkgtest/vcpkgtest.vcxproj15
-rw-r--r--toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters15
233 files changed, 3513 insertions, 2431 deletions
diff --git a/docs/maintainers/control-files.md b/docs/maintainers/control-files.md
index a074a7ae2..87468e6af 100644
--- a/docs/maintainers/control-files.md
+++ b/docs/maintainers/control-files.md
@@ -8,7 +8,7 @@ Field names are case-sensitive and start the line without leading whitespace. P
## Source Paragraph
-The first paragraph in a `CONTROL` file is the Source paragraph. It must have a `Source`, `Version`, and `Description` field. It can optionally have a `Build-Depends` and `Default-Features` field.
+The first paragraph in a `CONTROL` file is the Source paragraph. It must have a `Source`, `Version`, and `Description` field. The full set of fields is documented below.
### Examples:
```no-highlight
@@ -58,7 +58,7 @@ For example, given:
Then if you update the source version today, you should give it version `2019-06-01`. If you need to make a change which doesn't adjust the source version, you should give it version `2019-02-14-2`.
-Example:
+##### Examples:
```no-highlight
Version: 1.0.5-2
```
@@ -71,7 +71,7 @@ A description of the library.
By convention the first line of the description is a summary of the library. An optional detailed description follows. The detailed description can be multiple lines, all starting with whitespace.
-Example:
+##### Examples:
```no-highlight
Description: C++ header-only JSON library
```
@@ -96,17 +96,13 @@ Vcpkg does not distinguish between build-only dependencies and runtime dependenc
*For example: websocketpp is a header only library, and thus does not require any dependencies at install time. However, downstream users need boost and openssl to make use of the library. Therefore, websocketpp lists boost and openssl as dependencies*
-Example:
-```no-highlight
-Build-Depends: zlib, libpng, libjpeg-turbo, tiff
-```
-If the port is dependent on optional features of another library those can be specified using the `portname[featurelist]` syntax.
+If the port is dependent on optional features of another library those can be specified using the `portname[featurelist]` syntax. If the port does not require any features from the dependency, this should be specifed as `portname[core]`.
-Dependencies can be filtered based on the target triplet to support different requirements on Windows Desktop versus the Universal Windows Platform. Currently, the string inside parentheses is substring-compared against the triplet name. There must be a space between the name of the port and the filter. __This will change in a future version to not depend on the triplet name.__
+Dependencies can be filtered based on the target triplet to support differing requirements. These filters use the same syntax as the Supports field below and are surrounded in parentheses following the portname and feature list.
-Example:
+##### Example:
```no-highlight
-Build-Depends: curl[openssl] (!windows&!osx), curl[winssl] (windows), curl[darwinssl] (osx)
+Build-Depends: rapidjson, curl[core,openssl] (!windows), curl[core,winssl] (windows)
```
#### Default-Features
@@ -114,10 +110,46 @@ Comma separated list of optional port features to install by default.
This field is optional.
+##### Example:
```no-highlight
Default-Features: dynamodb, s3, kinesis
```
+<a name="Supports"></a>
+#### Supports
+Expression that evaluates to true when the port is expected to build successfully for a triplet.
+
+Currently, this field is only used in the CI testing to skip ports. In the future, this mechanism is intended to warn users in advance that a given install tree is not expected to succeed. Therefore, this field should be used optimistically; in cases where a port is expected to succeed 10% of the time, it should still be marked "supported".
+
+The grammar for the supports expression uses standard operators:
+- `!expr` - negation
+- `expr|expr` - or (`||` is also supported)
+- `expr&expr` - and (`&&` is also supported)
+- `(expr)` - grouping/precedence
+
+The predefined expressions are computed from standard triplet settings:
+- `x64` - `VCPKG_TARGET_ARCHITECTURE` == `"x64"`
+- `x86` - `VCPKG_TARGET_ARCHITECTURE` == `"x86"`
+- `arm` - `VCPKG_TARGET_ARCHITECTURE` == `"arm"` or `VCPKG_TARGET_ARCHITECTURE` == `"arm64"`
+- `arm64` - `VCPKG_TARGET_ARCHITECTURE` == `"arm64"`
+- `windows` - `VCPKG_CMAKE_SYSTEM_NAME` == `""` or `VCPKG_CMAKE_SYSTEM_NAME` == `"WindowsStore"`
+- `uwp` - `VCPKG_CMAKE_SYSTEM_NAME` == `"WindowsStore"`
+- `linux` - `VCPKG_CMAKE_SYSTEM_NAME` == `"Linux"`
+- `osx` - `VCPKG_CMAKE_SYSTEM_NAME` == `"Darwin"`
+- `android` - `VCPKG_CMAKE_SYSTEM_NAME` == `"Android"`
+- `static` - `VCPKG_LIBRARY_LINKAGE` == `"static"`
+
+These predefined expressions can be overridden in the triplet file via the [`VCPKG_DEP_INFO_OVERRIDE_VARS`](../users/triplets.md) option.
+
+This field is optional and defaults to true.
+
+> Implementers' Note: these terms are computed from the triplet via the `vcpkg_get_dep_info` mechanism.
+
+##### Example:
+```no-highlight
+Supports: !(uwp|arm)
+```
+
## Feature Paragraphs
Multiple optional features can be specified in the `CONTROL` files. It must have a `Feature` and `Description` field. It can optionally have a `Build-Depends` field. It must be separated from other paragraphs by one or more empty lines.
diff --git a/docs/users/triplets.md b/docs/users/triplets.md
index 6e52d347d..21dea5c31 100644
--- a/docs/users/triplets.md
+++ b/docs/users/triplets.md
@@ -2,20 +2,17 @@
Triplet is a standard term used in cross compiling as a way to completely capture the target environment (cpu, os, compiler, runtime, etc) in a single convenient name.
-In Vcpkg, we use triplets to describe self-consistent builds of library sets. This means every library will be built using the same target cpu, OS, and compiler toolchain, but also CRT linkage and preferred library type.
+In Vcpkg, we use triplets to describe an imaginary "target configuration set" for every library. Within a triplet, libraries are generally built with the same configuration, but it is not a requirement. For example, you could have one triplet that builds `openssl` statically and `zlib` dynamically, one that builds them both statically, and one that builds them both dynamically (all for the same target OS and architecture). A single build will consume files from a single triplet.
We currently provide many triplets by default (run `vcpkg help triplet`). However, you can easily add your own by creating a new file in the `triplets\` directory. The new triplet will immediately be available for use in commands, such as `vcpkg install boost:x86-windows-custom`.
To change the triplet used by your project, such as to enable static linking, see our [Integration Document](integration.md#triplet-selection).
-
## Community triplets
-Triplets contained in the `triplets\community` folder are not tested by continuous integration.
-
-These triplets contain configurations commonly requested by the community, but for which we lack the resources to properly test.
+Triplets contained in the `triplets\community` folder are not tested by continuous integration, but are commonly requested by the community.
-Port updates may break compatibility with community triplets, such regressions won't get caught by our testing pipelines. Because of this, community involvement is paramount!
+Because we do not have continuous coverage, port updates may break compatibility with community triplets. Because of this, community involvement is paramount!
We will gladly accept and review contributions that aim to solve issues with these triplets.
@@ -23,7 +20,7 @@ We will gladly accept and review contributions that aim to solve issues with the
Community Triplets are enabled by default, when using a community triplet a message like the following one will be printed during a package install:
-```bash
+```no-highlight
-- Using community triplet x86-uwp. This triplet configuration is not guaranteed to succeed.
-- [COMMUNITY] Loading triplet configuration from: D:\src\viromer\vcpkg\triplets\community\x86-uwp.cmake
```
@@ -78,8 +75,29 @@ This option also has forms for configuration-specific and C flags:
- `VCPKG_C_FLAGS_DEBUG`
- `VCPKG_C_FLAGS_RELEASE`
+<a name="VCPKG_DEP_INFO_OVERRIDE_VARS"></a>
+### VCPKG_DEP_INFO_OVERRIDE_VARS
+Replaces the default computed list of triplet "Supports" terms.
+
+This option (if set) will override the default set of terms used for qualified dependency resolution and "Supports" field evaluation.
+
+See the [`Supports`](../maintainers/control-files.md#Supports) control file field documentation for more details.
+
+> Implementers' Note: this list is extracted via the `vcpkg_get_dep_info` mechanism.
+
## Windows Variables
+### VCPKG_ENV_PASSTHROUGH
+Instructs vcpkg to allow additional environment variables into the build process.
+
+On Windows, vcpkg builds packages in a special clean environment that is isolated from the current command prompt to ensure build reliability and consistency.
+
+This triplet option can be set to a list of additional environment variables that will be added to the clean environment.
+
+See also the `vcpkg env` command for how you can inspect the precise environment that will be used.
+
+> Implementers' Note: this list is extracted via the `vcpkg_get_tags` mechanism.
+
<a name="VCPKG_VISUAL_STUDIO_PATH"></a>
### VCPKG_VISUAL_STUDIO_PATH
Specifies the Visual Studio installation to use.
diff --git a/ports/abseil/CONTROL b/ports/abseil/CONTROL
index 459eeee3f..01f27c758 100644
--- a/ports/abseil/CONTROL
+++ b/ports/abseil/CONTROL
@@ -5,3 +5,4 @@ Description: an open-source collection designed to augment the C++ standard libr
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.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/ace/CONTROL b/ports/ace/CONTROL
index 1530b043a..4cf1db8bc 100644
--- a/ports/ace/CONTROL
+++ b/ports/ace/CONTROL
@@ -2,6 +2,7 @@ Source: ace
Version: 6.5.7-1
Homepage: https://www.dre.vanderbilt.edu/~schmidt/ACE.html
Description: The ADAPTIVE Communication Environment
+Supports: !uwp
Feature: wchar
Description: Enable extra wide char functions in ACE
diff --git a/ports/activemq-cpp/CONTROL b/ports/activemq-cpp/CONTROL
index 5a7ade4e9..891c51ee7 100644
--- a/ports/activemq-cpp/CONTROL
+++ b/ports/activemq-cpp/CONTROL
@@ -2,3 +2,4 @@ Source: activemq-cpp
Version: 3.9.5-1
Build-Depends: apr
Description: Apache ActiveMQ is the most popular and powerful open source messaging and Integration Patterns server.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/akali/portfile.cmake b/ports/akali/portfile.cmake
index e1be35018..aa59b0389 100644
--- a/ports/akali/portfile.cmake
+++ b/ports/akali/portfile.cmake
@@ -12,7 +12,8 @@ string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" AKALI_STATIC)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
- PREFER_NINJA
+ DISABLE_PARALLEL_CONFIGURE
+ PREFER_NINJA
OPTIONS
-DAKALI_STATIC:BOOL=${AKALI_STATIC}
-DBUILD_TESTS:BOOL=OFF
diff --git a/ports/alac/CONTROL b/ports/alac/CONTROL
index 1bea4dc14..7938d6b71 100644
--- a/ports/alac/CONTROL
+++ b/ports/alac/CONTROL
@@ -2,3 +2,4 @@ Source: alac
Version: 2017-11-03-c38887c5-1
Homepage: https://github.com/macosforge/alac
Description: The Apple Lossless Audio Codec (ALAC) is a lossless audio codec developed by Apple and deployed on all of its platforms and devices.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/aliyun-oss-c-sdk/CONTROL b/ports/aliyun-oss-c-sdk/CONTROL
index 430541401..fdf8c658b 100644
--- a/ports/aliyun-oss-c-sdk/CONTROL
+++ b/ports/aliyun-oss-c-sdk/CONTROL
@@ -2,3 +2,4 @@ Source: aliyun-oss-c-sdk
Version: 3.7.1-1
Description: Alibaba Cloud Object Storage Service (OSS) is a cloud storage service provided by Alibaba Cloud, featuring massive capacity, security, a low cost, and high reliability.
Build-Depends: curl, apr-util
+Supports: !uwp
diff --git a/ports/ampl-mp/CONTROL b/ports/ampl-mp/CONTROL
index d45564c4f..a8f88ac55 100644
--- a/ports/ampl-mp/CONTROL
+++ b/ports/ampl-mp/CONTROL
@@ -1,3 +1,4 @@
Source: ampl-mp
Version: 2019-03-21-1
Description: An open-source library for mathematical programming
+Supports: !uwp \ No newline at end of file
diff --git a/ports/apr/CONTROL b/ports/apr/CONTROL
index 746583603..714022691 100644
--- a/ports/apr/CONTROL
+++ b/ports/apr/CONTROL
@@ -2,6 +2,7 @@ Source: apr
Version: 1.6.5-3
Homepage: https://apr.apache.org/
Description: The Apache Portable Runtime (APR) is a C library that forms a system portability layer that covers many operating systems.
+Supports: !uwp
Feature: private-headers
Description: Install non-standard files required for building Apache httpd
diff --git a/ports/arrow/CONTROL b/ports/arrow/CONTROL
index 780568f03..896f78af4 100644
--- a/ports/arrow/CONTROL
+++ b/ports/arrow/CONTROL
@@ -3,3 +3,4 @@ Version: 0.15.1
Build-Depends: boost-system, boost-filesystem, boost-multiprecision, boost-algorithm, flatbuffers, rapidjson, zlib, lz4, brotli, zstd, snappy, gflags, thrift, double-conversion, glog, uriparser
Homepage: https://github.com/apache/arrow
Description: Apache Arrow is a columnar in-memory analytics layer designed to accelerate big data. It houses a set of canonical in-memory representations of flat and hierarchical data along with multiple language-bindings for structure manipulation. It also provides IPC and common algorithm implementations.
+Supports: x64 \ No newline at end of file
diff --git a/ports/aws-sdk-cpp/CONTROL b/ports/aws-sdk-cpp/CONTROL
index 625d1f3de..93be6843d 100644
--- a/ports/aws-sdk-cpp/CONTROL
+++ b/ports/aws-sdk-cpp/CONTROL
@@ -1,5 +1,5 @@
Source: aws-sdk-cpp
-Version: 1.7.214
+Version: 1.7.214-1
Homepage: https://github.com/aws/aws-sdk-cpp
Description: AWS SDK for C++
Build-Depends: openssl (!uwp&!windows), curl (!uwp&!windows), aws-c-event-stream
diff --git a/ports/aws-sdk-cpp/portfile.cmake b/ports/aws-sdk-cpp/portfile.cmake
index b058608f3..9fa6b2f5f 100644
--- a/ports/aws-sdk-cpp/portfile.cmake
+++ b/ports/aws-sdk-cpp/portfile.cmake
@@ -3,7 +3,7 @@ vcpkg_buildpath_length_warning(37)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO aws/aws-sdk-cpp
- REF e8a7e7263e900983921e95363026efaa494622ab # 1.7.214
+ REF e8a7e7263e900983921e95363026efaa494622ab # 1.7.214
SHA512 dc4e003ffaebf21410d8d360f8a4602dda99d3ee0c0ab7fb61c97fe8b5f0b38438ed5315fb85d3a435cd5a99724e43c5cf569a7cb365ed8137caeac32c619a86
HEAD_REF master
)
@@ -14,14 +14,11 @@ set(BUILD_ONLY core)
include(${CMAKE_CURRENT_LIST_DIR}/compute_build_only.cmake)
-if(CMAKE_HOST_WIN32)
- string(REPLACE ";" "\\\\\\;" BUILD_ONLY "${BUILD_ONLY}")
-else()
- string(REPLACE ";" "\\\\\\\\\\\;" BUILD_ONLY "${BUILD_ONLY}")
-endif()
+string(REPLACE ";" "\\\\\\\\\\\;" BUILD_ONLY "${BUILD_ONLY}")
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
+ DISABLE_PARALLEL_CONFIGURE
PREFER_NINJA
OPTIONS
-DENABLE_UNITY_BUILD=ON
diff --git a/ports/azure-storage-cpp/CONTROL b/ports/azure-storage-cpp/CONTROL
index be93299da..66a402f8f 100644
--- a/ports/azure-storage-cpp/CONTROL
+++ b/ports/azure-storage-cpp/CONTROL
@@ -4,3 +4,4 @@ Build-Depends: cpprestsdk[core], atlmfc (windows), boost-log (!windows&!uwp), bo
Description: Microsoft Azure Storage Client SDK for C++
A client library for working with Microsoft Azure storage services including blobs, files, tables, and queues. This client library enables working with the Microsoft Azure storage services which include the blob service for storing binary and text data, the file service for storing binary and text data, the table service for storing structured non-relational data, and the queue service for storing messages that may be accessed by a client.
Homepage: https://blogs.msdn.com/b/windowsazurestorage/
+Supports: !uwp \ No newline at end of file
diff --git a/ports/benchmark/CONTROL b/ports/benchmark/CONTROL
index 27c4c8256..d82040748 100644
--- a/ports/benchmark/CONTROL
+++ b/ports/benchmark/CONTROL
@@ -2,3 +2,4 @@ Source: benchmark
Version: 1.5
Homepage: https://github.com/google/benchmark
Description: A library to support the benchmarking of functions, similar to unit-tests.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/berkeleydb/CONTROL b/ports/berkeleydb/CONTROL
index 7d93c230c..75c856c08 100644
--- a/ports/berkeleydb/CONTROL
+++ b/ports/berkeleydb/CONTROL
@@ -2,3 +2,4 @@ Source: berkeleydb
Version: 4.8.30-3
Homepage: https://download.oracle.com/
Description: BDB - A high-performance embedded database for key/value data.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/c-ares/CONTROL b/ports/c-ares/CONTROL
index c8a5f4854..4898ec5de 100644
--- a/ports/c-ares/CONTROL
+++ b/ports/c-ares/CONTROL
@@ -2,3 +2,4 @@ Source: c-ares
Version: 2019-5-2-1
Homepage: https://github.com/c-ares/c-ares
Description: A C library for asynchronous DNS requests
+Supports: !uwp \ No newline at end of file
diff --git a/ports/caffe2/CONTROL b/ports/caffe2/CONTROL
index 4d72fb764..e9bb4dbd7 100644
--- a/ports/caffe2/CONTROL
+++ b/ports/caffe2/CONTROL
@@ -3,3 +3,4 @@ Version: 0.8.1-3
Build-Depends: lmdb, gflags, glog, eigen3, protobuf
Homepage: https://github.com/caffe2/caffe2
Description: Caffe2 is a lightweight, modular, and scalable deep learning framework.
+Supports: !x86 \ No newline at end of file
diff --git a/ports/capnproto/CONTROL b/ports/capnproto/CONTROL
index 02cc080f1..cb1258c97 100644
--- a/ports/capnproto/CONTROL
+++ b/ports/capnproto/CONTROL
@@ -3,3 +3,4 @@ Version: 0.7.0-3
Description: Data interchange format and capability-based RPC system
Homepage: https://capnproto.org/
Build-Depends: zlib
+Supports: !uwp \ No newline at end of file
diff --git a/ports/civetweb/CONTROL b/ports/civetweb/CONTROL
index b24a4ffec..07b7306f1 100644
--- a/ports/civetweb/CONTROL
+++ b/ports/civetweb/CONTROL
@@ -1,3 +1,4 @@
Source: civetweb
Version: 2019-07-05
Description: Easy to use, powerful, C/C++ embeddable web server.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/coroutine/CONTROL b/ports/coroutine/CONTROL
index 13c8e3d21..c716f2585 100644
--- a/ports/coroutine/CONTROL
+++ b/ports/coroutine/CONTROL
@@ -2,3 +2,4 @@ Source: coroutine
Version: 2020-01-13
Build-Depends: ms-gsl
Description: C++ coroutine helper/example library
+Supports: !x86 \ No newline at end of file
diff --git a/ports/cpp-netlib/CONTROL b/ports/cpp-netlib/CONTROL
index 845a89e66..70c70b13f 100644
--- a/ports/cpp-netlib/CONTROL
+++ b/ports/cpp-netlib/CONTROL
@@ -3,3 +3,4 @@ Version: 0.13.0-3
Homepage: https://cpp-netlib.org/
Build-Depends: boost
Description: A collection of network-related routines/implementations geared towards providing a robust cross-platform networking library
+Supports: !uwp \ No newline at end of file
diff --git a/ports/cppfs/CONTROL b/ports/cppfs/CONTROL
index d94532e8a..c97527ff4 100644
--- a/ports/cppfs/CONTROL
+++ b/ports/cppfs/CONTROL
@@ -1,6 +1,7 @@
Source: cppfs
Version: 1.2.0-1
Description: Cross-platform C++ file system library supporting multiple backends
+Supports: !uwp
Feature: ssh
Description: SSH backend for cppfs
diff --git a/ports/cppitertools/CONTROL b/ports/cppitertools/CONTROL
index 8c5f387ec..579a85a69 100644
--- a/ports/cppitertools/CONTROL
+++ b/ports/cppitertools/CONTROL
@@ -1,4 +1,4 @@
Source: cppitertools
-Version: 2019-04-14-2
+Version: 2019-04-14-3
Description: Range-based for loop add-ons inspired by the Python builtins and itertools library
Build-Depends: boost-optional
diff --git a/ports/cppitertools/portfile.cmake b/ports/cppitertools/portfile.cmake
index f19069a3b..26b6ee93b 100644
--- a/ports/cppitertools/portfile.cmake
+++ b/ports/cppitertools/portfile.cmake
@@ -1,7 +1,3 @@
-# header-only library
-
-include(vcpkg_common_functions)
-
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO ryanhaining/cppitertools
@@ -13,8 +9,8 @@ vcpkg_from_github(
file(GLOB INCLUDE_FILES ${SOURCE_PATH}/*.hpp)
file(GLOB INCLUDE_INTERNAL_FILES ${SOURCE_PATH}/internal/*.hpp)
-file(COPY ${INCLUDE_FILES} DESTINATION ${CURRENT_PACKAGES_DIR}/include)
-file(COPY ${INCLUDE_INTERNAL_FILES} DESTINATION ${CURRENT_PACKAGES_DIR}/include/internal)
+file(COPY ${INCLUDE_FILES} DESTINATION ${CURRENT_PACKAGES_DIR}/include/cppitertools)
+file(COPY ${INCLUDE_INTERNAL_FILES} DESTINATION ${CURRENT_PACKAGES_DIR}/include/cppitertools/internal)
# Handle copyright
configure_file(${SOURCE_PATH}/LICENSE.md ${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright COPYONLY)
diff --git a/ports/cudnn/CONTROL b/ports/cudnn/CONTROL
index cc8019b5b..4ab7c941b 100644
--- a/ports/cudnn/CONTROL
+++ b/ports/cudnn/CONTROL
@@ -2,3 +2,4 @@ Source: cudnn
Version: 7.6
Description: NVIDIA's cuDNN deep neural network acceleration library
Build-Depends: cuda
+Supports: (windows|linux)&x64
diff --git a/ports/darknet/CONTROL b/ports/darknet/CONTROL
index 3665fa069..66bcbb76b 100644
--- a/ports/darknet/CONTROL
+++ b/ports/darknet/CONTROL
@@ -2,6 +2,7 @@ Source: darknet
Version: 0.2.5.1-1
Description: Darknet is an open source neural network framework written in C and CUDA. You only look once (YOLO) is a state-of-the-art, real-time object detection system, best example of darknet functionalities.
Build-Depends: pthreads (windows), stb
+Supports: !(arm|uwp)
Feature: cuda
Build-Depends: cuda
diff --git a/ports/dirent/portfile.cmake b/ports/dirent/portfile.cmake
index 80aab02f0..945f6017a 100644
--- a/ports/dirent/portfile.cmake
+++ b/ports/dirent/portfile.cmake
@@ -3,7 +3,6 @@ if(VCPKG_CMAKE_SYSTEM_NAME AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStor
return()
endif()
-include(vcpkg_common_functions)
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO tronkko/dirent
@@ -14,3 +13,5 @@ vcpkg_from_github(
file(INSTALL ${SOURCE_PATH}/include/ DESTINATION ${CURRENT_PACKAGES_DIR}/include)
file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/dirent RENAME copyright)
vcpkg_copy_pdbs()
+
+set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
diff --git a/ports/dlfcn-win32/portfile.cmake b/ports/dlfcn-win32/portfile.cmake
index e2376ab63..1e1fdccb1 100644
--- a/ports/dlfcn-win32/portfile.cmake
+++ b/ports/dlfcn-win32/portfile.cmake
@@ -1,4 +1,3 @@
-include(vcpkg_common_functions)
set(SOURCE_VERSION 1.1.1)
vcpkg_from_github(
@@ -27,3 +26,5 @@ vcpkg_copy_pdbs()
file(COPY ${SOURCE_PATH}/COPYING DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT})
file(RENAME ${CURRENT_PACKAGES_DIR}/share/${PORT}/COPYING ${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright)
+
+set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
diff --git a/ports/dmlc/CONTROL b/ports/dmlc/CONTROL
index 24d639ce3..673862144 100644
--- a/ports/dmlc/CONTROL
+++ b/ports/dmlc/CONTROL
@@ -3,6 +3,7 @@ Version: 2019-08-12-1
Homepage: https://github.com/dmlc/dmlc-core
Description: DMLC-Core is the backbone library to support all DMLC projects, offers the bricks to build efficient and scalable distributed machine learning libraries.
Default-Features: openmp
+Supports: !uwp
Feature: openmp
Description: Build with openmp \ No newline at end of file
diff --git a/ports/dpdk/CONTROL b/ports/dpdk/CONTROL
index 056800d29..53d79f7e6 100644
--- a/ports/dpdk/CONTROL
+++ b/ports/dpdk/CONTROL
@@ -1,4 +1,4 @@
Source: dpdk
Version: 19.02
Description: A set of libraries and drivers for fast packet processing
-
+Supports: linux
diff --git a/ports/easyhook/CONTROL b/ports/easyhook/CONTROL
index a47eb803d..077a5fb53 100644
--- a/ports/easyhook/CONTROL
+++ b/ports/easyhook/CONTROL
@@ -1,4 +1,5 @@
Source: easyhook
Version: 2.7.6789.0
Homepage: https://github.com/EasyHook/EasyHook
-Description: This project supports extending (hooking) unmanaged code (APIs) with pure managed ones, from within a fully managed environment on 32- or 64-bit Windows Vista x64, Windows Server 2008 x64, Windows 7, Windows 8.1, and Windows 10. \ No newline at end of file
+Description: This project supports extending (hooking) unmanaged code (APIs) with pure managed ones, from within a fully managed environment on 32- or 64-bit Windows Vista x64, Windows Server 2008 x64, Windows 7, Windows 8.1, and Windows 10.
+Supports: windows \ No newline at end of file
diff --git a/ports/ebml/CONTROL b/ports/ebml/CONTROL
index 0b2aac432..9af9cc865 100644
--- a/ports/ebml/CONTROL
+++ b/ports/ebml/CONTROL
@@ -2,3 +2,4 @@ Source: ebml
Version: 1.3.9
Homepage: https://github.com/Matroska-Org/libebml
Description: a C++ libary to parse EBML files
+Supports: !uwp \ No newline at end of file
diff --git a/ports/expat/CONTROL b/ports/expat/CONTROL
index 68629eb2d..9007da6cd 100644
--- a/ports/expat/CONTROL
+++ b/ports/expat/CONTROL
@@ -2,3 +2,4 @@ Source: expat
Version: 2.2.7
Homepage: https://github.com/libexpat/libexpat
Description: XML parser library written in C
+Supports: !uwp \ No newline at end of file
diff --git a/ports/field3d/CONTROL b/ports/field3d/CONTROL
index 487075eb4..c65ac02c5 100644
--- a/ports/field3d/CONTROL
+++ b/ports/field3d/CONTROL
@@ -3,3 +3,4 @@ Version: 1.7.2
Homepage: https://github.com/imageworks/Field3D
Description: An open source library for storing voxel data. It provides C++ classes that handle in-memory storage and a file format based on HDF5 that allows the C++ objects to be written to and read from disk.
Build-Depends: hdf5, boost-regex, boost-thread, boost-program-options, boost-system, openexr, boost-foreach, boost-test, boost-timer, boost-format
+Supports: !(windows|arm|uwp) \ No newline at end of file
diff --git a/ports/folly/CONTROL b/ports/folly/CONTROL
index 1ec16d009..77c75a702 100644
--- a/ports/folly/CONTROL
+++ b/ports/folly/CONTROL
@@ -4,6 +4,7 @@ Homepage: https://github.com/facebook/folly
Description: An open-source C++ library developed and used at Facebook. The library is UNSTABLE on Windows
Build-Depends: openssl, libevent, double-conversion, glog, gflags, boost-chrono, boost-context, boost-conversion, boost-crc, boost-date-time, boost-filesystem, boost-multi-index, boost-program-options, boost-regex, boost-system, boost-thread, boost-smart-ptr
Default-Features: zlib
+Supports: x64
Feature: zlib
Build-Depends: zlib
diff --git a/ports/forge/CONTROL b/ports/forge/CONTROL
index d791f8ad6..3aa7608d0 100644
--- a/ports/forge/CONTROL
+++ b/ports/forge/CONTROL
@@ -2,3 +2,4 @@ Source: forge
Version: 1.0.4-2
Description: Helps with high performance visualizations involving OpenGL-CUDA/OpenCL interop.
Build-Depends: glfw3, glm, glbinding, freetype, boost-functional, freeimage, fontconfig (!windows)
+Supports: x64 \ No newline at end of file
diff --git a/ports/getopt-win32/CONTROL b/ports/getopt-win32/CONTROL
index ba14d4909..5de151a79 100644
--- a/ports/getopt-win32/CONTROL
+++ b/ports/getopt-win32/CONTROL
@@ -2,3 +2,4 @@ Source: getopt-win32
Version: 0.1
Description: An implementation of getopt.
Homepage: https://github.com/libimobiledevice-win32
+Supports: windows \ No newline at end of file
diff --git a/ports/getopt-win32/portfile.cmake b/ports/getopt-win32/portfile.cmake
index 50ffc2b88..780cb1c5f 100644
--- a/ports/getopt-win32/portfile.cmake
+++ b/ports/getopt-win32/portfile.cmake
@@ -1,5 +1,3 @@
-include(vcpkg_common_functions)
-
if(VCPKG_CMAKE_SYSTEM_NAME)
message(FATAL_ERROR "getopt-win32 only supports building on Windows Desktop")
endif()
@@ -22,3 +20,5 @@ vcpkg_install_msbuild(
# Copy header
file(COPY ${SOURCE_PATH}/getopt.h DESTINATION ${CURRENT_PACKAGES_DIR}/include/)
+
+set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
diff --git a/ports/getopt/CONTROL b/ports/getopt/CONTROL
index bae137bbd..d2b9c2930 100644
--- a/ports/getopt/CONTROL
+++ b/ports/getopt/CONTROL
@@ -2,3 +2,4 @@ Source: getopt
Version: 0
Description: The getopt and getopt_long functions automate some of the chore involved in parsing typical unix command line options.
Build-Depends: getopt-win32 (windows)
+Supports: !uwp \ No newline at end of file
diff --git a/ports/gettext/portfile.cmake b/ports/gettext/portfile.cmake
index a9ab3d2e7..38ada752c 100644
--- a/ports/gettext/portfile.cmake
+++ b/ports/gettext/portfile.cmake
@@ -1,16 +1,16 @@
-if(VCPKG_CMAKE_SYSTEM_NAME AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(VCPKG_TARGET_IS_LINUX)
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
if (NOT EXISTS "/usr/include/libintl.h")
message(FATAL_ERROR "Please use command \"sudo apt-get install gettext\" to install gettext on linux.")
endif()
file(COPY ${CMAKE_CURRENT_LIST_DIR}/unofficial-gettext-config.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/unofficial-gettext)
return()
+else()
+ set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
endif()
#Based on https://github.com/winlibs/gettext
-include(vcpkg_common_functions)
-
set(GETTEXT_VERSION 0.19)
vcpkg_download_distfile(ARCHIVE
diff --git a/ports/gflags/CONTROL b/ports/gflags/CONTROL
index 4cd423293..f2b930778 100644
--- a/ports/gflags/CONTROL
+++ b/ports/gflags/CONTROL
@@ -2,3 +2,4 @@ Source: gflags
Version: 2.2.2-1
Homepage: https://github.com/gflags/gflags
Description: A C++ library that implements commandline flags processing
+Supports: !uwp \ No newline at end of file
diff --git a/ports/glib/CONTROL b/ports/glib/CONTROL
index cdf5441fe..871f98d86 100644
--- a/ports/glib/CONTROL
+++ b/ports/glib/CONTROL
@@ -3,6 +3,7 @@ Version: 2.52.3-14-5
Homepage: https://developer.gnome.org/glib/
Description: Portable, general-purpose utility library.
Build-Depends: zlib, pcre, libffi, gettext, libiconv
+Supports: !uwp
Feature: selinux
Description: Build with selinux support. \ No newline at end of file
diff --git a/ports/glibmm/CONTROL b/ports/glibmm/CONTROL
index 941735feb..aefaf7b83 100644
--- a/ports/glibmm/CONTROL
+++ b/ports/glibmm/CONTROL
@@ -2,4 +2,5 @@ Source: glibmm
Version: 2.52.1-11
Description: This is glibmm, a C++ API for parts of glib that are useful for C++.
Homepage: https://www.gtkmm.org.
-Build-Depends: zlib, pcre, libffi, gettext, libiconv, glib, libsigcpp \ No newline at end of file
+Build-Depends: zlib, pcre, libffi, gettext, libiconv, glib, libsigcpp
+Supports: !uwp
diff --git a/ports/gmmlib/CONTROL b/ports/gmmlib/CONTROL
index 4d043f870..b17937635 100644
--- a/ports/gmmlib/CONTROL
+++ b/ports/gmmlib/CONTROL
@@ -1,3 +1,4 @@
Source: gmmlib
Version: 19.2.3
Description: intel's graphics memory management library
+Supports: linux \ No newline at end of file
diff --git a/ports/googleapis/CONTROL b/ports/googleapis/CONTROL
index ac633e51b..d89aa8cd4 100644
--- a/ports/googleapis/CONTROL
+++ b/ports/googleapis/CONTROL
@@ -3,3 +3,4 @@ Version: 0.1.5
Build-Depends: grpc, protobuf
Description: C++ Proto Libraries for Google APIs.
Homepage: https://github.com/googleapis/cpp-cmakefiles
+Supports: !uwp
diff --git a/ports/grpc/00008-uwp_upb_disable_C4146_error.patch b/ports/grpc/00008-uwp_upb_disable_C4146_error.patch
deleted file mode 100644
index e2259e294..000000000
--- a/ports/grpc/00008-uwp_upb_disable_C4146_error.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-diff --git a/third_party/upb/upb/msg.c b/third_party/upb/upb/msg.c
-index a77da5665c..399e8753ba 100644
---- a/third_party/upb/upb/msg.c
-+++ b/third_party/upb/upb/msg.c
-@@ -33,17 +33,26 @@ static size_t upb_msg_sizeof(const upb_msglayout *l) {
- }
-
- static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
-+#pragma warning(push)
-+#pragma warning(disable : 4146)
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
-+#pragma warning(pop)
- }
-
- static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
-+#pragma warning(push)
-+#pragma warning(disable : 4146)
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
-+#pragma warning(pop)
- }
-
- static upb_msg_internal_withext *upb_msg_getinternalwithext(
- upb_msg *msg, const upb_msglayout *l) {
- UPB_ASSERT(l->extendable);
-+#pragma warning(push)
-+#pragma warning(disable : 4146)
- return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
-+#pragma warning(pop)
- }
-
- upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
diff --git a/ports/grpc/00009-use-system-upb.patch b/ports/grpc/00009-use-system-upb.patch
new file mode 100644
index 000000000..515238b9a
--- /dev/null
+++ b/ports/grpc/00009-use-system-upb.patch
@@ -0,0 +1,118 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index b535f10..0fcb682 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1530,7 +1530,7 @@ target_link_libraries(grpc
+ ${_gRPC_UPB_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+ if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
+ target_link_libraries(grpc "-framework CoreFoundation")
+@@ -1941,7 +1941,7 @@ target_link_libraries(grpc_cronet
+ ${_gRPC_UPB_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+ if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
+ target_link_libraries(grpc_cronet "-framework CoreFoundation")
+@@ -2283,7 +2283,7 @@ target_link_libraries(grpc_test_util
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+ grpc
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+ if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
+ target_link_libraries(grpc_test_util "-framework CoreFoundation")
+@@ -2626,7 +2626,7 @@ target_link_libraries(grpc_test_util_unsecure
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+ grpc_unsecure
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+ if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
+ target_link_libraries(grpc_test_util_unsecure "-framework CoreFoundation")
+@@ -3017,7 +3017,7 @@ target_link_libraries(grpc_unsecure
+ ${_gRPC_UPB_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+ if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
+ target_link_libraries(grpc_unsecure "-framework CoreFoundation")
+@@ -3553,7 +3553,7 @@ target_link_libraries(grpc++
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc
+ gpr
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+
+ foreach(_hdr
+@@ -4817,7 +4817,7 @@ target_link_libraries(grpc++_unsecure
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr
+ grpc_unsecure
+- upb
++ ${_gRPC_UPB_LIBRARIES}
+ )
+
+ foreach(_hdr
+@@ -5848,7 +5848,7 @@ if(gRPC_INSTALL)
+ endif()
+
+ endif()
+-
++if(0)
+ add_library(upb
+ third_party/upb/upb/decode.c
+ third_party/upb/upb/encode.c
+@@ -5888,10 +5888,10 @@ target_include_directories(upb
+ target_link_libraries(upb
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ )
++endif()
+
+
+-
+-if(gRPC_INSTALL)
++if(gRPC_INSTALL AND 0)
+ install(TARGETS upb EXPORT gRPCTargets
+ RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
+diff --git a/cmake/gRPCConfig.cmake.in b/cmake/gRPCConfig.cmake.in
+index 504d5a7..e2a3122 100644
+--- a/cmake/gRPCConfig.cmake.in
++++ b/cmake/gRPCConfig.cmake.in
+@@ -3,6 +3,7 @@
+ @_gRPC_FIND_PROTOBUF@
+ @_gRPC_FIND_SSL@
+ @_gRPC_FIND_CARES@
++find_package(upb CONFIG)
+
+ # Targets
+ include(${CMAKE_CURRENT_LIST_DIR}/gRPCTargets.cmake)
+diff --git a/cmake/upb.cmake b/cmake/upb.cmake
+index 2c0ab84..746e067 100644
+--- a/cmake/upb.cmake
++++ b/cmake/upb.cmake
+@@ -12,9 +12,9 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+-set(UPB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/upb)
++find_package(upb REQUIRED)
++set(_gRPC_UPB_INCLUDE_DIR)
+
+-set(_gRPC_UPB_INCLUDE_DIR "${UPB_ROOT_DIR}")
+ set(_gRPC_UPB_GRPC_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/core/ext/upb-generated")
+
+-set(_gRPC_UPB_LIBRARIES upb)
++set(_gRPC_UPB_LIBRARIES upb::upb)
diff --git a/ports/grpc/CONTROL b/ports/grpc/CONTROL
index 4f5652a8b..790e19e8d 100644
--- a/ports/grpc/CONTROL
+++ b/ports/grpc/CONTROL
@@ -1,5 +1,5 @@
Source: grpc
-Version: 1.26.0
-Build-Depends: zlib, openssl, protobuf, c-ares (!uwp)
+Version: 1.26.0-1
+Build-Depends: zlib, openssl, protobuf, c-ares (!uwp), upb
Homepage: https://github.com/grpc/grpc
Description: An RPC library and framework
diff --git a/ports/grpc/portfile.cmake b/ports/grpc/portfile.cmake
index 9e925898c..e156ea4d5 100644
--- a/ports/grpc/portfile.cmake
+++ b/ports/grpc/portfile.cmake
@@ -1,15 +1,7 @@
-include(vcpkg_common_functions)
-
-if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR NOT VCPKG_CMAKE_SYSTEM_NAME)
+if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()
-# This snippet is a workaround for users who are upgrading from an extremely old version of this
-# port, which cloned directly into `src\`
-if(EXISTS "${CURRENT_BUILDTREES_DIR}/src/.git")
- file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/src)
-endif()
-
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO grpc/grpc
@@ -23,28 +15,19 @@ vcpkg_from_github(
00004-link-gdi32-on-windows.patch
00005-fix-uwp-error.patch
00006-crypt32.patch
- 00008-uwp_upb_disable_C4146_error.patch
+ 00009-use-system-upb.patch
)
-if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
+if(VCPKG_TARGET_IS_UWP OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
set(gRPC_BUILD_CODEGEN OFF)
else()
set(gRPC_BUILD_CODEGEN ON)
endif()
-if(VCPKG_CRT_LINKAGE STREQUAL "static")
- set(gRPC_MSVC_STATIC_RUNTIME ON)
-else()
- set(gRPC_MSVC_STATIC_RUNTIME OFF)
-endif()
-
-if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
- set(gRPC_STATIC_LINKING ON)
-else()
- set(gRPC_STATIC_LINKING OFF)
-endif()
+string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" gRPC_MSVC_STATIC_RUNTIME)
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" gRPC_STATIC_LINKING)
-if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+if(VCPKG_TARGET_IS_UWP)
set(cares_CARES_PROVIDER OFF)
else()
set(cares_CARES_PROVIDER "package")
diff --git a/ports/gtkmm/CONTROL b/ports/gtkmm/CONTROL
index b346cd699..ecdab2cc3 100644
--- a/ports/gtkmm/CONTROL
+++ b/ports/gtkmm/CONTROL
@@ -3,3 +3,4 @@ Version: 3.22.2-2
Homepage: https://www.gtkmm.org/
Description: gtkmm is the official C++ interface for the popular GUI library GTK+.
Build-Depends: glib, atk, gtk, gdk-pixbuf, pango, cairo, libepoxy, gettext, glibmm, atkmm, cairomm, pangomm
+Supports: !uwp
diff --git a/ports/hdf5/CONTROL b/ports/hdf5/CONTROL
index a8d27e029..6a74b2da9 100644
--- a/ports/hdf5/CONTROL
+++ b/ports/hdf5/CONTROL
@@ -1,8 +1,9 @@
Source: hdf5
-Version: 1.10.5-9
+Version: 1.10.5-10
Homepage: https://www.hdfgroup.org/downloads/hdf5/
Description: HDF5 is a data model, library, and file format for storing and managing data
Default-Features: szip, zlib
+Supports: !uwp
Feature: parallel
Description: parallel support for HDF5
diff --git a/ports/hwloc/CONTROL b/ports/hwloc/CONTROL
index f754a0fd8..eeb7421f3 100644
--- a/ports/hwloc/CONTROL
+++ b/ports/hwloc/CONTROL
@@ -3,3 +3,4 @@ Version: 1.11.7-3
Homepage: https://github.com/open-mpi/hwloc
Description: Portable Hardware Locality (hwloc)
The Portable Hardware Locality (hwloc) software package provides a portable abstraction (across OS, versions, architectures, ...) of the hierarchical topology of modern architectures, including NUMA memory nodes, sockets, shared caches, cores and simultaneous multithreading. It also gathers various system attributes such as cache and memory information as well as the locality of I/O devices such as network interfaces, InfiniBand HCAs or GPUs.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/icu/CONTROL b/ports/icu/CONTROL
index 4fccc8622..06d902e19 100644
--- a/ports/icu/CONTROL
+++ b/ports/icu/CONTROL
@@ -2,3 +2,4 @@ Source: icu
Version: 61.1-8
Homepage: http://icu-project.org/apiref/icu4c/
Description: Mature and widely used Unicode and localization library.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/jinja2cpplight/CONTROL b/ports/jinja2cpplight/CONTROL
index 57334bc42..f918eb28f 100644
--- a/ports/jinja2cpplight/CONTROL
+++ b/ports/jinja2cpplight/CONTROL
@@ -1,4 +1,5 @@
Source: jinja2cpplight
Version: 2018-05-08
Homepage: https://github.com/hughperkins/Jinja2CppLight
-Description: (very) lightweight version of Jinja2 for C++, Lightweight templating engine for C++, based on Jinja2. \ No newline at end of file
+Description: (very) lightweight version of Jinja2 for C++, Lightweight templating engine for C++, based on Jinja2.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/jsonnet/0003-use-upstream-nlohmann-json.patch b/ports/jsonnet/0003-use-upstream-nlohmann-json.patch
new file mode 100644
index 000000000..a2e1105b7
--- /dev/null
+++ b/ports/jsonnet/0003-use-upstream-nlohmann-json.patch
@@ -0,0 +1,13 @@
+diff --git a/core/vm.cpp b/core/vm.cpp
+index 0cf06fa..d65a6d7 100644
+--- a/core/vm.cpp
++++ b/core/vm.cpp
+@@ -23,7 +23,7 @@ limitations under the License.
+
+ #include "desugarer.h"
+ #include "json.h"
+-#include "json.hpp"
++#include "nlohmann/json.hpp"
+ #include "md5.h"
+ #include "parser.h"
+ #include "state.h"
diff --git a/ports/jsonnet/002-fix-dependency-and-install.patch b/ports/jsonnet/002-fix-dependency-and-install.patch
index cccdc9439..7c7b5da77 100644
--- a/ports/jsonnet/002-fix-dependency-and-install.patch
+++ b/ports/jsonnet/002-fix-dependency-and-install.patch
@@ -24,7 +24,7 @@ index 82fb7c2..a94b4ff 100644
endif()
+
+
-+install(FILES ${LIBJSONNET_HEADERS} DESTINATION include)
++install(FILES ${LIB_HEADER} DESTINATION include)
\ No newline at end of file
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index bf349df..6ed1442 100644
diff --git a/ports/jsonnet/CONTROL b/ports/jsonnet/CONTROL
index 2f6e669ef..78542024c 100644
--- a/ports/jsonnet/CONTROL
+++ b/ports/jsonnet/CONTROL
@@ -1,4 +1,5 @@
Source: jsonnet
-Version: 0.14.0
+Version: 0.14.0-1
Homepage: https://github.com/google/jsonnet
Description: Jsonnet - The data templating language
+Build-Depends: nlohmann-json
diff --git a/ports/jsonnet/portfile.cmake b/ports/jsonnet/portfile.cmake
index 2840f513f..6b4a30a11 100644
--- a/ports/jsonnet/portfile.cmake
+++ b/ports/jsonnet/portfile.cmake
@@ -11,9 +11,10 @@ vcpkg_from_github(
PATCHES
001-enable-msvc.patch
002-fix-dependency-and-install.patch
+ 0003-use-upstream-nlohmann-json.patch
)
-if (VCPKG_TARGET_IS_WINDOWS)
+if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_execute_required_process(
COMMAND Powershell -Command "((Get-Content -AsByteStream \"${SOURCE_PATH}/stdlib/std.jsonnet\") -join ',') + ',0' | Out-File -Encoding Ascii \"${SOURCE_PATH}/core/std.jsonnet.h\""
WORKING_DIRECTORY "${SOURCE_PATH}"
@@ -27,7 +28,7 @@ else()
)
endif()
-if (VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
+if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic")
set(BUILD_SHARED ON)
set(BUILD_STATIC OFF)
else()
@@ -44,6 +45,7 @@ vcpkg_configure_cmake(
-DBUILD_JSONNET=OFF
-DBUILD_JSONNETFMT=OFF
-DBUILD_TESTS=OFF
+ -DUSE_SYSTEM_JSON=ON
)
vcpkg_install_cmake()
diff --git a/ports/kinectsdk1/CONTROL b/ports/kinectsdk1/CONTROL
index 9764fb69a..d4cd1d273 100644
--- a/ports/kinectsdk1/CONTROL
+++ b/ports/kinectsdk1/CONTROL
@@ -1,3 +1,4 @@
Source: kinectsdk1
Version: 1.8-2
Description: Kinect for Windows SDK for Kinect v1 sensor.
+Supports: !arm \ No newline at end of file
diff --git a/ports/kinectsdk2/CONTROL b/ports/kinectsdk2/CONTROL
index 4fc290d0f..d92784df4 100644
--- a/ports/kinectsdk2/CONTROL
+++ b/ports/kinectsdk2/CONTROL
@@ -1,3 +1,4 @@
Source: kinectsdk2
Version: 2.0-2
Description: Kinect for Windows SDK for Kinect v2 sensor.
+Supports: !arm \ No newline at end of file
diff --git a/ports/lastools/CONTROL b/ports/lastools/CONTROL
index cb908a8d4..311130373 100644
--- a/ports/lastools/CONTROL
+++ b/ports/lastools/CONTROL
@@ -1,4 +1,5 @@
Source: lastools
Version: 2019-07-10
Homepage: https://github.com/LAStools/LAStools
-Description: LAStools: award-winning software for efficient LiDAR processing (with LASzip) \ No newline at end of file
+Description: LAStools: award-winning software for efficient LiDAR processing (with LASzip)
+Supports: !uwp \ No newline at end of file
diff --git a/ports/leveldb/CONTROL b/ports/leveldb/CONTROL
index aa0b2bc3e..1b1302f97 100644
--- a/ports/leveldb/CONTROL
+++ b/ports/leveldb/CONTROL
@@ -2,3 +2,4 @@ Source: leveldb
Version: 1.22-1
Homepage: https://github.com/bitcoin-core/leveldb
Description: LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/libarchive/CONTROL b/ports/libarchive/CONTROL
index 73760e887..6678faacc 100644
--- a/ports/libarchive/CONTROL
+++ b/ports/libarchive/CONTROL
@@ -4,6 +4,7 @@ Homepage: https://github.com/libarchive/libarchive
Description: Library for reading and writing streaming archives
Build-Depends: zlib
Default-Features: bzip2, libxml2, lz4, lzma, lzo, openssl
+Supports: !uwp
Feature: bzip2
Build-Depends: bzip2
diff --git a/ports/libevent/CONTROL b/ports/libevent/CONTROL
index 64067f15c..4df532990 100644
--- a/ports/libevent/CONTROL
+++ b/ports/libevent/CONTROL
@@ -1,7 +1,8 @@
Source: libevent
-Version: 2.1.11-4
+Version: 2.1.11-5
Homepage: https://github.com/libevent/libevent
Description: An event notification library
+Supports: !uwp
Default-Features: thread
Feature: openssl
diff --git a/ports/libexif/CONTROL b/ports/libexif/CONTROL
index e37d0960e..f3e4e4105 100644
--- a/ports/libexif/CONTROL
+++ b/ports/libexif/CONTROL
@@ -2,3 +2,4 @@ Source: libexif
Version: 0.6.21-2
Homepage: https://libexif.github.io/
Description: a library for parsing, editing, and saving EXIF data
+Supports: !uwp \ No newline at end of file
diff --git a/ports/libffi/CONTROL b/ports/libffi/CONTROL
index 4492dbce1..2bc4a093a 100644
--- a/ports/libffi/CONTROL
+++ b/ports/libffi/CONTROL
@@ -2,3 +2,4 @@ Source: libffi
Version: 3.1-7
Homepage: https://github.com/libffi/libffi
Description: Portable, high level programming interface to various calling conventions
+Supports: !arm \ No newline at end of file
diff --git a/ports/libgit2/CONTROL b/ports/libgit2/CONTROL
index d4050188c..0c320dd40 100644
--- a/ports/libgit2/CONTROL
+++ b/ports/libgit2/CONTROL
@@ -3,3 +3,4 @@ Version: 0.28.4
Homepage: https://github.com/libgit2/libgit2
Build-Depends: openssl (!windows&&!uwp)
Description: Git linkable library
+Supports: !uwp
diff --git a/ports/libiconv/portfile.cmake b/ports/libiconv/portfile.cmake
index 9027e2acf..5f184079f 100644
--- a/ports/libiconv/portfile.cmake
+++ b/ports/libiconv/portfile.cmake
@@ -40,3 +40,5 @@ vcpkg_copy_pdbs()
file(INSTALL ${SOURCE_PATH}/COPYING.LIB DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)
vcpkg_test_cmake(PACKAGE_NAME unofficial-iconv)
+
+set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
diff --git a/ports/libmysql/CONTROL b/ports/libmysql/CONTROL
index fb236147e..1195fecc2 100644
--- a/ports/libmysql/CONTROL
+++ b/ports/libmysql/CONTROL
@@ -3,3 +3,4 @@ Version: 8.0.4-5
Homepage: https://github.com/mysql/mysql-server
Build-Depends: boost-algorithm, boost-geometry, boost-optional, boost-functional, boost-graph, openssl, icu, libevent, liblzma, lz4, zlib
Description: A MySQL client library for C development.
+Supports: !(windows&x86)&!uwp \ No newline at end of file
diff --git a/ports/libodb-sqlite/CMakeLists.txt b/ports/libodb-sqlite/CMakeLists.txt
index 79f9bc2bf..8a62ab9a8 100644
--- a/ports/libodb-sqlite/CMakeLists.txt
+++ b/ports/libodb-sqlite/CMakeLists.txt
@@ -2,8 +2,7 @@ cmake_minimum_required(VERSION 3.0)
project(libodb-sqlite VERSION 2.4.0 LANGUAGES CXX)
find_package(odb 2.4.0 REQUIRED COMPONENTS libodb)
find_package(sqlite3 CONFIG)
-configure_file(config.unix.h.in
- ${CMAKE_CURRENT_SOURCE_DIR}/odb/sqlite/details/config.h COPYONLY)
+configure_file(config.unix.h.in odb/sqlite/details/config.h COPYONLY)
set(LIBODB_INSTALL_HEADERS ON CACHE BOOL "Install the header files (a debug install)")
file(GLOB_RECURSE libodb_src LIST_DIRECTORIES False
@@ -15,7 +14,7 @@ target_include_directories(libodb-sqlite
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)
target_link_libraries(libodb-sqlite PRIVATE odb::libodb sqlite3)
@@ -35,14 +34,22 @@ install(TARGETS libodb-sqlite EXPORT odb_sqliteConfig
RUNTIME DESTINATION bin
)
if(LIBODB_INSTALL_HEADERS)
-install(DIRECTORY odb DESTINATION include/
+ install(
+ DIRECTORY odb
+ DESTINATION include/
COMPONENT sqlite
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hxx"
PATTERN "*.ixx"
PATTERN "*.txx"
-)
+ )
+ install(
+ FILES config.unix.h.in
+ DESTINATION include/odb/sqlite/detail
+ COMPONENT sqlite
+ RENAME config.h
+ )
endif()
install(EXPORT odb_sqliteConfig NAMESPACE odb:: COMPONENT sqlite DESTINATION share/odb)
export(TARGETS libodb-sqlite NAMESPACE odb:: FILE odb_sqliteConfig.cmake) \ No newline at end of file
diff --git a/ports/libodb-sqlite/CONTROL b/ports/libodb-sqlite/CONTROL
index 0c87a6fc8..e7afd76e0 100644
--- a/ports/libodb-sqlite/CONTROL
+++ b/ports/libodb-sqlite/CONTROL
@@ -1,5 +1,5 @@
Source: libodb-sqlite
-Version: 2.4.0-5
+Version: 2.4.0-6
Homepage: https://www.codesynthesis.com/products/odb/
Description: Sqlite support for the ODB ORM library
Build-Depends: libodb, sqlite3
diff --git a/ports/libodb/portfile.cmake b/ports/libodb/portfile.cmake
index 18dc60f73..d616f1b35 100644
--- a/ports/libodb/portfile.cmake
+++ b/ports/libodb/portfile.cmake
@@ -20,6 +20,7 @@ file(COPY
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
+ DISABLE_PARALLEL_CONFIGURE
OPTIONS_DEBUG
-DLIBODB_INSTALL_HEADERS=OFF
)
diff --git a/ports/libopenmpt/CONTROL b/ports/libopenmpt/CONTROL
index 32fa988d1..be431f49e 100644
--- a/ports/libopenmpt/CONTROL
+++ b/ports/libopenmpt/CONTROL
@@ -3,3 +3,4 @@ Version: 2017-01-28-cf2390140
Homepage: https://github.com/OpenMPT/openmpt
Description: a library to render tracker music
Build-Depends: zlib, mpg123, libogg, libvorbis, portaudio, libflac
+Supports: !uwp \ No newline at end of file
diff --git a/ports/libopusenc/CONTROL b/ports/libopusenc/CONTROL
index 844b22d49..7e52b1353 100644
--- a/ports/libopusenc/CONTROL
+++ b/ports/libopusenc/CONTROL
@@ -3,3 +3,4 @@ Version: 0.2.1
Homepage: https://github.com/xiph/libopusenc
Description: Library for encoding .opus audio files and live streams.
Build-Depends: opus
+Supports: !uwp \ No newline at end of file
diff --git a/ports/libosip2/CONTROL b/ports/libosip2/CONTROL
index 693a9d73e..2fe1f8b16 100644
--- a/ports/libosip2/CONTROL
+++ b/ports/libosip2/CONTROL
@@ -1,4 +1,5 @@
Source: libosip2
Version: 5.1.0-3
Homepage: https://www.gnu.org/software/osip/
-Description: oSIP is an LGPL implementation of SIP. It's stable, portable, flexible and compliant! -may be more-! It is used mostly with eXosip2 stack (GPL) which provides simpler API for User-Agent implementation. \ No newline at end of file
+Description: oSIP is an LGPL implementation of SIP. It's stable, portable, flexible and compliant! -may be more-! It is used mostly with eXosip2 stack (GPL) which provides simpler API for User-Agent implementation.
+Supports: !(windows|uwp) \ No newline at end of file
diff --git a/ports/libp7-baical/CONTROL b/ports/libp7-baical/CONTROL
index 698334f58..80037450b 100644
--- a/ports/libp7-baical/CONTROL
+++ b/ports/libp7-baical/CONTROL
@@ -2,3 +2,4 @@ Source: libp7-baical
Version: 4.4-4
Homepage: https://baical.net/
Description: P7 is a library for high-speed sending telemetry & trace data from application
+Supports: !(arm|uwp) \ No newline at end of file
diff --git a/ports/libp7client/CONTROL b/ports/libp7client/CONTROL
index 0069877d4..f7020b6f1 100644
--- a/ports/libp7client/CONTROL
+++ b/ports/libp7client/CONTROL
@@ -1,3 +1,4 @@
Source: libp7client
Version: 5.2-1
Description: Open source, cross-platform, fastest library for sending logs, telemetry & trace data from your application.
+Supports: x86|x64 \ No newline at end of file
diff --git a/ports/libpq/CONTROL b/ports/libpq/CONTROL
index 724d9acd8..359481816 100644
--- a/ports/libpq/CONTROL
+++ b/ports/libpq/CONTROL
@@ -1,6 +1,7 @@
Source: libpq
Version: 12.0
Build-Depends: libpq[bonjour] (osx)
+Supports: !uwp
Homepage: https://www.postgresql.org/
Description: The official database access API of postgresql
Default-Features: zlib, openssl
@@ -79,4 +80,4 @@ Build-Depends: libxslt
Description: Build with libxslt (--with-libxslt)
Feature: client
-Description: Build all client tools and libraries. \ No newline at end of file
+Description: Build all client tools and libraries.
diff --git a/ports/libpqxx/CMakeLists.txt b/ports/libpqxx/CMakeLists.txt
index d8b9ce4f5..a3e6ae3f4 100644
--- a/ports/libpqxx/CMakeLists.txt
+++ b/ports/libpqxx/CMakeLists.txt
@@ -67,6 +67,7 @@ install(DIRECTORY include/ DESTINATION include
PATTERN "*.am" EXCLUDE
PATTERN "*.in" EXCLUDE
PATTERN "*.template" EXCLUDE
+ PATTERN "CMakeLists.txt" EXCLUDE
)
install(DIRECTORY ${CMAKE_BINARY_DIR}/pqxx/ DESTINATION include/pqxx
CONFIGURATIONS Release
diff --git a/ports/libpqxx/CONTROL b/ports/libpqxx/CONTROL
index 1742189b9..9acdf8146 100644
--- a/ports/libpqxx/CONTROL
+++ b/ports/libpqxx/CONTROL
@@ -1,5 +1,5 @@
Source: libpqxx
-Version: 6.4.5-1
+Version: 6.4.5-2
Homepage: https://github.com/jtv/libpqxx
Description: The official C++ client API for PostgreSQL
-Build-Depends: libpq
+Build-Depends: libpq[core]
diff --git a/ports/libpqxx/portfile.cmake b/ports/libpqxx/portfile.cmake
index e9fbdbc98..85e9cedb7 100644
--- a/ports/libpqxx/portfile.cmake
+++ b/ports/libpqxx/portfile.cmake
@@ -6,8 +6,8 @@ vcpkg_from_github(
REF a6b1d60e74c1427c8ac2324b85cd4a0dc2068332
SHA512 990083f738322283dc9c98b138a676e5ba04ab77794d5a51d672557e0562d2366b5085ad5571dd91af8ba4dea56baa94e8c1e4e6fe571341c95e92eb28d2b15a
HEAD_REF master
- PATCHES
- fix-deprecated-bug.patch
+ PATCHES
+ fix-deprecated-bug.patch
)
file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH})
diff --git a/ports/libressl/CONTROL b/ports/libressl/CONTROL
index 2cb09fb6c..a5dfd10c7 100644
--- a/ports/libressl/CONTROL
+++ b/ports/libressl/CONTROL
@@ -1,6 +1,7 @@
Source: libressl
Version: 2.9.1-2
Description: LibreSSL is a version of the TLS/crypto stack forked from OpenSSL in 2014, with goals of modernizing the codebase, improving security, and applying best practice development processes.
+Supports: !(uwp|arm)
Feature: tools
Description: Build openssl and ocspcheck executables
diff --git a/ports/libsoundio/CONTROL b/ports/libsoundio/CONTROL
index 52ab4845f..d8abcf070 100644
--- a/ports/libsoundio/CONTROL
+++ b/ports/libsoundio/CONTROL
@@ -1,4 +1,5 @@
Source: libsoundio
-Version: 2.0.0-1
+Version: 2.0.0-3
Description: libsoundio is C library providing cross-platform audio input and output.
Homepage: http://libsound.io/
+Supports: !uwp \ No newline at end of file
diff --git a/ports/libsoundio/fix_cmakelists.patch b/ports/libsoundio/fix_cmakelists.patch
index 225c4cff3..ffe00adff 100644
--- a/ports/libsoundio/fix_cmakelists.patch
+++ b/ports/libsoundio/fix_cmakelists.patch
@@ -1,184 +1,49 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 6541f1b..058bf3b 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -1,6 +1,4 @@
- cmake_minimum_required(VERSION 2.8.5)
--project(libsoundio C)
--set(CMAKE_MODULE_PATH ${libsoundio_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
-
- if(CMAKE_VERSION VERSION_LESS 3.0.0)
- set(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "library install dir (lib)")
-@@ -11,6 +9,11 @@ else()
- cmake_policy(SET CMP0046 NEW)
- include(GNUInstallDirs)
- endif()
-+cmake_policy(SET CMP0022 NEW)
-+
-+project(libsoundio C)
-+set(CMAKE_MODULE_PATH ${libsoundio_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
-+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
-
- if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
-@@ -27,8 +30,7 @@ if(NOT SOUNDIO_STATIC_LIBNAME)
- set(SOUNDIO_STATIC_LIBNAME soundio)
- endif()
-
--option(BUILD_STATIC_LIBS "Build static libraries" ON)
--option(BUILD_DYNAMIC_LIBS "Build dynamic libraries" ON)
-+option(BUILD_SHARED_LIBS "Build dynamic libraries" ON)
- option(BUILD_EXAMPLE_PROGRAMS "Build example programs" ON)
- option(BUILD_TESTS "Build tests" ON)
- option(ENABLE_JACK "Enable JACK backend" ON)
-@@ -203,7 +205,7 @@ if(MSVC)
- set(EXAMPLE_CFLAGS "/W4")
- set(TEST_CFLAGS "${LIB_CFLAGS}")
- set(TEST_LDFLAGS " ")
-- set(LIBM " ")
-+ set(LIBM "")
- else()
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -pedantic")
- set(LIB_CFLAGS "-std=c11 -fvisibility=hidden -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes -D_REENTRANT -D_POSIX_C_SOURCE=200809L -Wno-missing-braces")
-@@ -223,32 +225,33 @@ configure_file(
- ${DOXYGEN_CONF_FILE}
- )
-
--if(BUILD_DYNAMIC_LIBS)
-- add_library(libsoundio_shared SHARED ${LIBSOUNDIO_SOURCES})
-- set_target_properties(libsoundio_shared PROPERTIES
-+if(BUILD_SHARED_LIBS)
-+ add_library(libsoundio SHARED ${LIBSOUNDIO_SOURCES})
-+ set_target_properties(libsoundio PROPERTIES PUBLIC_HEADER "${LIBSOUNDIO_HEADERS}")
-+ set_target_properties(libsoundio PROPERTIES
- OUTPUT_NAME soundio
- SOVERSION ${LIBSOUNDIO_VERSION_MAJOR}
- VERSION ${LIBSOUNDIO_VERSION}
- COMPILE_FLAGS ${LIB_CFLAGS}
- LINKER_LANGUAGE C
- )
-- target_link_libraries(libsoundio_shared LINK_PUBLIC ${LIBSOUNDIO_LIBS})
-- install(TARGETS libsoundio_shared DESTINATION ${CMAKE_INSTALL_LIBDIR})
--endif()
--
--if(BUILD_STATIC_LIBS)
-- add_library(libsoundio_static STATIC ${LIBSOUNDIO_SOURCES})
-- set_target_properties(libsoundio_static PROPERTIES
-- OUTPUT_NAME ${SOUNDIO_STATIC_LIBNAME}
-+ target_link_libraries(libsoundio LINK_PUBLIC ${LIBSOUNDIO_LIBS})
-+ install(TARGETS libsoundio EXPORT libsoundio-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-+else()
-+ add_library(libsoundio STATIC ${LIBSOUNDIO_SOURCES})
-+ set_target_properties(libsoundio PROPERTIES PUBLIC_HEADER "${LIBSOUNDIO_HEADERS}")
-+ set_target_properties(libsoundio PROPERTIES
-+ OUTPUT_NAME soundio
- COMPILE_FLAGS ${LIB_CFLAGS}
- LINKER_LANGUAGE C
- )
-- install(TARGETS libsoundio_static DESTINATION ${CMAKE_INSTALL_LIBDIR})
-+ target_link_libraries(libsoundio LINK_PUBLIC ${LIBSOUNDIO_LIBS})
-+ target_compile_definitions(libsoundio PUBLIC SOUNDIO_STATIC_LIBRARY)
-+ install(TARGETS libsoundio EXPORT libsoundio-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
- endif()
-
--install(FILES
-- ${LIBSOUNDIO_HEADERS}
-- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundio")
-+add_library(libsoundio::libsoundio ALIAS libsoundio)
-+install(EXPORT libsoundio-export FILE libsoundio-config.cmake DESTINATION share/libsoundio/ NAMESPACE ${PROJECT_NAME}:: EXPORT_LINK_INTERFACE_LIBRARIES)
-
- # Example Programs
-
-@@ -257,44 +260,28 @@ if(BUILD_EXAMPLE_PROGRAMS)
- set_target_properties(sio_sine PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(sio_sine libsoundio_shared ${LIBM})
-- else()
-- target_link_libraries(sio_sine libsoundio_static ${LIBSOUNDIO_LIBS} ${LIBM})
-- endif()
-+ target_link_libraries(sio_sine libsoundio::libsoundio ${LIBM})
- install(TARGETS sio_sine DESTINATION ${CMAKE_INSTALL_BINDIR})
-
- add_executable(sio_list_devices example/sio_list_devices.c)
- set_target_properties(sio_list_devices PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(sio_list_devices libsoundio_shared)
-- else()
-- target_link_libraries(sio_list_devices libsoundio_static ${LIBSOUNDIO_LIBS})
-- endif()
-+ target_link_libraries(sio_list_devices libsoundio::libsoundio)
- install(TARGETS sio_list_devices DESTINATION ${CMAKE_INSTALL_BINDIR})
-
- add_executable(sio_microphone example/sio_microphone.c)
- set_target_properties(sio_microphone PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(sio_microphone libsoundio_shared)
-- else()
-- target_link_libraries(sio_microphone libsoundio_static ${LIBSOUNDIO_LIBS})
-- endif()
-+ target_link_libraries(sio_microphone libsoundio::libsoundio)
- install(TARGETS sio_microphone DESTINATION ${CMAKE_INSTALL_BINDIR})
-
- add_executable(sio_record example/sio_record.c)
- set_target_properties(sio_record PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(sio_record libsoundio_shared)
-- else()
-- target_link_libraries(sio_record libsoundio_static ${LIBSOUNDIO_LIBS})
-- endif()
-+ target_link_libraries(sio_record libsoundio::libsoundio)
- install(TARGETS sio_record DESTINATION ${CMAKE_INSTALL_BINDIR})
- endif()
-
-@@ -308,7 +295,7 @@ if(BUILD_TESTS)
- )
-
- add_executable(latency "${libsoundio_SOURCE_DIR}/test/latency.c" ${LIBSOUNDIO_SOURCES})
-- target_link_libraries(latency LINK_PUBLIC ${LIBSOUNDIO_LIBS} ${LIBM})
-+ target_link_libraries(latency LINK_PUBLIC libsoundio::libsoundio ${LIBM})
- set_target_properties(latency PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${LIB_CFLAGS}
-@@ -318,31 +305,19 @@ if(BUILD_TESTS)
- set_target_properties(underflow PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(underflow libsoundio_shared ${LIBM})
-- else()
-- target_link_libraries(underflow libsoundio_static ${LIBSOUNDIO_LIBS} ${LIBM})
-- endif()
-+ target_link_libraries(underflow libsoundio::libsoundio ${LIBM})
-
- add_executable(backend_disconnect_recover test/backend_disconnect_recover.c)
- set_target_properties(backend_disconnect_recover PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(backend_disconnect_recover libsoundio_shared)
-- else()
-- target_link_libraries(backend_disconnect_recover libsoundio_static ${LIBSOUNDIO_LIBS})
-- endif()
-+ target_link_libraries(backend_disconnect_recover libsoundio::libsoundio)
-
- add_executable(overflow test/overflow.c)
- set_target_properties(overflow PROPERTIES
- LINKER_LANGUAGE C
- COMPILE_FLAGS ${EXAMPLE_CFLAGS})
-- if(BUILD_DYNAMIC_LIBS)
-- target_link_libraries(overflow libsoundio_shared)
-- else()
-- target_link_libraries(overflow libsoundio_static ${LIBSOUNDIO_LIBS})
-- endif()
-+ target_link_libraries(overflow libsoundio::libsoundio)
-
-
-
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 6541f1b..e81bdce 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,4 +1,5 @@
+-cmake_minimum_required(VERSION 2.8.5)
++cmake_minimum_required(VERSION 3.14)
++cmake_policy(SET CMP0022 NEW)
+ project(libsoundio C)
+ set(CMAKE_MODULE_PATH ${libsoundio_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
+
+@@ -233,7 +234,8 @@ if(BUILD_DYNAMIC_LIBS)
+ LINKER_LANGUAGE C
+ )
+ target_link_libraries(libsoundio_shared LINK_PUBLIC ${LIBSOUNDIO_LIBS})
+- install(TARGETS libsoundio_shared DESTINATION ${CMAKE_INSTALL_LIBDIR})
++ target_include_directories(libsoundio_shared PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
++ install(TARGETS libsoundio_shared EXPORT libsoundio-export)
+ endif()
+
+ if(BUILD_STATIC_LIBS)
+@@ -243,9 +245,26 @@ if(BUILD_STATIC_LIBS)
+ COMPILE_FLAGS ${LIB_CFLAGS}
+ LINKER_LANGUAGE C
+ )
+- install(TARGETS libsoundio_static DESTINATION ${CMAKE_INSTALL_LIBDIR})
++ target_link_libraries(libsoundio_static PUBLIC ${LIBSOUNDIO_LIBS})
++ target_include_directories(libsoundio_static PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
++ install(TARGETS libsoundio_static EXPORT libsoundio-export)
+ endif()
+
++add_library(libsoundio INTERFACE)
++if(BUILD_DYNAMIC_LIBS)
++ target_link_libraries(libsoundio INTERFACE libsoundio_shared)
++else()
++ target_link_libraries(libsoundio INTERFACE libsoundio_static)
++endif()
++install(TARGETS libsoundio EXPORT libsoundio-export)
++install(
++ EXPORT libsoundio-export
++ FILE libsoundio-config.cmake
++ DESTINATION share/libsoundio/
++ NAMESPACE ${PROJECT_NAME}::
++ EXPORT_LINK_INTERFACE_LIBRARIES
++)
++
+ install(FILES
+ ${LIBSOUNDIO_HEADERS}
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/soundio")
diff --git a/ports/libsoundio/portfile.cmake b/ports/libsoundio/portfile.cmake
index 0e1b7f561..e28aa40c6 100644
--- a/ports/libsoundio/portfile.cmake
+++ b/ports/libsoundio/portfile.cmake
@@ -1,8 +1,5 @@
-include(vcpkg_common_functions)
-if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
- message(FATAL_ERROR "WindowsStore not supported")
-endif()
+vcpkg_fail_port_install(ON_TARGET "UWP")
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
@@ -14,15 +11,22 @@ vcpkg_from_github(
fix_cmakelists.patch
)
-string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" BUILD_SHARED_LIBS)
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" BUILD_DYNAMIC_LIBS)
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" BUILD_STATIC_LIBS)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
OPTIONS
- -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
+ -DBUILD_DYNAMIC_LIBS=${BUILD_DYNAMIC_LIBS}
+ -DBUILD_STATIC_LIBS=${BUILD_STATIC_LIBS}
-DBUILD_EXAMPLE_PROGRAMS=OFF
-DBUILD_TESTS=OFF
+ -DENABLE_JACK=OFF
+ -DENABLE_PULSEAUDIO=OFF
+ -DENABLE_ALSA=OFF
+ -DENABLE_COREAUDIO=${VCPKG_TARGET_IS_OSX}
+ -DENABLE_WASAPI=${VCPKG_TARGET_IS_WINDOWS}
)
vcpkg_install_cmake()
diff --git a/ports/libssh/CONTROL b/ports/libssh/CONTROL
index c12fb8f8f..443940653 100644
--- a/ports/libssh/CONTROL
+++ b/ports/libssh/CONTROL
@@ -3,6 +3,7 @@ Version: 0.9.0
Homepage: https://www.libssh.org/
Description: libssh is a multiplatform C library implementing the SSHv2 and SSHv1 protocol on client and server side
Build-Depends: openssl
+Supports: !uwp
Feature: zlib
Description: libssh with zlib
diff --git a/ports/libusb-win32/CONTROL b/ports/libusb-win32/CONTROL
index 6904f7066..bea5b9092 100644
--- a/ports/libusb-win32/CONTROL
+++ b/ports/libusb-win32/CONTROL
@@ -2,3 +2,4 @@ Source: libusb-win32
Version: 1.2.6.0-3
Homepage: https://sourceforge.net/projects/libusb-win32
Description: Allows user space applications to access many USB device on Windows.
+Supports: windows \ No newline at end of file
diff --git a/ports/libuuid/CONTROL b/ports/libuuid/CONTROL
index e5dc0c0b4..2d46a8307 100644
--- a/ports/libuuid/CONTROL
+++ b/ports/libuuid/CONTROL
@@ -1,3 +1,4 @@
Source: libuuid
Version: 1.0.3-3
Description: Universally unique id library
+Supports: linux|osx \ No newline at end of file
diff --git a/ports/llgl/CONTROL b/ports/llgl/CONTROL
index 476ccd8c2..fcba2d2d4 100644
--- a/ports/llgl/CONTROL
+++ b/ports/llgl/CONTROL
@@ -2,6 +2,7 @@ Source: llgl
Version: 2019-08-15
Homepage: https://github.com/LukasBanana/LLGL
Description: Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal.
+Supports: !uwp
Feature: opengl
Description: Support for opengl
diff --git a/ports/llvm/CONTROL b/ports/llvm/CONTROL
index e1569bdee..2eb184a84 100644
--- a/ports/llvm/CONTROL
+++ b/ports/llvm/CONTROL
@@ -3,6 +3,7 @@ Version: 8.0.0-3
Homepage: https://llvm.org/
Description: The LLVM Compiler Infrastructure
Build-Depends: atlmfc (windows)
+Supports: !uwp
Default-Features: tools, utils
Feature: tools
@@ -15,4 +16,4 @@ Feature: example
Description: Generate build targets for the LLVM examples
Feature: test
-Description: Generate build targets for the LLVM unit tests. \ No newline at end of file
+Description: Generate build targets for the LLVM unit tests.
diff --git a/ports/log4cpp/CONTROL b/ports/log4cpp/CONTROL
index 11c37843b..ec84f4065 100644
--- a/ports/log4cpp/CONTROL
+++ b/ports/log4cpp/CONTROL
@@ -2,4 +2,4 @@ Source: log4cpp
Version: 2.9.1-2
Homepage: https://github.com/orocos-toolchain/log4cpp
Description: Log4cpp is library of C++ classes for flexible logging to files, syslog, IDSA and other destinations. It is modeled after the Log4j Java library, staying as close to their API as is reasonable.
-
+Supports: !uwp
diff --git a/ports/luajit/CONTROL b/ports/luajit/CONTROL
index 03b778e9a..f37d4dcbe 100644
--- a/ports/luajit/CONTROL
+++ b/ports/luajit/CONTROL
@@ -2,3 +2,4 @@ Source: luajit
Version: 2.0.5-3
Homepage: https://github.com/LuaJIT/LuaJIT
Description: LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/lzfse/CONTROL b/ports/lzfse/CONTROL
index f79063ad9..cc4669974 100644
--- a/ports/lzfse/CONTROL
+++ b/ports/lzfse/CONTROL
@@ -2,3 +2,4 @@ Source: lzfse
Version: 1.0-2
Homepage: https://github.com/lzfse/lzfse
Description: Lempel-Ziv style data compressor using Finite State Entropy coding.
+Supports: !arm \ No newline at end of file
diff --git a/ports/marl/CONTROL b/ports/marl/CONTROL
index f3a24fdcd..16f464135 100644
--- a/ports/marl/CONTROL
+++ b/ports/marl/CONTROL
@@ -2,3 +2,4 @@ Source: marl
Version: 2019-09-13
Description: A hybrid thread/fiber task scheduler written in C++ 11
Homepage: https://github.com/google/marl
+Supports: !uwp \ No newline at end of file
diff --git a/ports/matroska/CONTROL b/ports/matroska/CONTROL
index 29cef7e80..1a5235db7 100644
--- a/ports/matroska/CONTROL
+++ b/ports/matroska/CONTROL
@@ -3,3 +3,4 @@ Version: 1.5.2
Homepage: https://github.com/Matroska-Org/libmatroska
Description: a C++ libary to parse Matroska files (.mkv and .mka)
Build-Depends: ebml
+Supports: !uwp \ No newline at end of file
diff --git a/ports/mcpp/CONTROL b/ports/mcpp/CONTROL
index e76634440..cc756ae9a 100644
--- a/ports/mcpp/CONTROL
+++ b/ports/mcpp/CONTROL
@@ -1,4 +1,4 @@
Source: mcpp
-Version: 2.7.2.14
+Version: 2.7.2.14-1
Homepage: https://github.com/zeroc-ice/mcpp
Description: Fork of mcpp, a C/C++ preprocessor
diff --git a/ports/mcpp/portfile.cmake b/ports/mcpp/portfile.cmake
index 9394d00c3..11e268f99 100644
--- a/ports/mcpp/portfile.cmake
+++ b/ports/mcpp/portfile.cmake
@@ -15,7 +15,6 @@ vcpkg_install_cmake()
file(
INSTALL
- ${SOURCE_PATH}/config.h
${SOURCE_PATH}/mcpp_lib.h
${SOURCE_PATH}/mcpp_out.h
DESTINATION
diff --git a/ports/mdnsresponder/CONTROL b/ports/mdnsresponder/CONTROL
index 66c039dbc..9f97716e8 100644
--- a/ports/mdnsresponder/CONTROL
+++ b/ports/mdnsresponder/CONTROL
@@ -2,3 +2,4 @@ Source: mdnsresponder
Version: 765.30.11-2
Description: The mDNSResponder project is a component of Bonjour, Apple's ease-of-use IP networking initiative.
Homepage: https://developer.apple.com/bonjour/
+Supports: !arm \ No newline at end of file
diff --git a/ports/mecab/CONTROL b/ports/mecab/CONTROL
index b5b9c8f10..9bf6cec34 100644
--- a/ports/mecab/CONTROL
+++ b/ports/mecab/CONTROL
@@ -1,3 +1,4 @@
Source: mecab
Version: 1.0
Description: A morphological analysis engine based on CRF
+Supports: !(uwp|arm|arm64) \ No newline at end of file
diff --git a/ports/minhook/CONTROL b/ports/minhook/CONTROL
index 95209891b..0daab0e4c 100644
--- a/ports/minhook/CONTROL
+++ b/ports/minhook/CONTROL
@@ -1,3 +1,4 @@
Source: minhook
Version: 1.3.3
-Description: The Minimalistic x86/x64 API Hooking Library for Windows. \ No newline at end of file
+Description: The Minimalistic x86/x64 API Hooking Library for Windows.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/minifb/CONTROL b/ports/minifb/CONTROL
index cff3a97c0..5a86f9bbe 100644
--- a/ports/minifb/CONTROL
+++ b/ports/minifb/CONTROL
@@ -2,3 +2,4 @@ Source: minifb
Version: 2019-08-20-1
Homepage: https://github.com/emoon/minifb
Description: MiniFB (Mini FrameBuffer) is a small cross platform library that makes it easy to render (32-bit) pixels in a window.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/minizip/CONTROL b/ports/minizip/CONTROL
index 22ea0c9f3..415a3a82c 100644
--- a/ports/minizip/CONTROL
+++ b/ports/minizip/CONTROL
@@ -3,6 +3,7 @@ Version: 1.2.11-6
Build-Depends: zlib
Homepage: https://github.com/madler/zlib
Description: Zip compression library
+Supports: !uwp
Feature: bzip2
Build-Depends: bzip2
diff --git a/ports/mongoose/CONTROL b/ports/mongoose/CONTROL
index c307982cf..a6c7f8663 100644
--- a/ports/mongoose/CONTROL
+++ b/ports/mongoose/CONTROL
@@ -2,7 +2,8 @@ Source: mongoose
Version: 6.15-2
Description: Embedded web server / embedded networking library
Homepage: https://cesanta.com/
+Supports: !uwp
Feature: ssl
Build-Depends: openssl
-Description: Build with openssl \ No newline at end of file
+Description: Build with openssl
diff --git a/ports/monkeys-audio/CONTROL b/ports/monkeys-audio/CONTROL
index d265f22d9..abe072f25 100644
--- a/ports/monkeys-audio/CONTROL
+++ b/ports/monkeys-audio/CONTROL
@@ -1,8 +1,9 @@
Source: monkeys-audio
-Version: 5.14
+Version: 5.14-1
Homepage: https://monkeysaudio.com
Description: Monkey's Audio is an excellent audio compression tool which has multiple advantages over traditional methods.
Audio files compressed with it ends with .ape extension.
+Supports: !uwp
Feature: tools
-Description: Build monkeys-audio tools \ No newline at end of file
+Description: Build monkeys-audio tools
diff --git a/ports/mpir/CONTROL b/ports/mpir/CONTROL
index 12f9d38ea..79238cbb5 100644
--- a/ports/mpir/CONTROL
+++ b/ports/mpir/CONTROL
@@ -2,3 +2,4 @@ Source: mpir
Version: 3.0.0-7
Homepage: https://github.com/wbhart/mpir
Description: Multiple Precision Integers and Rationals.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/mqtt-cpp/CONTROL b/ports/mqtt-cpp/CONTROL
index 73303edd2..eae0c7dd4 100644
--- a/ports/mqtt-cpp/CONTROL
+++ b/ports/mqtt-cpp/CONTROL
@@ -1,5 +1,5 @@
Source: mqtt-cpp
-Version: 7.0.1
+Version: 7.0.1-1
Description: Header-only MQTT client/server for C++14 based on Boost.Asio.
Homepage: https://github.com/redboltz/mqtt_cpp
-Build-Depends: boost-asio, boost-timer
+Build-Depends: boost-asio, boost-timer, boost-system, boost-date-time
diff --git a/ports/mqtt-cpp/portfile.cmake b/ports/mqtt-cpp/portfile.cmake
index 13e5e2077..d1b930826 100644
--- a/ports/mqtt-cpp/portfile.cmake
+++ b/ports/mqtt-cpp/portfile.cmake
@@ -1,5 +1,3 @@
-# header-only library
-
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO redboltz/mqtt_cpp
@@ -14,7 +12,10 @@ vcpkg_configure_cmake(
OPTIONS
-DMQTT_BUILD_EXAMPLES=OFF
-DMQTT_BUILD_TESTS=OFF
+ -DCMAKE_DISABLE_FIND_PACKAGE_Doxygen=ON
)
-file(INSTALL ${SOURCE_PATH}/include/ DESTINATION ${CURRENT_PACKAGES_DIR}/include)
+vcpkg_install_cmake()
+
+file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug)
file(INSTALL ${SOURCE_PATH}/LICENSE_1_0.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)
diff --git a/ports/ms-angle/CONTROL b/ports/ms-angle/CONTROL
index 4fadc5994..4ba095050 100644
--- a/ports/ms-angle/CONTROL
+++ b/ports/ms-angle/CONTROL
@@ -2,3 +2,4 @@ Source: ms-angle
Version: 2018-04-18-2
Description: The UWP version of a conformant OpenGL ES implementation for Windows, Mac and Linux.
The goal of ANGLE is to allow users of multiple operating systems to seamlessly run WebGL and other OpenGL ES content by translating OpenGL ES API calls to one of the hardware-supported APIs available for that platform. ANGLE currently provides translation from OpenGL ES 2.0 and 3.0 to desktop OpenGL, OpenGL ES, Direct3D 9, and Direct3D 11. Support for translation from OpenGL ES to Vulkan is underway, and future plans include compute shader support (ES 3.1) and MacOS support.
+Supports: windows|uwp \ No newline at end of file
diff --git a/ports/msmpi/CONTROL b/ports/msmpi/CONTROL
index d21b80c37..baa44b8fe 100644
--- a/ports/msmpi/CONTROL
+++ b/ports/msmpi/CONTROL
@@ -1,3 +1,4 @@
Source: msmpi
Version: 10.0-2
Description: Microsoft MPI
+Supports: windows \ No newline at end of file
diff --git a/ports/nano-signal-slot/CONTROL b/ports/nano-signal-slot/CONTROL
index 9594e575b..99cee9fec 100644
--- a/ports/nano-signal-slot/CONTROL
+++ b/ports/nano-signal-slot/CONTROL
@@ -2,3 +2,4 @@ Source: nano-signal-slot
Version: 2.0.1
Homepage: https://github.com/NoAvailableAlias/nano-signal-slot
Description: Pure C++17 Signals and Slots
+Supports: !uwp \ No newline at end of file
diff --git a/ports/nativefiledialog/CONTROL b/ports/nativefiledialog/CONTROL
index 60aca3c45..afe283577 100644
--- a/ports/nativefiledialog/CONTROL
+++ b/ports/nativefiledialog/CONTROL
@@ -2,6 +2,7 @@ Source: nativefiledialog
Version: 2019-08-28
Description: A tiny, neat C library that portably invokes native file open and save dialogs
Homepage: https://github.com/mlabbe/nativefiledialog
+Supports: !uwp
Feature: zenity
Description: Using Zenity backend on Linux
diff --git a/ports/networkdirect-sdk/CONTROL b/ports/networkdirect-sdk/CONTROL
index 3cc939c8e..158183800 100644
--- a/ports/networkdirect-sdk/CONTROL
+++ b/ports/networkdirect-sdk/CONTROL
@@ -1,4 +1,5 @@
Source: networkdirect-sdk
Version: 2.0.1
Description: The Network Direct architecture allows hardware vendors to expose the advanced capabilities of their networking devices.
-Homepage: https://www.nuget.org/packages/NetworkDirect \ No newline at end of file
+Homepage: https://www.nuget.org/packages/NetworkDirect
+Supports: windows&(x64|x86) \ No newline at end of file
diff --git a/ports/openal-soft/CONTROL b/ports/openal-soft/CONTROL
index b52d568cd..0833c52c0 100644
--- a/ports/openal-soft/CONTROL
+++ b/ports/openal-soft/CONTROL
@@ -2,3 +2,4 @@ Source: openal-soft
Version: 1.20.0
Homepage: https://github.com/kcat/openal-soft
Description: OpenAL Soft is an LGPL-licensed, cross-platform, software implementation of the OpenAL 3D audio API.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/openexr/CONTROL b/ports/openexr/CONTROL
index 7d8759237..ddf7b0fbd 100644
--- a/ports/openexr/CONTROL
+++ b/ports/openexr/CONTROL
@@ -3,3 +3,4 @@ Version: 2.3.0-5
Homepage: https://www.openexr.com/
Description: OpenEXR is a high dynamic-range (HDR) image file format developed by Industrial Light & Magic for use in computer imaging applications
Build-Depends: zlib
+Supports: !uwp \ No newline at end of file
diff --git a/ports/openmpi/CONTROL b/ports/openmpi/CONTROL
index 6ea5a17c1..86af5ffd5 100644
--- a/ports/openmpi/CONTROL
+++ b/ports/openmpi/CONTROL
@@ -2,3 +2,4 @@ Source: openmpi
Version: 4.0.1
Homepage: https://www.open-mpi.org/
Description: The Open MPI Project is an open source Message Passing Interface implementation that is developed and maintained by a consortium of academic, research, and industry partners. Open MPI is therefore able to combine the expertise, technologies, and resources from all across the High Performance Computing community in order to build the best MPI library available. Open MPI offers advantages for system and software vendors, application developers and computer science researchers.
+Supports: !(windows|uwp) \ No newline at end of file
diff --git a/ports/openni2/CONTROL b/ports/openni2/CONTROL
index a8fa4a2ac..c1b869a57 100644
--- a/ports/openni2/CONTROL
+++ b/ports/openni2/CONTROL
@@ -3,3 +3,4 @@ Version: 2.2.0.33-11
Build-Depends: kinectsdk1
Homepage: https://github.com/OpenNI/OpenNI2
Description: OpenNI is open source library for access to Natural Interaction (NI) devices such as RGB-D camera.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/openssl-unix/CONTROL b/ports/openssl-unix/CONTROL
index b2a55c187..c56c95dad 100644
--- a/ports/openssl-unix/CONTROL
+++ b/ports/openssl-unix/CONTROL
@@ -1,3 +1,4 @@
Source: openssl-unix
Version: 1.1.1d-1
Description: OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library.
+Supports: !(windows|uwp) \ No newline at end of file
diff --git a/ports/openssl-uwp/CONTROL b/ports/openssl-uwp/CONTROL
index a4a8e681a..7e7650fc2 100644
--- a/ports/openssl-uwp/CONTROL
+++ b/ports/openssl-uwp/CONTROL
@@ -1,3 +1,4 @@
Source: openssl-uwp
Version: 1.1.1d-1
Description: OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library.
+Supports: uwp \ No newline at end of file
diff --git a/ports/openssl-windows/CONTROL b/ports/openssl-windows/CONTROL
index 9d80476f8..561977fe0 100644
--- a/ports/openssl-windows/CONTROL
+++ b/ports/openssl-windows/CONTROL
@@ -1,3 +1,4 @@
Source: openssl-windows
Version: 1.1.1d-1
Description: OpenSSL is an open source project that provides a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library.
+Supports: windows \ No newline at end of file
diff --git a/ports/opentracing/CONTROL b/ports/opentracing/CONTROL
index 62f6dd303..8a5e0625f 100644
--- a/ports/opentracing/CONTROL
+++ b/ports/opentracing/CONTROL
@@ -2,3 +2,4 @@ Source: opentracing
Version: 1.5.1-1
Description: C++ implementation of the OpenTracing API
Homepage: https://opentracing.io
+Supports: !uwp \ No newline at end of file
diff --git a/ports/openxr-loader/CONTROL b/ports/openxr-loader/CONTROL
index 0088df713..632fadab7 100644
--- a/ports/openxr-loader/CONTROL
+++ b/ports/openxr-loader/CONTROL
@@ -1,6 +1,7 @@
Source: openxr-loader
Version: 1.0.3.0
Description: Khronos API for abstracting VR/MR/AR hardware
+Supports: !(arm|uwp)
Feature: vulkan
Description: Vulkan functionality for OpenXR
diff --git a/ports/opusfile/CONTROL b/ports/opusfile/CONTROL
index 0ba3167a6..80ca95f96 100644
--- a/ports/opusfile/CONTROL
+++ b/ports/opusfile/CONTROL
@@ -3,6 +3,7 @@ Version: 0.11-3
Homepage: https://github.com/xiph/opusfile
Description: Stand-alone decoder library for .opus streams
Build-Depends: libogg, opus
+Supports: !uwp
Feature: opusurl
Description: Support decoding of http(s) streams
diff --git a/ports/osg/CONTROL b/ports/osg/CONTROL
index f677e0284..8df250d7c 100644
--- a/ports/osg/CONTROL
+++ b/ports/osg/CONTROL
@@ -1,8 +1,8 @@
Source: osg
-Version: 3.6.4
+Version: 3.6.4-1
Homepage: https://github.com/openscenegraph/OpenSceneGraph
Description: The OpenSceneGraph is an open source high performance 3D graphics toolkit.
-Build-Depends: freetype, jasper, openexr, zlib, gdal, giflib, libjpeg-turbo, libpng, tiff, fontconfig
+Build-Depends: freetype, jasper, openexr, zlib, gdal, giflib, libjpeg-turbo, libpng, tiff, fontconfig, sdl2, boost-asio (!windows), libxml2 (windows), giflib (windows), freeglut (windows)
Feature: collada
Description: Support for Collada (.dae) files
diff --git a/ports/osg/portfile.cmake b/ports/osg/portfile.cmake
index 8c6b5f299..03520aa9b 100644
--- a/ports/osg/portfile.cmake
+++ b/ports/osg/portfile.cmake
@@ -18,6 +18,18 @@ else()
set(OSG_DYNAMIC ON)
endif()
file(REMOVE ${SOURCE_PATH}/CMakeModules/FindSDL2.cmake)
+
+set(OPTIONS)
+if(NOT "collada" IN_LIST FEATURES)
+ list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_COLLADA=ON)
+endif()
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_FFmpeg=ON)
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_DCMTK=ON)
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_GStreamer=ON)
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_GLIB=ON)
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_SDL=ON)
+list(APPEND OPTIONS -DCMAKE_DISABLE_FIND_PACKAGE_LIBLAS=ON)
+
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
OPTIONS
diff --git a/ports/pbc/CONTROL b/ports/pbc/CONTROL
index b717ac1e5..1577832fd 100644
--- a/ports/pbc/CONTROL
+++ b/ports/pbc/CONTROL
@@ -3,3 +3,4 @@ Version: 0.5.14-2
Build-Depends: mpir (windows)
Homepage: https://crypto.stanford.edu/pbc
Description: Pairing-Based Crypto library provides low-level routines for pairing-based cryptosystems.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/physx/CONTROL b/ports/physx/CONTROL
index 49150dc29..c744a2ae3 100644
--- a/ports/physx/CONTROL
+++ b/ports/physx/CONTROL
@@ -1,3 +1,4 @@
-Source: physx
-Version: 4.1.1-3
-Description: The NVIDIA PhysX SDK is a scalable multi-platform physics solution supporting a wide range of devices, from smartphones to high-end multicore CPUs and GPUs
+Source: physx
+Version: 4.1.1-3
+Description: The NVIDIA PhysX SDK is a scalable multi-platform physics solution supporting a wide range of devices, from smartphones to high-end multicore CPUs and GPUs
+Supports: !uwp
diff --git a/ports/pistache/CONTROL b/ports/pistache/CONTROL
index c1b4408cf..307fe0191 100644
--- a/ports/pistache/CONTROL
+++ b/ports/pistache/CONTROL
@@ -1,4 +1,5 @@
Source: pistache
Version: 2019-08-05
Homepage: https://github.com/oktal/pistache
-Description: Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++11 and provides a clear and pleasant API. \ No newline at end of file
+Description: Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++11 and provides a clear and pleasant API.
+Supports: linux \ No newline at end of file
diff --git a/ports/pmdk/CONTROL b/ports/pmdk/CONTROL
index c2e5bed30..4b4cac6b2 100644
--- a/ports/pmdk/CONTROL
+++ b/ports/pmdk/CONTROL
@@ -2,3 +2,4 @@ Source: pmdk
Version: 1.7-1
Homepage: https://github.com/pmem/pmdk
Description: Persistent Memory Development Kit
+Supports: !(arm|x86) \ No newline at end of file
diff --git a/ports/portmidi/CONTROL b/ports/portmidi/CONTROL
index 07ba19c0c..1a9917935 100644
--- a/ports/portmidi/CONTROL
+++ b/ports/portmidi/CONTROL
@@ -2,3 +2,4 @@ Source: portmidi
Version: 0.217.1-1
Homepage: https://sourceforge.net/projects/portmedia/
Description: Free, cross-platform, open-source I/O library for MIDI
+Supports: !uwp \ No newline at end of file
diff --git a/ports/ptex/CONTROL b/ports/ptex/CONTROL
index 823988f85..501913cf5 100644
--- a/ports/ptex/CONTROL
+++ b/ports/ptex/CONTROL
@@ -3,3 +3,4 @@ Version: 2.3.2-1
Homepage: https://github.com/wdas/ptex
Description: Per-Face Texture Mapping for Production Rendering.
Build-Depends: zlib
+Supports: !uwp \ No newline at end of file
diff --git a/ports/pthreads/CONTROL b/ports/pthreads/CONTROL
index 43c38ffdb..19e2bd0ac 100644
--- a/ports/pthreads/CONTROL
+++ b/ports/pthreads/CONTROL
@@ -2,3 +2,4 @@ Source: pthreads
Version: 3.0.0-4
Homepage: https://sourceware.org/pub/pthreads-win32/
Description: pthreads for windows
+Supports: !(uwp|arm|arm64) \ No newline at end of file
diff --git a/ports/pthreads/portfile.cmake b/ports/pthreads/portfile.cmake
index 393fefddc..3abb2d591 100644
--- a/ports/pthreads/portfile.cmake
+++ b/ports/pthreads/portfile.cmake
@@ -1,14 +1,12 @@
-include(vcpkg_common_functions)
-
-if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
- message(FATAL_ERROR "${PORT} does not currently support UWP platform nor ARM architectures")
-endif()
-
if(VCPKG_CMAKE_SYSTEM_NAME AND NOT VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
return()
endif()
+if(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
+ message(FATAL_ERROR "${PORT} does not currently support UWP platform nor ARM architectures")
+endif()
+
set(PTHREADS4W_VERSION "3.0.0")
vcpkg_download_distfile(ARCHIVE
@@ -98,3 +96,5 @@ file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/pt
file(COPY ${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/pthread)
file(COPY ${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/pthreads)
file(COPY ${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake DESTINATION ${CURRENT_PACKAGES_DIR}/share/pthreads_windows)
+
+set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)
diff --git a/ports/qt5-activeqt/CONTROL b/ports/qt5-activeqt/CONTROL
index 4ec2594b3..e4aa3b5c1 100644
--- a/ports/qt5-activeqt/CONTROL
+++ b/ports/qt5-activeqt/CONTROL
@@ -2,3 +2,4 @@ Source: qt5-activeqt
Version: 5.12.5
Description: Qt5 ActiveQt Module - ActiveX components
Build-Depends: qt5-base
+Supports: windows \ No newline at end of file
diff --git a/ports/qt5-connectivity/CONTROL b/ports/qt5-connectivity/CONTROL
index 0bec2a8b4..245cfa1b1 100644
--- a/ports/qt5-connectivity/CONTROL
+++ b/ports/qt5-connectivity/CONTROL
@@ -1,4 +1,4 @@
Source: qt5-connectivity
Version: 5.12.5-1
Description: Qt5 Connectivity module - Provides access to Bluetooth and NFC hardware
-Build-Depends: qt5-base, qt5-androidextras (android)
+Build-Depends: qt5-base
diff --git a/ports/qt5-macextras/CONTROL b/ports/qt5-macextras/CONTROL
index 21b0ad5fa..6bd46f216 100644
--- a/ports/qt5-macextras/CONTROL
+++ b/ports/qt5-macextras/CONTROL
@@ -2,3 +2,4 @@ Source: qt5-macextras
Version: 5.12.5
Description: Qt5 Mac Extras Module. Provides platform-specific APIs for mac.
Build-Depends: qt5-base
+Supports: osx \ No newline at end of file
diff --git a/ports/qt5-purchasing/CONTROL b/ports/qt5-purchasing/CONTROL
index f970ba418..f83c48053 100644
--- a/ports/qt5-purchasing/CONTROL
+++ b/ports/qt5-purchasing/CONTROL
@@ -1,4 +1,4 @@
Source: qt5-purchasing
Version: 5.12.5-1
Description: Qt5 Purchasing Module - Enables in-app purchase of products in Qt applications.
-Build-Depends: qt5-base, qt5-declarative, qt5-androidextras (android)
+Build-Depends: qt5-base, qt5-declarative
diff --git a/ports/qt5-winextras/CONTROL b/ports/qt5-winextras/CONTROL
index 5d948ee5c..3f65220bf 100644
--- a/ports/qt5-winextras/CONTROL
+++ b/ports/qt5-winextras/CONTROL
@@ -2,3 +2,4 @@ Source: qt5-winextras
Version: 5.12.5-1
Description: Qt5 Windows Extras Module. Provides platform-specific APIs for Windows.
Build-Depends: qt5-base, atlmfc (windows), qt5-declarative, qt5-multimedia
+Supports: windows \ No newline at end of file
diff --git a/ports/rabit/CONTROL b/ports/rabit/CONTROL
index 7b07cba7b..64dd8ea8d 100644
--- a/ports/rabit/CONTROL
+++ b/ports/rabit/CONTROL
@@ -3,4 +3,4 @@ Version: 0.1-2
Homepage: https://github.com/dmlc/rabit
Description: rabit is a light weight library that provides a fault tolerant interface of Allreduce and Broadcast. It is designed to support easy implementations of distributed machine learning programs, many of which fall naturally under the Allreduce abstraction.
Build-Depends: dmlc
-
+Supports: !uwp
diff --git a/ports/raylib/CONTROL b/ports/raylib/CONTROL
index 8d50803e6..2113f5760 100644
--- a/ports/raylib/CONTROL
+++ b/ports/raylib/CONTROL
@@ -1,6 +1,7 @@
Source: raylib
Version: 2.5.0
Description: A simple and easy-to-use library to enjoy videogames programming
+Supports: !(arm|uwp)
#Build-Depends: glfw3
Feature: non-audio
diff --git a/ports/readline/CONTROL b/ports/readline/CONTROL
index 4fdb10939..c487f389b 100644
--- a/ports/readline/CONTROL
+++ b/ports/readline/CONTROL
@@ -2,3 +2,4 @@ Source: readline
Version: 0
Description: GNU readline and history libraries
Build-Depends: readline-win32 (windows)
+Supports: !uwp \ No newline at end of file
diff --git a/ports/rhash/CONTROL b/ports/rhash/CONTROL
index a2bb52c2f..8b838cc39 100644
--- a/ports/rhash/CONTROL
+++ b/ports/rhash/CONTROL
@@ -2,3 +2,4 @@ Source: rhash
Version: 1.3.8
Homepage: https://github.com/rhash/RHash
Description: C library for computing a wide variety of hash sums
+Supports: !uwp
diff --git a/ports/sciter/CONTROL b/ports/sciter/CONTROL
index 10beb200a..b835b87e1 100644
--- a/ports/sciter/CONTROL
+++ b/ports/sciter/CONTROL
@@ -2,3 +2,4 @@ Source: sciter
Version: 4.2.6.9-2
Homepage: https://github.com/c-smile/sciter-sdk
Description: Sciter is an embeddable HTML/CSS/scripting engine.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/septag-sx/CONTROL b/ports/septag-sx/CONTROL
index ee9917e66..a41e214af 100644
--- a/ports/septag-sx/CONTROL
+++ b/ports/septag-sx/CONTROL
@@ -1,3 +1,4 @@
Source: septag-sx
Version: 2019-05-07-2
Description: Portable base library for C programmers, designed for performance and simplicity.
+Supports: !(uwp|arm) \ No newline at end of file
diff --git a/ports/simdjson/CONTROL b/ports/simdjson/CONTROL
index 14f70df1c..fe34d9af3 100644
--- a/ports/simdjson/CONTROL
+++ b/ports/simdjson/CONTROL
@@ -2,3 +2,4 @@ Source: simdjson
Version: 2019-12-27
Description: A extremely fast JSON library that can parse gigabytes of JSON per second
Homepage: https://github.com/lemire/simdjson
+Supports: !(x86|arm|arm64) \ No newline at end of file
diff --git a/ports/soundtouch/CONTROL b/ports/soundtouch/CONTROL
index 7ce1c2ba6..28b6ac87c 100644
--- a/ports/soundtouch/CONTROL
+++ b/ports/soundtouch/CONTROL
@@ -3,3 +3,4 @@ Version: 2.0.0-4
Homepage: https://www.surina.net/soundtouch
Description: SoundTouch is an open-source audio processing library for changing the Tempo, Pitch and Playback Rates of audio streams or audio files.
Build-Depends: atlmfc (windows)
+Supports: !uwp \ No newline at end of file
diff --git a/ports/spdk-dpdk/CONTROL b/ports/spdk-dpdk/CONTROL
index 02647149a..61d1415cd 100644
--- a/ports/spdk-dpdk/CONTROL
+++ b/ports/spdk-dpdk/CONTROL
@@ -1,4 +1,4 @@
Source: spdk-dpdk
Version: 20181124
Description: SPDK mirror of DPDK. A set of libraries and drivers for fast packet processing
-
+Supports: linux
diff --git a/ports/spdk-ipsec/CONTROL b/ports/spdk-ipsec/CONTROL
index 3f8e1a034..7adb9c4c9 100644
--- a/ports/spdk-ipsec/CONTROL
+++ b/ports/spdk-ipsec/CONTROL
@@ -1,4 +1,4 @@
Source: spdk-ipsec
Version: 20180711
Description: SPDK mirror of ipsec. Intel(R) Multi-Buffer Crypto for IPsec Library
-
+Supports: x64
diff --git a/ports/spdk-isal/CONTROL b/ports/spdk-isal/CONTROL
index abfbe3de0..1a134ae14 100644
--- a/ports/spdk-isal/CONTROL
+++ b/ports/spdk-isal/CONTROL
@@ -1,4 +1,4 @@
Source: spdk-isal
Version: 20181006
Description: SPDK mirror of isa-l. Intel(R) Intelligent Storage Acceleration Library
-
+Supports: x64
diff --git a/ports/spdk/CONTROL b/ports/spdk/CONTROL
index 5e2cf3ca2..0233395c1 100644
--- a/ports/spdk/CONTROL
+++ b/ports/spdk/CONTROL
@@ -1,4 +1,5 @@
Source: spdk
Version: 19.01.1
Description: Storage Performance Development Kit
-Build-Depends: spdk-dpdk, spdk-ipsec, spdk-isal \ No newline at end of file
+Build-Depends: spdk-dpdk, spdk-ipsec, spdk-isal
+Supports: linux \ No newline at end of file
diff --git a/ports/teemo/CONTROL b/ports/teemo/CONTROL
index 2ee045a35..4d96fe5af 100644
--- a/ports/teemo/CONTROL
+++ b/ports/teemo/CONTROL
@@ -1,5 +1,5 @@
Source: teemo
-Version: 1.2
+Version: 1.2-1
Build-Depends: curl[non-http], cpprestsdk
Description: C++ File Download Library, support Multithreading, Breakpoint Transmission, Speed Limit, Real-time Speed.
Homepage: https://github.com/winsoft666/teemo \ No newline at end of file
diff --git a/ports/teemo/adjust-install-dir.patch b/ports/teemo/adjust-install-dir.patch
new file mode 100644
index 000000000..3ca1dcf56
--- /dev/null
+++ b/ports/teemo/adjust-install-dir.patch
@@ -0,0 +1,22 @@
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index 20de97c..0009c8a 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -108,7 +108,7 @@ set_target_properties(${LIB_NAME}
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" )
+
+ target_include_directories(${LIB_NAME} INTERFACE
+- $<INSTALL_INTERFACE:include>)
++ $<INSTALL_INTERFACE:include/teemo>)
+
+ install(TARGETS ${LIB_NAME}
+ EXPORT ${LIB_NAME}-target
+@@ -117,7 +117,7 @@ install(TARGETS ${LIB_NAME}
+ ARCHIVE DESTINATION lib)
+
+
+-install(FILES ${HEADER_FILES} DESTINATION include)
++install(FILES ${HEADER_FILES} DESTINATION include/teemo)
+
+
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../CMake/teemo-config.cmake
diff --git a/ports/teemo/portfile.cmake b/ports/teemo/portfile.cmake
index df79626c0..07b5d5a53 100644
--- a/ports/teemo/portfile.cmake
+++ b/ports/teemo/portfile.cmake
@@ -6,6 +6,9 @@ vcpkg_from_github(
REF 15edb1705d18ee78b32516a8ae52d6b10507af62
SHA512 7dbe917d48b1e8c4b004bad33d8a82524e501d8bec6cdeca4e89ebbe8ed79fa484028c3afd365347e31fa83f64a6f0f5a42ea0063baa7c0985824fb3dffcc8f2
HEAD_REF master
+ PATCHES
+ # Installing "slice.h" to the root include directory causes build issues in many other libraries
+ adjust-install-dir.patch
)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" TEEMO_STATIC)
@@ -26,13 +29,13 @@ elseif(EXISTS ${CURRENT_PACKAGES_DIR}/share/teemo)
vcpkg_fixup_cmake_targets(CONFIG_PATH share/teemo)
endif()
-file(READ ${CURRENT_PACKAGES_DIR}/include/teemo.h TEEMO_H)
+file(READ ${CURRENT_PACKAGES_DIR}/include/teemo/teemo.h TEEMO_H)
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
string(REPLACE "#ifdef TEEMO_STATIC" "#if 1" TEEMO_H "${TEEMO_H}")
else()
string(REPLACE "#ifdef TEEMO_STATIC" "#if 0" TEEMO_H "${TEEMO_H}")
endif()
-file(WRITE ${CURRENT_PACKAGES_DIR}/include/teemo.h "${TEEMO_H}")
+file(WRITE ${CURRENT_PACKAGES_DIR}/include/teemo/teemo.h "${TEEMO_H}")
file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
diff --git a/ports/telnetpp/CONTROL b/ports/telnetpp/CONTROL
index 53dd8657a..ffb5ef01a 100644
--- a/ports/telnetpp/CONTROL
+++ b/ports/telnetpp/CONTROL
@@ -4,6 +4,7 @@ Homepage: https://github.com/KazDragon/telnetpp
Description: Telnet++ is an implementation of the Telnet Session Layer protocol using C++14
Build-Depends: boost-container, boost-signals2, boost-variant, gsl-lite, boost-exception
Default-Features: zlib
+Supports: !uwp
Feature: zlib
Description: Zlib support
diff --git a/ports/tensorflow-cc/CONTROL b/ports/tensorflow-cc/CONTROL
index 29f15a376..8bcc1cc35 100644
--- a/ports/tensorflow-cc/CONTROL
+++ b/ports/tensorflow-cc/CONTROL
@@ -2,3 +2,4 @@ Source: tensorflow-cc
Version: 1.14-1
Description: Library for computation using data flow graphs for scalable machine learning
Build-Depends: c-ares
+Supports: !x86 \ No newline at end of file
diff --git a/ports/tgui/portfile.cmake b/ports/tgui/portfile.cmake
index 33e3dd9bf..736946af9 100644
--- a/ports/tgui/portfile.cmake
+++ b/ports/tgui/portfile.cmake
@@ -11,7 +11,7 @@ set(TGUI_TOOLS_PATH ${CURRENT_PACKAGES_DIR}/tools/tgui)
# Enable static build
file(REMOVE "${SOURCE_PATH}/cmake/Modules/FindSFML.cmake")
-string(COMPARE EQUAL ${VCPKG_LIBRARY_LINKAGE} "dynamic" TGUI_SHARED_LIBS)
+string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" TGUI_SHARED_LIBS)
# gui-builder
set(BUILD_GUI_BUILDER OFF)
@@ -21,6 +21,7 @@ endif()
vcpkg_configure_cmake(
SOURCE_PATH "${SOURCE_PATH}"
+ DISABLE_PARALLEL_CONFIGURE
PREFER_NINJA
OPTIONS
-DTGUI_BUILD_GUI_BUILDER=${BUILD_GUI_BUILDER}
diff --git a/ports/tinkerforge/CONTROL b/ports/tinkerforge/CONTROL
index 5eb67e96b..da38ec368 100644
--- a/ports/tinkerforge/CONTROL
+++ b/ports/tinkerforge/CONTROL
@@ -1,3 +1,4 @@
Source: tinkerforge
Version: 2.1.25
Description: Tinkerforge C API bindings for bricks and bricklets
+Supports: !uwp \ No newline at end of file
diff --git a/ports/unicorn/CONTROL b/ports/unicorn/CONTROL
index 74d581487..6dbc5f123 100644
--- a/ports/unicorn/CONTROL
+++ b/ports/unicorn/CONTROL
@@ -2,3 +2,4 @@ Source: unicorn
Version: 2019-07-11
Homepage: https://github.com/unicorn-engine/unicorn
Description: Unicorn is a lightweight multi-platform, multi-architecture CPU emulator framework
+Supports: !uwp
diff --git a/ports/upb/CONTROL b/ports/upb/CONTROL
index d42b9e367..cb9b6041d 100644
--- a/ports/upb/CONTROL
+++ b/ports/upb/CONTROL
@@ -1,13 +1,4 @@
Source: upb
-Version: 2019-10-21
+Version: 2019-10-21-1
Homepage: https://github.com/protocolbuffers/upb/
Description: μpb (often written 'upb') is a small protobuf implementation written in C.
-
-Feature: asan
-Description: build with asan support
-
-Feature: ubsan
-Description: build with ubsan support
-
-Feature: tests
-Description: build tests \ No newline at end of file
diff --git a/ports/upb/add-cmake-install.patch b/ports/upb/add-cmake-install.patch
new file mode 100644
index 000000000..ece6b8db4
--- /dev/null
+++ b/ports/upb/add-cmake-install.patch
@@ -0,0 +1,60 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 836c5ff..6eb8bb5 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -8,7 +8,7 @@ else()
+ cmake_policy(VERSION 3.12)
+ endif()
+
+-cmake_minimum_required (VERSION 3.0)
++cmake_minimum_required (VERSION 3.14)
+ cmake_policy(SET CMP0048 NEW)
+
+ project(upb)
+@@ -59,7 +59,7 @@ elseif(UNIX)
+ endif()
+
+ enable_testing()
+-
++add_library(descriptor_upbproto INTERFACE)
+ add_library(upb
+ upb/decode.c
+ upb/encode.c
+@@ -136,12 +136,35 @@ target_link_libraries(upb_cc_bindings INTERFACE
+ descriptor_upbproto
+ handlers
+ upb)
+-add_library(upb_test
++if(ENABLE_TESTING)
++add_executable(upb_test
+ tests/testmain.cc
+ tests/test_util.h
+ tests/upb_test.h)
+ target_link_libraries(upb_test
+ handlers
+ upb)
++endif()
+
+-
++install(
++ DIRECTORY upb
++ DESTINATION include
++ FILES_MATCHING
++ PATTERN "*.h"
++ PATTERN "*.inc"
++ PATTERN "*.int.h" EXCLUDE
++)
++target_include_directories(upb PUBLIC $<INSTALL_INTERFACE:include>)
++install(TARGETS
++ upb
++ upb_cc_bindings
++ upb_json
++ upb_pb
++ table
++ descriptor_upbproto
++ handlers
++ legacy_msg_reflection
++ reflection
++ EXPORT upb-config
++)
++install(EXPORT upb-config NAMESPACE upb:: DESTINATION share/upb)
diff --git a/ports/upb/fix-cmakelists.patch b/ports/upb/fix-cmakelists.patch
deleted file mode 100644
index 4c7ab1413..000000000
--- a/ports/upb/fix-cmakelists.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 836c5ff..6ee66a7 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -58,90 +58,148 @@ elseif(UNIX)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id")
- endif()
-
--enable_testing()
-+if (ENABLE_TEST)
-+ enable_testing()
-+endif()
-
-+set(UPB_HDRS
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/generated_util.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/msg.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/table.int.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/port_def.inc
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/port_undef.inc
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/decode.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/encode.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/upb.h
-+)
-+
-+set(UBP_PROJECTS upb)
- add_library(upb
- upb/decode.c
- upb/encode.c
-- upb/generated_util.h
- upb/msg.c
-- upb/msg.h
- upb/port.c
-- upb/port_def.inc
-- upb/port_undef.inc
- upb/table.c
-- upb/table.int.h
- upb/upb.c
-- upb/decode.h
-- upb/encode.h
-- upb/upb.h)
-+ upb/upb.h
-+ ${UPB_HDRS})
-+
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me)
- add_library(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE)
- target_link_libraries(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE
- upb)
-+
-+set(REFLECTION_HDRS
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/def.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/msgfactory.h
-+)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} reflection)
- add_library(reflection
- upb/def.c
- upb/msgfactory.c
-- upb/def.h
-- upb/msgfactory.h)
-+ ${REFLECTION_HDRS})
- target_link_libraries(reflection
- descriptor_upbproto
- table
- upb)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} table)
- add_library(table INTERFACE)
- target_link_libraries(table INTERFACE
- upb)
-+
-+set(LEGACY_MSG_HDRS ${CMAKE_CURRENT_LIST_DIR}/upb/legacy_msg_reflection.h)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} legacy_msg_reflection)
- add_library(legacy_msg_reflection
- upb/legacy_msg_reflection.c
-- upb/legacy_msg_reflection.h)
-+ ${LEGACY_MSG_HDRS})
- target_link_libraries(legacy_msg_reflection
- table
- upb)
-+
-+set(HANDLERS_HDRS
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/handlers-inl.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/handlers.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/sink.h
-+)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} handlers)
- add_library(handlers
- upb/handlers.c
-- upb/handlers-inl.h
- upb/sink.c
-- upb/handlers.h
-- upb/sink.h)
-+ ${HANDLERS_HDRS})
- target_link_libraries(handlers
- reflection
- table
- upb)
-+
-+set(UPB_PB_HDRS
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/pb/decoder.int.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/pb/varint.int.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/pb/decoder.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/pb/encoder.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/pb/textprinter.h
-+)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} upb_pb)
- add_library(upb_pb
- upb/pb/compile_decoder.c
- upb/pb/decoder.c
-- upb/pb/decoder.int.h
- upb/pb/encoder.c
- upb/pb/textprinter.c
- upb/pb/varint.c
-- upb/pb/varint.int.h
-- upb/pb/decoder.h
-- upb/pb/encoder.h
-- upb/pb/textprinter.h)
-+ ${UPB_PB_HDRS})
- target_link_libraries(upb_pb
- descriptor_upbproto
- handlers
- reflection
- table
- upb)
-+
-+set(UPB_JSON_HDRS
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/json/parser.h
-+ ${CMAKE_CURRENT_LIST_DIR}/upb/json/printer.h
-+)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} upb_json)
- add_library(upb_json
- generated_for_cmake/upb/json/parser.c
- upb/json/printer.c
-- upb/json/parser.h
-- upb/json/printer.h)
-+ ${UPB_JSON_HDRS})
- target_link_libraries(upb_json
- upb
- upb_pb)
-+
-+set(UBP_PROJECTS ${UBP_PROJECTS} upb_cc_bindings)
- add_library(upb_cc_bindings INTERFACE)
- target_link_libraries(upb_cc_bindings INTERFACE
- descriptor_upbproto
- handlers
- upb)
--add_library(upb_test
-- tests/testmain.cc
-- tests/test_util.h
-- tests/upb_test.h)
--target_link_libraries(upb_test
-- handlers
-- upb)
--
-
-+if (ENABLE_TEST)
-+ set(UBP_PROJECTS ${UBP_PROJECTS} upb_test)
-+ add_library(upb_test
-+ tests/testmain.cc
-+ tests/test_util.h
-+ tests/upb_test.h)
-+ target_link_libraries(upb_test
-+ handlers
-+ upb)
-+endif()
-+
-+install(FILES ${UPB_HDRS} ${REFLECTION_HDRS} ${LEGACY_MSG_HDRS} ${HANDLERS_HDRS} DESTINATION include/upb)
-+install(FILES ${UPB_PB_HDRS} DESTINATION include/upb/pb)
-+install(FILES ${UPB_JSON_HDRS} DESTINATION include/upb/json)
-+
-+foreach(PROJ ${UBP_PROJECTS})
-+ install(
-+ TARGETS ${PROJ}
-+ RUNTIME DESTINATION bin
-+ LIBRARY DESTINATION lib
-+ ARCHIVE DESTINATION lib
-+ )
-+endforeach()
-\ No newline at end of file
diff --git a/ports/upb/portfile.cmake b/ports/upb/portfile.cmake
index 303587cea..b5a46253c 100644
--- a/ports/upb/portfile.cmake
+++ b/ports/upb/portfile.cmake
@@ -1,29 +1,27 @@
-vcpkg_fail_port_install(ON_TARGET "Windows")
+vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
vcpkg_from_github(
- OUT_SOURCE_PATH SOURCE_PATH
- REPO protocolbuffers/upb
- REF 9effcbcb27f0a665f9f345030188c0b291e32482
- SHA512 416ff26ec21181d53be23e94203205072152ab3a8e4b3b28d16263a601995fd2d2f8afe5d8cfbecdac8543249482287b9fe6129314f7c9a7880660f5508bb85e
+ OUT_SOURCE_PATH SOURCE_PATH
+ REPO protocolbuffers/upb
+ REF 9effcbcb27f0a665f9f345030188c0b291e32482
+ SHA512 416ff26ec21181d53be23e94203205072152ab3a8e4b3b28d16263a601995fd2d2f8afe5d8cfbecdac8543249482287b9fe6129314f7c9a7880660f5508bb85e
HEAD_REF master
- PATCHES fix-cmakelists.patch
-)
-
-vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
- asan UPB_ENABLE_ASAN
- ubsan UPB_ENABLE_UBSAN
- tests ENABLE_TEST
+ PATCHES add-cmake-install.patch
)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
- OPTIONS ${FEATURE_OPTIONS}
)
vcpkg_install_cmake()
+vcpkg_fixup_cmake_targets()
vcpkg_copy_pdbs()
-file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
+file(REMOVE_RECURSE
+ ${CURRENT_PACKAGES_DIR}/debug/include
+ # empty folder
+ ${CURRENT_PACKAGES_DIR}/include/upb/bindings/lua/upb
+)
file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
diff --git a/ports/uvatlas/CONTROL b/ports/uvatlas/CONTROL
index 0c0cb84b3..e1621c5b5 100644
--- a/ports/uvatlas/CONTROL
+++ b/ports/uvatlas/CONTROL
@@ -1,4 +1,5 @@
Source: uvatlas
Version: dec2019
Homepage: https://github.com/Microsoft/UVAtlas
-Description: UVAtlas isochart texture atlas \ No newline at end of file
+Description: UVAtlas isochart texture atlas
+Supports: windows \ No newline at end of file
diff --git a/ports/vectorclass/CONTROL b/ports/vectorclass/CONTROL
index cc3471358..a5110d95c 100644
--- a/ports/vectorclass/CONTROL
+++ b/ports/vectorclass/CONTROL
@@ -2,3 +2,4 @@ Source: vectorclass
Version: 2.00.01
Homepage: https://github.com/vectorclass/version2
Description: C++ class library for using the Single Instruction Multiple Data (SIMD) instructions in modern Microprocessors
+Supports: !(arm|arm64) \ No newline at end of file
diff --git a/ports/winreg/CONTROL b/ports/winreg/CONTROL
index 6b798d4d0..0e2cc7188 100644
--- a/ports/winreg/CONTROL
+++ b/ports/winreg/CONTROL
@@ -1,4 +1,5 @@
Source: winreg
Version: 1.2.1-1
Homepage: https://github.com/GiovanniDicanio/WinReg
-Description: High-level C++ wrapper around the Windows Registry C API. \ No newline at end of file
+Description: High-level C++ wrapper around the Windows Registry C API.
+Supports: windows || uwp \ No newline at end of file
diff --git a/ports/wintoast/CONTROL b/ports/wintoast/CONTROL
index d9d410796..033a5abdf 100644
--- a/ports/wintoast/CONTROL
+++ b/ports/wintoast/CONTROL
@@ -1,3 +1,4 @@
Source: wintoast
Version: 1.2.0
-Description: WinToast is a lightly library written in C++ which brings a complete integration of the modern toast notifications of Windows 8 & Windows 10. \ No newline at end of file
+Description: WinToast is a lightly library written in C++ which brings a complete integration of the modern toast notifications of Windows 8 & Windows 10.
+Supports: !uwp \ No newline at end of file
diff --git a/ports/x-plane/CONTROL b/ports/x-plane/CONTROL
index c151e8719..de1217a60 100644
--- a/ports/x-plane/CONTROL
+++ b/ports/x-plane/CONTROL
@@ -1,3 +1,4 @@
Source: x-plane
Version: 3.0.1-1
Description: The X-Plane Plugin SDK.
+Supports: !x86 \ No newline at end of file
diff --git a/ports/x265/CONTROL b/ports/x265/CONTROL
index 0ed00a54d..c94ba6801 100644
--- a/ports/x265/CONTROL
+++ b/ports/x265/CONTROL
@@ -1,4 +1,4 @@
Source: x265
-Version: 3.2-1
+Version: 3.2-3
Homepage: https://bitbucket.org/multicoreware/x265
Description: x265 is a H.265 / HEVC video encoder application library, designed to encode video or images into an H.265 / HEVC encoded bitstream.
diff --git a/ports/yasm/CONTROL b/ports/yasm/CONTROL
index 5cb349270..bdcaaea9f 100644
--- a/ports/yasm/CONTROL
+++ b/ports/yasm/CONTROL
@@ -2,3 +2,4 @@ Source: yasm
Version: 1.3.0
Homepage: https://github.com/yasm/yasm
Description: Yasm is a complete rewrite of the NASM assembler under the “new” BSD License.
+Supports: windows & !uwp & !arm \ No newline at end of file
diff --git a/ports/yoga/CONTROL b/ports/yoga/CONTROL
index 52e8498a3..5a0c6d260 100644
--- a/ports/yoga/CONTROL
+++ b/ports/yoga/CONTROL
@@ -2,3 +2,4 @@ Source: yoga
Version: 1.16.0-1
Homepage: https://github.com/facebook/yoga
Description: Yoga is a cross-platform layout engine which implements Flexbox
+Supports: !uwp
diff --git a/ports/z3/CONTROL b/ports/z3/CONTROL
index be11a9d7c..866f2cf5f 100644
--- a/ports/z3/CONTROL
+++ b/ports/z3/CONTROL
@@ -1,4 +1,5 @@
Source: z3
Version: 4.8.6
Homepage: https://github.com/Z3Prover/z3
-Description: Z3 is a theorem prover from Microsoft Research. \ No newline at end of file
+Description: Z3 is a theorem prover from Microsoft Research.
+Supports: !arm64 && !uwp
diff --git a/ports/zfp/CONTROL b/ports/zfp/CONTROL
index eb9505fa4..164bade9d 100644
--- a/ports/zfp/CONTROL
+++ b/ports/zfp/CONTROL
@@ -1,5 +1,5 @@
Source: zfp
-Version: 0.5.5-1
+Version: 0.5.5-2
Homepage: https://github.com/LLNL/zfp
Description: Zfp is an open source C/C++ library for compressed numerical arrays that support high throughput read and write random access. zfp also supports streaming compression of integer and floating-point data, e.g., for applications that read and write large data sets to and from disk. zfp is primarily written in C and C++ but also includes Python and Fortran bindings.
diff --git a/ports/zfp/portfile.cmake b/ports/zfp/portfile.cmake
index 7c9af2547..d189762b7 100644
--- a/ports/zfp/portfile.cmake
+++ b/ports/zfp/portfile.cmake
@@ -31,12 +31,16 @@ vcpkg_install_cmake()
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)
-if(VCPKG_LIBRARY_LINKAGE STREQUAL static)
+if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin)
endif()
vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/${PORT})
+# Rename problematic root include "bitstream.h"; conflicts with x265's private headers
+file(RENAME ${CURRENT_PACKAGES_DIR}/include/bitstream.h ${CURRENT_PACKAGES_DIR}/include/zfp/bitstream.h)
+vcpkg_replace_string(${CURRENT_PACKAGES_DIR}/include/zfp.h "\"bitstream.h\"" "\"zfp/bitstream.h\"")
+
vcpkg_copy_pdbs()
file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright) \ No newline at end of file
diff --git a/scripts/ci.baseline.txt b/scripts/ci.baseline.txt
index e13f9870f..b658bcea3 100644
--- a/scripts/ci.baseline.txt
+++ b/scripts/ci.baseline.txt
@@ -224,6 +224,9 @@ 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:x64-linux=skip
+charls:x64-osx=skip
chartdir:arm64-windows=fail
chartdir:arm-uwp=fail
chartdir:x64-uwp=fail
@@ -654,7 +657,6 @@ jemalloc:x64-uwp=fail
jemalloc:x64-windows-static=fail
jinja2cpplight:arm-uwp=fail
jinja2cpplight:x64-uwp=fail
-jsonnet:x64-osx=fail
kd-soap:x64-linux=fail
kd-soap:x64-osx=fail
kd-soap:x64-windows-static=fail
@@ -785,12 +787,15 @@ libmariadb:x64-uwp = skip
libmariadb:x64-windows = skip
libmariadb:x64-windows-static = skip
libmariadb:x86-windows = skip
-libmesh:arm64-windows=fail
-libmesh:arm-uwp=fail
-libmesh:x64-uwp=fail
-libmesh:x64-windows=fail
-libmesh:x64-windows-static=fail
-libmesh:x86-windows=fail
+# 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
libmicrohttpd:arm64-windows=fail
libmicrohttpd:arm-uwp=fail
libmicrohttpd:x64-linux=fail
@@ -1057,11 +1062,18 @@ minizip:x64-uwp=fail
mlpack:x64-linux=ignore
mman:x64-linux=fail
mman:x64-osx=fail
-mmx:x64-windows=ignore
-mmx:x64-windows-static=ignore
-mmx:x86-windows=ignore
+# 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
mongo-c-driver:arm64-windows=fail
-mongo-c-driver:x64-osx=fail
+# Flaky strange linker error
+mongo-c-driver:x64-osx=skip
mongoose:arm-uwp=fail
mongoose:x64-uwp=fail
monkeys-audio:arm64-windows=fail
@@ -1722,12 +1734,8 @@ unrar:x64-linux=fail
unrar:x64-osx=fail
unrar:x64-uwp=fail
unrar:x64-windows-static=fail
-upb:arm64-windows=fail
upb:arm-uwp=fail
upb:x64-uwp=fail
-upb:x64-windows=fail
-upb:x64-windows-static=fail
-upb:x86-windows=fail
urdfdom:x64-windows-static=fail
usd:x64-linux=ignore
usd:x86-windows=fail
diff --git a/scripts/cmake/vcpkg_fixup_cmake_targets.cmake b/scripts/cmake/vcpkg_fixup_cmake_targets.cmake
index a042d9124..d72381be5 100644
--- a/scripts/cmake/vcpkg_fixup_cmake_targets.cmake
+++ b/scripts/cmake/vcpkg_fixup_cmake_targets.cmake
@@ -30,7 +30,6 @@ function(vcpkg_fixup_cmake_targets)
set(_vfct_TARGET_PATH share/${PORT})
endif()
-
if(NOT VCPKG_CMAKE_SYSTEM_NAME OR VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
set(EXECUTABLE_SUFFIX "\\.exe")
else()
@@ -49,7 +48,6 @@ function(vcpkg_fixup_cmake_targets)
set(DEBUG_CONFIG ${CURRENT_PACKAGES_DIR}/debug/${_vfct_CONFIG_PATH})
set(RELEASE_CONFIG ${CURRENT_PACKAGES_DIR}/${_vfct_CONFIG_PATH})
-
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
if(NOT EXISTS ${DEBUG_CONFIG})
message(FATAL_ERROR "'${DEBUG_CONFIG}' does not exist.")
diff --git a/scripts/get_triplet_environment.cmake b/scripts/get_triplet_environment.cmake
deleted file mode 100644
index 3b0b9fbef..000000000
--- a/scripts/get_triplet_environment.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-include(${CMAKE_TRIPLET_FILE})
-if (DEFINED VCPKG_ENV_OVERRIDES_FILE)
- include(${VCPKG_ENV_OVERRIDES_FILE})
-endif()
-
-# GUID used as a flag - "cut here line"
-message("c35112b6-d1ba-415b-aa5d-81de856ef8eb")
-message("VCPKG_TARGET_ARCHITECTURE=${VCPKG_TARGET_ARCHITECTURE}")
-message("VCPKG_CMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}")
-message("VCPKG_CMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}")
-message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}")
-message("VCPKG_VISUAL_STUDIO_PATH=${VCPKG_VISUAL_STUDIO_PATH}")
-message("VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
-message("VCPKG_BUILD_TYPE=${VCPKG_BUILD_TYPE}")
-message("VCPKG_ENV_PASSTHROUGH=${VCPKG_ENV_PASSTHROUGH}")
-message("VCPKG_PUBLIC_ABI_OVERRIDE=${VCPKG_PUBLIC_ABI_OVERRIDE}")
diff --git a/scripts/ports.cmake b/scripts/ports.cmake
index 1aea1ffa3..20e59a184 100644
--- a/scripts/ports.cmake
+++ b/scripts/ports.cmake
@@ -78,13 +78,9 @@ if(CMD MATCHES "^BUILD$")
include(${CMAKE_TRIPLET_FILE})
- if (DEFINED VCPKG_ENV_OVERRIDES_FILE)
- include(${VCPKG_ENV_OVERRIDES_FILE})
- endif()
-
- if (DEFINED VCPKG_PORT_TOOLCHAINS)
- foreach(VCPKG_PORT_TOOLCHAIN ${VCPKG_PORT_TOOLCHAINS})
- include(${VCPKG_PORT_TOOLCHAIN})
+ if (DEFINED VCPKG_PORT_CONFIGS)
+ foreach(VCPKG_PORT_CONFIG ${VCPKG_PORT_CONFIGS})
+ include(${VCPKG_PORT_CONFIG})
endforeach()
endif()
@@ -115,6 +111,9 @@ if(CMD MATCHES "^BUILD$")
if (DEFINED VCPKG_POLICY_EMPTY_INCLUDE_FOLDER)
file(APPEND ${BUILD_INFO_FILE_PATH} "PolicyEmptyIncludeFolder: ${VCPKG_POLICY_EMPTY_INCLUDE_FOLDER}\n")
endif()
+ if (DEFINED VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS)
+ file(APPEND ${BUILD_INFO_FILE_PATH} "PolicyAllowRestrictedHeaders: ${VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS}\n")
+ endif()
if (DEFINED VCPKG_HEAD_VERSION)
file(APPEND ${BUILD_INFO_FILE_PATH} "Version: ${VCPKG_HEAD_VERSION}\n")
endif()
diff --git a/scripts/vcpkg_get_dep_info.cmake b/scripts/vcpkg_get_dep_info.cmake
new file mode 100644
index 000000000..92212b82d
--- /dev/null
+++ b/scripts/vcpkg_get_dep_info.cmake
@@ -0,0 +1,19 @@
+function(vcpkg_get_dep_info PORT VCPKG_TRIPLET_ID)
+ message("d8187afd-ea4a-4fc3-9aa4-a6782e1ed9af")
+ vcpkg_triplet_file(${VCPKG_TRIPLET_ID})
+
+ # GUID used as a flag - "cut here line"
+ message("c35112b6-d1ba-415b-aa5d-81de856ef8eb
+VCPKG_TARGET_ARCHITECTURE=${VCPKG_TARGET_ARCHITECTURE}
+VCPKG_CMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}
+VCPKG_CMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}
+VCPKG_LIBRARY_LINKAGE=${VCPKG_LIBRARY_LINKAGE}
+VCPKG_CRT_LINKAGE=${VCPKG_CRT_LINKAGE}
+VCPKG_DEP_INFO_OVERRIDE_VARS=${VCPKG_DEP_INFO_OVERRIDE_VARS}
+CMAKE_HOST_SYSTEM_NAME=${CMAKE_HOST_SYSTEM_NAME}
+CMAKE_HOST_SYSTEM_PROCESSOR=${CMAKE_HOST_SYSTEM_PROCESSOR}
+CMAKE_HOST_SYSTEM_VERSION=${CMAKE_HOST_SYSTEM_VERSION}
+CMAKE_HOST_SYSTEM=${CMAKE_HOST_SYSTEM}
+e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f
+8c504940-be29-4cba-9f8f-6cd83e9d87b7")
+endfunction()
diff --git a/scripts/vcpkg_get_tags.cmake b/scripts/vcpkg_get_tags.cmake
new file mode 100644
index 000000000..ccdc4fea6
--- /dev/null
+++ b/scripts/vcpkg_get_tags.cmake
@@ -0,0 +1,28 @@
+function(vcpkg_get_tags PORT FEATURES VCPKG_TRIPLET_ID VCPKG_ABI_SETTINGS_FILE)
+ message("d8187afd-ea4a-4fc3-9aa4-a6782e1ed9af")
+ vcpkg_triplet_file(${VCPKG_TRIPLET_ID})
+
+ # GUID used as a flag - "cut here line"
+ message("c35112b6-d1ba-415b-aa5d-81de856ef8eb
+VCPKG_TARGET_ARCHITECTURE=${VCPKG_TARGET_ARCHITECTURE}
+VCPKG_CMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}
+VCPKG_CMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}
+VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}
+VCPKG_VISUAL_STUDIO_PATH=${VCPKG_VISUAL_STUDIO_PATH}
+VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}
+VCPKG_BUILD_TYPE=${VCPKG_BUILD_TYPE}
+e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f")
+
+ # Just to enforce the user didn't set it in the triplet file
+ if (DEFINED VCPKG_PUBLIC_ABI_OVERRIDE)
+ set(VCPKG_PUBLIC_ABI_OVERRIDE)
+ message(WARNING "VCPKG_PUBLIC_ABI_OVERRIDE set in the triplet will be ignored.")
+ endif()
+ include("${VCPKG_ABI_SETTINGS_FILE}" OPTIONAL)
+
+ message("c35112b6-d1ba-415b-aa5d-81de856ef8eb
+VCPKG_PUBLIC_ABI_OVERRIDE=${VCPKG_PUBLIC_ABI_OVERRIDE}
+VCPKG_ENV_PASSTHROUGH=${VCPKG_ENV_PASSTHROUGH}
+e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f
+8c504940-be29-4cba-9f8f-6cd83e9d87b7")
+endfunction()
diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt
index 80548a819..f9cb2e7e9 100644
--- a/toolsrc/VERSION.txt
+++ b/toolsrc/VERSION.txt
@@ -1 +1 @@
-"2020.01.17"
+"2020.01.18"
diff --git a/toolsrc/include/vcpkg-test/mockcmakevarprovider.h b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
new file mode 100644
index 000000000..03defdcdd
--- /dev/null
+++ b/toolsrc/include/vcpkg-test/mockcmakevarprovider.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <vcpkg/cmakevars.h>
+
+namespace vcpkg::Test
+{
+ struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider
+ {
+ void load_generic_triplet_vars(const Triplet& triplet) const override { generic_triplet_vars[triplet] = {}; }
+
+ void load_dep_info_vars(Span<const PackageSpec> specs) const override
+ {
+ for (auto&& spec : specs)
+ dep_info_vars[spec] = {};
+ }
+
+ void load_tag_vars(Span<const FullPackageSpec> specs,
+ const PortFileProvider::PortFileProvider& port_provider) const override
+ {
+ for (auto&& spec : specs)
+ tag_vars[spec.package_spec] = {};
+ Util::unused(port_provider);
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
+ const Triplet& triplet) const override;
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
+ const PackageSpec& spec) const override;
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
+ const PackageSpec& spec) const override;
+
+ mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_info_vars;
+ mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
+ mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
+ };
+}
diff --git a/toolsrc/include/vcpkg-test/util.h b/toolsrc/include/vcpkg-test/util.h
index 259b0ba7e..088a39b7d 100644
--- a/toolsrc/include/vcpkg-test/util.h
+++ b/toolsrc/include/vcpkg-test/util.h
@@ -17,6 +17,12 @@
namespace vcpkg::Test
{
+ std::unique_ptr<SourceControlFile> make_control_file(
+ const char* name,
+ const char* depends,
+ const std::vector<std::pair<const char*, const char*>>& features = {},
+ const std::vector<const char*>& default_features = {});
+
std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
const char* depends = "",
const char* default_features = "",
@@ -27,6 +33,23 @@ namespace vcpkg::Test
const char* depends = "",
const char* triplet = "x86-windows");
+ /// <summary>
+ /// Map of source control files by their package name.
+ /// </summary>
+ struct PackageSpecMap
+ {
+ std::unordered_map<std::string, SourceControlFileLocation> map;
+ Triplet triplet;
+ PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept : triplet(t) {}
+
+ PackageSpec emplace(const char* name,
+ const char* depends = "",
+ const std::vector<std::pair<const char*, const char*>>& features = {},
+ const std::vector<const char*>& default_features = {});
+
+ PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl);
+ };
+
vcpkg::PackageSpec unsafe_pspec(std::string name, vcpkg::Triplet t = vcpkg::Triplet::X86_WINDOWS);
template<class T, class S>
diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h
index 683735b1c..f368a872d 100644
--- a/toolsrc/include/vcpkg/base/graphs.h
+++ b/toolsrc/include/vcpkg/base/graphs.h
@@ -1,11 +1,10 @@
#pragma once
+#include <string>
#include <unordered_map>
-#include <unordered_set>
-#include <utility>
+#include <vector>
#include <vcpkg/base/checks.h>
-#include <vcpkg/base/span.h>
#include <vcpkg/base/system.print.h>
namespace vcpkg::Graphs
@@ -95,10 +94,8 @@ namespace vcpkg::Graphs
}
}
- template<class VertexContainer, class V, class U>
- std::vector<U> topological_sort(VertexContainer starting_vertices,
- const AdjacencyProvider<V, U>& f,
- Randomizer* randomizer)
+ template<class Range, class V, class U>
+ std::vector<U> topological_sort(Range starting_vertices, const AdjacencyProvider<V, U>& f, Randomizer* randomizer)
{
std::vector<U> sorted;
std::unordered_map<V, ExplorationStatus> exploration_status;
@@ -112,40 +109,4 @@ namespace vcpkg::Graphs
return sorted;
}
-
- template<class V>
- struct Graph final : AdjacencyProvider<V, V>
- {
- public:
- void add_vertex(const V& v) { this->m_edges[v]; }
-
- void add_edge(const V& u, const V& v)
- {
- this->m_edges[v];
- this->m_edges[u].insert(v);
- }
-
- std::vector<V> vertex_list() const
- {
- std::vector<V> vertex_list;
- for (auto&& vertex : this->m_edges)
- vertex_list.emplace_back(vertex.first);
- return vertex_list;
- }
-
- std::vector<V> adjacency_list(const V& vertex) const override
- {
- const std::unordered_set<V>& as_set = this->m_edges.at(vertex);
- return std::vector<V>(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy
- }
-
- V load_vertex_data(const V& vertex) const override { return vertex; }
-
- // Note: this function indicates how tied this template is to the exact type it will be templated upon.
- // Possible fix: This type shouldn't implement to_string() and should instead be derived from?
- std::string to_string(const V& spec) const override { return spec->spec.to_string(); }
-
- private:
- std::unordered_map<V, std::unordered_set<V>> m_edges;
- };
}
diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h
index 4c805e2b4..a5ba884af 100644
--- a/toolsrc/include/vcpkg/base/span.h
+++ b/toolsrc/include/vcpkg/base/span.h
@@ -23,14 +23,13 @@ namespace vcpkg
constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) {}
constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {}
constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {}
- constexpr Span(std::initializer_list<T> l) noexcept : m_ptr(l.begin()), m_count(l.size()) {}
template<size_t N>
constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
{
}
- template<size_t N>
+ template<size_t N, class = std::enable_if_t<std::is_const_v<T>>>
constexpr Span(std::remove_const_t<T> (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
{
}
diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h
index ad628e071..849781b95 100644
--- a/toolsrc/include/vcpkg/base/util.h
+++ b/toolsrc/include/vcpkg/base/util.h
@@ -18,7 +18,7 @@ namespace vcpkg::Util
namespace Vectors
{
template<class Container, class T = ElementT<Container>>
- void concatenate(std::vector<T>* augend, const Container& addend)
+ void append(std::vector<T>* augend, const Container& addend)
{
augend->insert(augend->end(), addend.begin(), addend.end());
}
@@ -122,6 +122,12 @@ namespace vcpkg::Util
std::sort(begin(cont), end(cont), comp);
}
+ template<class Range, class Pred>
+ bool any_of(Range&& rng, Pred pred)
+ {
+ return std::any_of(rng.begin(), rng.end(), std::move(pred));
+ }
+
template<class Range>
Range&& sort_unique_erase(Range&& cont)
{
@@ -220,4 +226,10 @@ namespace vcpkg::Util
void unused(const Ts&...)
{
}
+
+ template<class T>
+ T copy(const T& t)
+ {
+ return t;
+ }
}
diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h
index 457205384..223a1fb86 100644
--- a/toolsrc/include/vcpkg/binaryparagraph.h
+++ b/toolsrc/include/vcpkg/binaryparagraph.h
@@ -13,8 +13,14 @@ namespace vcpkg
{
BinaryParagraph();
explicit BinaryParagraph(Parse::RawParagraph fields);
- BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag);
- BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet);
+ BinaryParagraph(const SourceParagraph& spgh,
+ const Triplet& triplet,
+ const std::string& abi_tag,
+ const std::vector<FeatureSpec>& deps);
+ BinaryParagraph(const SourceParagraph& spgh,
+ const FeatureParagraph& fpgh,
+ const Triplet& triplet,
+ const std::vector<FeatureSpec>& deps);
std::string displayname() const;
@@ -30,6 +36,7 @@ namespace vcpkg
std::vector<std::string> default_features;
std::vector<std::string> depends;
std::string abi;
+ Type type;
};
struct BinaryControlFile
diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h
index be5424296..57663ebe5 100644
--- a/toolsrc/include/vcpkg/build.h
+++ b/toolsrc/include/vcpkg/build.h
@@ -1,5 +1,6 @@
#pragma once
+#include <vcpkg/cmakevars.h>
#include <vcpkg/packagespec.h>
#include <vcpkg/statusparagraphs.h>
#include <vcpkg/triplet.h>
@@ -21,6 +22,7 @@ namespace vcpkg::Build
{
void perform_and_exit_ex(const FullPackageSpec& full_spec,
const SourceControlFileLocation& scfl,
+ const PortFileProvider::PathsPortFileProvider& provider,
const ParsedArguments& options,
const VcpkgPaths& paths);
@@ -88,6 +90,12 @@ namespace vcpkg::Build
YES
};
+ enum class PurgeDecompressFailure
+ {
+ NO = 0,
+ YES
+ };
+
struct BuildPackageOptions
{
UseHeadVersion use_head_version;
@@ -99,6 +107,7 @@ namespace vcpkg::Build
DownloadTool download_tool;
BinaryCaching binary_caching;
FailOnTombstone fail_on_tombstone;
+ PurgeDecompressFailure purge_decompress_failure;
};
enum class BuildResult
@@ -130,12 +139,9 @@ namespace vcpkg::Build
/// </summary>
struct PreBuildInfo
{
- /// <summary>
- /// Runs the triplet file in a "capture" mode to create a PreBuildInfo
- /// </summary>
- static PreBuildInfo from_triplet_file(const VcpkgPaths& paths,
- const Triplet& triplet,
- Optional<const SourceControlFileLocation&> port = nullopt);
+ PreBuildInfo(const VcpkgPaths& paths,
+ const Triplet& triplet,
+ const std::unordered_map<std::string, std::string>& cmakevars);
std::string triplet_abi_tag;
std::string target_architecture;
@@ -193,12 +199,18 @@ namespace vcpkg::Build
BuildPackageConfig(const SourceControlFileLocation& scfl,
const Triplet& triplet,
const BuildPackageOptions& build_package_options,
- const std::set<std::string>& feature_list)
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::unordered_map<std::string, std::vector<FeatureSpec>>& feature_dependencies,
+ const std::vector<PackageSpec>& package_dependencies,
+ const std::vector<std::string>& feature_list)
: scfl(scfl)
, scf(*scfl.source_control_file)
, triplet(triplet)
, port_dir(scfl.source_location)
, build_package_options(build_package_options)
+ , var_provider(var_provider)
+ , feature_dependencies(feature_dependencies)
+ , package_dependencies(package_dependencies)
, feature_list(feature_list)
{
}
@@ -206,9 +218,13 @@ namespace vcpkg::Build
const SourceControlFileLocation& scfl;
const SourceControlFile& scf;
const Triplet& triplet;
- fs::path port_dir;
+ const fs::path& port_dir;
const BuildPackageOptions& build_package_options;
- const std::set<std::string>& feature_list;
+ const CMakeVars::CMakeVarProvider& var_provider;
+
+ const std::unordered_map<std::string, std::vector<FeatureSpec>>& feature_dependencies;
+ const std::vector<PackageSpec>& package_dependencies;
+ const std::vector<std::string>& feature_list;
};
ExtendedBuildResult build_package(const VcpkgPaths& paths,
@@ -223,6 +239,7 @@ namespace vcpkg::Build
ONLY_RELEASE_CRT,
EMPTY_INCLUDE_FOLDER,
ALLOW_OBSOLETE_MSVCRT,
+ ALLOW_RESTRICTED_HEADERS,
// Must be last
COUNT,
};
@@ -234,6 +251,7 @@ namespace vcpkg::Build
BuildPolicy::ONLY_RELEASE_CRT,
BuildPolicy::EMPTY_INCLUDE_FOLDER,
BuildPolicy::ALLOW_OBSOLETE_MSVCRT,
+ BuildPolicy::ALLOW_RESTRICTED_HEADERS,
};
const std::string& to_string(BuildPolicy policy);
diff --git a/toolsrc/include/vcpkg/cmakevars.h b/toolsrc/include/vcpkg/cmakevars.h
new file mode 100644
index 000000000..c634866d0
--- /dev/null
+++ b/toolsrc/include/vcpkg/cmakevars.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <vcpkg/base/hash.h>
+#include <vcpkg/base/system.process.h>
+
+#include <vcpkg/portfileprovider.h>
+#include <vcpkg/vcpkgpaths.h>
+
+namespace vcpkg::CMakeVars
+{
+ struct CMakeVarProvider
+ {
+ virtual Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
+ const Triplet& triplet) const = 0;
+
+ virtual Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
+ const PackageSpec& spec) const = 0;
+
+ virtual Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
+ const PackageSpec& spec) const = 0;
+
+ virtual void load_generic_triplet_vars(const Triplet& triplet) const = 0;
+
+ virtual void load_dep_info_vars(Span<const PackageSpec> specs) const = 0;
+
+ virtual void load_tag_vars(Span<const FullPackageSpec> specs,
+ const PortFileProvider::PortFileProvider& port_provider) const = 0;
+ };
+
+ struct TripletCMakeVarProvider : Util::ResourceBase, CMakeVarProvider
+ {
+ private:
+ fs::path create_tag_extraction_file(
+ const Span<const std::pair<const FullPackageSpec*, std::string>>& spec_abi_settings) const;
+
+ fs::path create_dep_info_extraction_file(const Span<const PackageSpec> specs) const;
+
+ void launch_and_split(const fs::path& script_path,
+ std::vector<std::vector<std::pair<std::string, std::string>>>& vars) const;
+
+ public:
+ explicit TripletCMakeVarProvider(const vcpkg::VcpkgPaths& paths) : paths(paths) {}
+
+ void load_generic_triplet_vars(const Triplet& triplet) const override;
+
+ void load_dep_info_vars(Span<const PackageSpec> specs) const override;
+
+ void load_tag_vars(Span<const FullPackageSpec> specs,
+ const PortFileProvider::PortFileProvider& port_provider) const override;
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
+ const Triplet& triplet) const override;
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
+ const PackageSpec& spec) const override;
+
+ Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
+ const PackageSpec& spec) const override;
+
+ private:
+ const VcpkgPaths& paths;
+ const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE);
+ const fs::path get_tags_path = paths.scripts / "vcpkg_get_tags.cmake";
+ const fs::path get_dep_info_path = paths.scripts / "vcpkg_get_dep_info.cmake";
+ mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_resolution_vars;
+ mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
+ mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
+ };
+}
diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h
index e9018b1b8..eb9d42b6d 100644
--- a/toolsrc/include/vcpkg/dependencies.h
+++ b/toolsrc/include/vcpkg/dependencies.h
@@ -3,7 +3,9 @@
#include <vcpkg/base/optional.h>
#include <vcpkg/base/util.h>
#include <vcpkg/build.h>
+#include <vcpkg/cmakevars.h>
#include <vcpkg/packagespec.h>
+#include <vcpkg/portfileprovider.h>
#include <vcpkg/statusparagraphs.h>
#include <vcpkg/vcpkgpaths.h>
@@ -43,15 +45,12 @@ namespace vcpkg::Dependencies
InstallPlanAction() noexcept;
- InstallPlanAction(InstalledPackageView&& spghs,
- const std::set<std::string>& features,
- const RequestType& request_type);
+ InstallPlanAction(InstalledPackageView&& spghs, const RequestType& request_type);
InstallPlanAction(const PackageSpec& spec,
const SourceControlFileLocation& scfl,
- const std::set<std::string>& features,
const RequestType& request_type,
- std::vector<PackageSpec>&& dependencies);
+ std::unordered_map<std::string, std::vector<FeatureSpec>>&& dependencies);
std::string displayname() const;
@@ -63,9 +62,11 @@ namespace vcpkg::Dependencies
InstallPlanType plan_type;
RequestType request_type;
Build::BuildPackageOptions build_options;
- std::set<std::string> feature_list;
- std::vector<PackageSpec> computed_dependencies;
+ std::unordered_map<std::string, std::vector<FeatureSpec>> feature_dependencies;
+ std::vector<PackageSpec> package_dependencies;
+
+ std::vector<std::string> feature_list;
};
enum class RemovePlanType
@@ -87,15 +88,14 @@ namespace vcpkg::Dependencies
RequestType request_type;
};
- struct AnyAction
+ struct ActionPlan
{
- AnyAction(InstallPlanAction&& iplan) : install_action(std::move(iplan)) {}
- AnyAction(RemovePlanAction&& rplan) : remove_action(std::move(rplan)) {}
-
- Optional<InstallPlanAction> install_action;
- Optional<RemovePlanAction> remove_action;
+ bool empty() const { return remove_actions.empty() && already_installed.empty() && install_actions.empty(); }
+ size_t size() const { return remove_actions.size() + already_installed.size() + install_actions.size(); }
- const PackageSpec& spec() const;
+ std::vector<RemovePlanAction> remove_actions;
+ std::vector<InstallPlanAction> already_installed;
+ std::vector<InstallPlanAction> install_actions;
};
enum class ExportPlanType
@@ -127,80 +127,36 @@ namespace vcpkg::Dependencies
Optional<InstalledPackageView> m_installed_package;
};
- struct PortFileProvider
- {
- virtual Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0;
- virtual std::vector<const SourceControlFileLocation*> load_all_control_files() const = 0;
- };
-
- struct MapPortFileProvider : Util::ResourceBase, PortFileProvider
- {
- explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map);
- Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
- std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
-
- private:
- const std::unordered_map<std::string, SourceControlFileLocation>& ports;
- };
-
- struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider
- {
- explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
- const std::vector<std::string>* ports_dirs_paths);
- Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
- std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
-
- private:
- Files::Filesystem& filesystem;
- std::vector<fs::path> ports_dirs;
- mutable std::unordered_map<std::string, SourceControlFileLocation> cache;
- };
-
struct ClusterGraph;
- struct GraphPlan;
struct CreateInstallPlanOptions
{
Graphs::Randomizer* randomizer = nullptr;
};
- struct PackageGraph
- {
- PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db);
- ~PackageGraph();
-
- void install(const FeatureSpec& spec,
- const std::unordered_set<std::string>& prevent_default_features = {}) const;
- void upgrade(const PackageSpec& spec) const;
-
- std::vector<AnyAction> serialize(const CreateInstallPlanOptions& options = {}) const;
-
- private:
- std::unique_ptr<GraphPlan> m_graph_plan;
- std::unique_ptr<ClusterGraph> m_graph;
- };
-
std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs,
const StatusParagraphs& status_db);
std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs,
const StatusParagraphs& status_db);
- std::vector<AnyAction> create_feature_install_plan(
- const std::unordered_map<std::string, SourceControlFileLocation>& map,
- const std::vector<FeatureSpec>& specs,
- const StatusParagraphs& status_db);
-
/// <summary>Figure out which actions are required to install features specifications in `specs`.</summary>
/// <param name="provider">Contains the ports of the current environment.</param>
/// <param name="specs">Feature specifications to resolve dependencies for.</param>
/// <param name="status_db">Status of installed packages in the current environment.</param>
- std::vector<AnyAction> create_feature_install_plan(const PortFileProvider& provider,
- const std::vector<FeatureSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options = {});
-
- void print_plan(const std::vector<AnyAction>& action_plan,
+ ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector<FullPackageSpec>& specs,
+ const StatusParagraphs& status_db,
+ const CreateInstallPlanOptions& options = {});
+
+ ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector<PackageSpec>& specs,
+ const StatusParagraphs& status_db,
+ const CreateInstallPlanOptions& options = {});
+
+ void print_plan(const ActionPlan& action_plan,
const bool is_recursive = true,
const fs::path& default_ports_dir = "");
}
diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h
index 2e92764dc..e020c8653 100644
--- a/toolsrc/include/vcpkg/install.h
+++ b/toolsrc/include/vcpkg/install.h
@@ -20,7 +20,7 @@ namespace vcpkg::Install
struct SpecSummary
{
- SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action);
+ SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action);
const BinaryParagraph* get_binary_paragraph() const;
@@ -28,7 +28,7 @@ namespace vcpkg::Install
Build::ExtendedBuildResult build_result;
vcpkg::Chrono::ElapsedTime timing;
- const Dependencies::AnyAction* action;
+ const Dependencies::InstallPlanAction* action;
};
struct InstallSummary
@@ -58,8 +58,9 @@ namespace vcpkg::Install
};
Build::ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths,
- const Dependencies::InstallPlanAction& action,
- StatusParagraphs& status_db);
+ Dependencies::InstallPlanAction& action,
+ StatusParagraphs& status_db,
+ const CMakeVars::CMakeVarProvider& var_provider);
enum class InstallResult
{
@@ -74,10 +75,11 @@ namespace vcpkg::Install
const BinaryControlFile& binary_paragraph,
StatusParagraphs* status_db);
- InstallSummary perform(const std::vector<Dependencies::AnyAction>& action_plan,
+ InstallSummary perform(Dependencies::ActionPlan& action_plan,
const KeepGoing keep_going,
const VcpkgPaths& paths,
- StatusParagraphs& status_db);
+ StatusParagraphs& status_db,
+ const CMakeVars::CMakeVarProvider& var_provider);
extern const CommandStructure COMMAND_STRUCTURE;
diff --git a/toolsrc/include/vcpkg/logicexpression.h b/toolsrc/include/vcpkg/logicexpression.h
index 8795971b9..3a3d0debe 100644
--- a/toolsrc/include/vcpkg/logicexpression.h
+++ b/toolsrc/include/vcpkg/logicexpression.h
@@ -1,10 +1,24 @@
#pragma once
#include <string>
+#include <unordered_map>
+#include <vcpkg/base/expected.h>
namespace vcpkg
{
+ struct ExpressionContext
+ {
+ // map of cmake variables and their values.
+ const std::unordered_map<std::string, std::string>& 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)
- bool evaluate_expression(const std::string& expression, const std::string& evaluation_context);
+ ExpectedT<bool, std::string> evaluate_expression(const std::string& expression, const ExpressionContext& context);
} \ No newline at end of file
diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h
index c87c6a2c6..628352cdb 100644
--- a/toolsrc/include/vcpkg/packagespec.h
+++ b/toolsrc/include/vcpkg/packagespec.h
@@ -23,6 +23,9 @@ namespace vcpkg
///
struct PackageSpec
{
+ PackageSpec() noexcept = default;
+ PackageSpec(std::string name, Triplet triplet) : m_name(std::move(name)), m_triplet(triplet) {}
+
static ExpectedT<PackageSpec, PackageSpecParseResult> from_name_and_triplet(const std::string& name,
const Triplet& triplet);
@@ -103,7 +106,14 @@ namespace vcpkg
PackageSpec package_spec;
std::vector<std::string> features;
- static std::vector<FeatureSpec> to_feature_specs(const std::vector<FullPackageSpec>& specs);
+ FullPackageSpec() noexcept = default;
+ explicit FullPackageSpec(PackageSpec spec, std::vector<std::string> features = {})
+ : package_spec(std::move(spec)), features(std::move(features))
+ {
+ }
+
+ std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string>& default_features,
+ const std::vector<std::string>& all_features) const;
static ExpectedT<FullPackageSpec, PackageSpecParseResult> from_string(const std::string& spec_as_string,
const Triplet& default_triplet);
@@ -145,4 +155,21 @@ namespace std
{
bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; }
};
+
+ template<>
+ struct hash<vcpkg::FeatureSpec>
+ {
+ size_t operator()(const vcpkg::FeatureSpec& value) const
+ {
+ size_t hash = std::hash<vcpkg::PackageSpec>()(value.spec());
+ hash = hash * 31 + std::hash<std::string>()(value.feature());
+ return hash;
+ }
+ };
+
+ template<>
+ struct equal_to<vcpkg::FeatureSpec>
+ {
+ bool operator()(const vcpkg::FeatureSpec& left, const vcpkg::FeatureSpec& right) const { return left == right; }
+ };
}
diff --git a/toolsrc/include/vcpkg/portfileprovider.h b/toolsrc/include/vcpkg/portfileprovider.h
new file mode 100644
index 000000000..79f69d9ae
--- /dev/null
+++ b/toolsrc/include/vcpkg/portfileprovider.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <vcpkg/base/optional.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/sourceparagraph.h>
+#include <vcpkg/vcpkgpaths.h>
+
+namespace vcpkg::PortFileProvider
+{
+ struct PortFileProvider
+ {
+ virtual Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const = 0;
+ virtual std::vector<const SourceControlFileLocation*> load_all_control_files() const = 0;
+ };
+
+ struct MapPortFileProvider : Util::ResourceBase, PortFileProvider
+ {
+ explicit MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map);
+ Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
+ std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
+
+ private:
+ const std::unordered_map<std::string, SourceControlFileLocation>& ports;
+ };
+
+ struct PathsPortFileProvider : Util::ResourceBase, PortFileProvider
+ {
+ explicit PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
+ const std::vector<std::string>* ports_dirs_paths);
+ Optional<const SourceControlFileLocation&> get_control_file(const std::string& src_name) const override;
+ std::vector<const SourceControlFileLocation*> load_all_control_files() const override;
+
+ private:
+ Files::Filesystem& filesystem;
+ std::vector<fs::path> ports_dirs;
+ mutable std::unordered_map<std::string, SourceControlFileLocation> cache;
+ };
+}
diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h
index 95347770a..0574afe74 100644
--- a/toolsrc/include/vcpkg/sourceparagraph.h
+++ b/toolsrc/include/vcpkg/sourceparagraph.h
@@ -7,6 +7,8 @@
#include <vcpkg/base/span.h>
#include <vcpkg/base/system.h>
+#include <vcpkg/base/system.print.h>
+
#include <string>
#include <vector>
@@ -21,15 +23,28 @@ namespace vcpkg
static Dependency parse_dependency(std::string name, std::string qualifier);
};
- std::vector<std::string> filter_dependencies(const std::vector<Dependency>& deps, const Triplet& t);
- std::vector<FeatureSpec> filter_dependencies_to_specs(const std::vector<Dependency>& deps, const Triplet& t);
- std::vector<Features> filter_dependencies_to_features(const std::vector<vcpkg::Dependency>& deps, const Triplet& t);
+ std::vector<FullPackageSpec> filter_dependencies(const std::vector<Dependency>& deps,
+ const Triplet& t,
+ const std::unordered_map<std::string, std::string>& cmake_vars);
// zlib[uwp] becomes Dependency{"zlib", "uwp"}
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends);
std::string to_string(const Dependency& dep);
+ struct Type
+ {
+ enum
+ {
+ UNKNOWN,
+ PORT,
+ ALIAS,
+ } type;
+
+ static std::string to_string(const Type&);
+ static Type from_string(const std::string&);
+ };
+
/// <summary>
/// Port metadata of additional feature in a package (part of CONTROL file)
/// </summary>
@@ -50,9 +65,10 @@ namespace vcpkg
std::string description;
std::string maintainer;
std::string homepage;
- std::vector<std::string> supports;
std::vector<Dependency> depends;
std::vector<std::string> default_features;
+ Type type;
+ std::string supports_expression;
};
/// <summary>
@@ -60,21 +76,48 @@ namespace vcpkg
/// </summary>
struct SourceControlFile
{
+ SourceControlFile() = default;
+ SourceControlFile(const SourceControlFile& scf)
+ : core_paragraph(std::make_unique<SourceParagraph>(*scf.core_paragraph))
+ {
+ for (const auto& feat_ptr : scf.feature_paragraphs)
+ {
+ feature_paragraphs.emplace_back(std::make_unique<FeatureParagraph>(*feat_ptr));
+ }
+ }
+
static Parse::ParseExpected<SourceControlFile> parse_control_file(
- std::vector<Parse::RawParagraph>&& control_paragraphs);
+ const fs::path& path_to_control, std::vector<Parse::RawParagraph>&& control_paragraphs);
std::unique_ptr<SourceParagraph> core_paragraph;
std::vector<std::unique_ptr<FeatureParagraph>> feature_paragraphs;
Optional<const FeatureParagraph&> find_feature(const std::string& featurename) const;
+ Optional<const std::vector<Dependency>&> find_dependencies_for_feature(const std::string& featurename) const;
};
/// <summary>
- /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was loaded
- /// from.
+ /// Full metadata of a package: core and other features. As well as the location the SourceControlFile was
+ /// loaded from.
/// </summary>
struct SourceControlFileLocation
{
+ SourceControlFileLocation(const SourceControlFileLocation& scfl)
+ : source_control_file(std::make_unique<SourceControlFile>(*scfl.source_control_file))
+ , source_location(scfl.source_location)
+ {
+ }
+
+ SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, fs::path&& source)
+ : source_control_file(std::move(scf)), source_location(std::move(source))
+ {
+ }
+
+ SourceControlFileLocation(std::unique_ptr<SourceControlFile>&& scf, const fs::path& source)
+ : source_control_file(std::move(scf)), source_location(source)
+ {
+ }
+
std::unique_ptr<SourceControlFile> source_control_file;
fs::path source_location;
};
@@ -84,35 +127,4 @@ namespace vcpkg
{
return print_error_message({&error_info_list, 1});
}
-
- struct Supports
- {
- static ExpectedT<Supports, std::vector<std::string>> parse(const std::vector<std::string>& strs);
-
- using Architecture = System::CPUArchitecture;
-
- enum class Platform
- {
- WINDOWS,
- UWP,
- };
- enum class Linkage
- {
- DYNAMIC,
- STATIC,
- };
- enum class ToolsetVersion
- {
- V140,
- V141,
- };
-
- bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools);
-
- private:
- std::vector<Architecture> architectures;
- std::vector<Platform> platforms;
- std::vector<Linkage> crt_linkages;
- std::vector<ToolsetVersion> toolsets;
- };
}
diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h
index 6e832fe2f..ec850607d 100644
--- a/toolsrc/include/vcpkg/statusparagraph.h
+++ b/toolsrc/include/vcpkg/statusparagraph.h
@@ -56,6 +56,7 @@ namespace vcpkg
const PackageSpec& spec() const { return core->package.spec; }
std::vector<PackageSpec> dependencies() const;
+ std::unordered_map<std::string, std::vector<FeatureSpec>> feature_dependencies() const;
const StatusParagraph* core;
std::vector<const StatusParagraph*> features;
diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h
index b85f7b2b3..6091da778 100644
--- a/toolsrc/include/vcpkg/update.h
+++ b/toolsrc/include/vcpkg/update.h
@@ -17,7 +17,7 @@ namespace vcpkg::Update
VersionDiff version_diff;
};
- std::vector<OutdatedPackage> find_outdated_packages(const Dependencies::PortFileProvider& provider,
+ std::vector<OutdatedPackage> find_outdated_packages(const PortFileProvider::PortFileProvider& provider,
const StatusParagraphs& status_db);
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths);
diff --git a/toolsrc/src/vcpkg-test/dependencies.cpp b/toolsrc/src/vcpkg-test/dependencies.cpp
index 2344bb990..63e7cfee7 100644
--- a/toolsrc/src/vcpkg-test/dependencies.cpp
+++ b/toolsrc/src/vcpkg-test/dependencies.cpp
@@ -1,5 +1,7 @@
#include <catch2/catch.hpp>
-
+#include <vcpkg-test/mockcmakevarprovider.h>
+#include <vcpkg-test/util.h>
+#include <vcpkg/dependencies.h>
#include <vcpkg/sourceparagraph.h>
using namespace vcpkg;
@@ -7,22 +9,69 @@ using Parse::parse_comma_list;
TEST_CASE ("parse depends", "[dependencies]")
{
- auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)"));
+ auto v = expand_qualified_dependencies(parse_comma_list("liba (windows)"));
REQUIRE(v.size() == 1);
- REQUIRE(v.at(0).depend.name == "libA");
+ REQUIRE(v.at(0).depend.name == "liba");
REQUIRE(v.at(0).qualifier == "windows");
}
TEST_CASE ("filter depends", "[dependencies]")
{
- auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)"));
- auto v = filter_dependencies(deps, Triplet::X64_WINDOWS);
+ const std::unordered_map<std::string, std::string> x64_win_cmake_vars{{"VCPKG_TARGET_ARCHITECTURE", "x64"},
+ {"VCPKG_CMAKE_SYSTEM_NAME", ""}};
+
+ const std::unordered_map<std::string, std::string> arm_uwp_cmake_vars{{"VCPKG_TARGET_ARCHITECTURE", "arm"},
+ {"VCPKG_CMAKE_SYSTEM_NAME", "WindowsStore"}};
+
+ auto deps = expand_qualified_dependencies(parse_comma_list("liba (windows), libb, libc (uwp)"));
+ auto v = filter_dependencies(deps, Triplet::X64_WINDOWS, x64_win_cmake_vars);
REQUIRE(v.size() == 2);
- REQUIRE(v.at(0) == "libA");
- REQUIRE(v.at(1) == "libB");
+ REQUIRE(v.at(0).package_spec.name() == "liba");
+ REQUIRE(v.at(1).package_spec.name() == "libb");
- auto v2 = filter_dependencies(deps, Triplet::ARM_UWP);
+ auto v2 = filter_dependencies(deps, Triplet::ARM_UWP, arm_uwp_cmake_vars);
+ REQUIRE(v.size() == 2);
+ REQUIRE(v2.at(0).package_spec.name() == "libb");
+ REQUIRE(v2.at(1).package_spec.name() == "libc");
+}
+
+TEST_CASE ("parse feature depends", "[dependencies]")
+{
+ auto u = parse_comma_list("libwebp[anim, gif2webp, img2webp, info, mux, nearlossless, "
+ "simd, cwebp, dwebp], libwebp[vwebp_sdl, extras] (!osx)");
+ REQUIRE(u.at(1) == "libwebp[vwebp_sdl, extras] (!osx)");
+ auto v = expand_qualified_dependencies(u);
REQUIRE(v.size() == 2);
- REQUIRE(v2.at(0) == "libB");
- REQUIRE(v2.at(1) == "libC");
+ auto&& a0 = v.at(0);
+ REQUIRE(a0.depend.name == "libwebp");
+ REQUIRE(a0.depend.features.size() == 9);
+ REQUIRE(a0.qualifier.empty());
+
+ auto&& a1 = v.at(1);
+ REQUIRE(a1.depend.name == "libwebp");
+ REQUIRE(a1.depend.features.size() == 2);
+ REQUIRE(a1.qualifier == "!osx");
+}
+
+TEST_CASE ("qualified dependency", "[dependencies]")
+{
+ using namespace Test;
+ PackageSpecMap spec_map;
+ auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1] (linux)"), {}};
+ auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {}};
+
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto plan = vcpkg::Dependencies::create_feature_install_plan(map_port, var_provider, {spec_a}, {});
+ REQUIRE(plan.install_actions.size() == 2);
+ REQUIRE(plan.install_actions.at(0).feature_list == std::vector<std::string>{"core"});
+
+ FullPackageSpec linspec_a{PackageSpec::from_name_and_triplet("a", Triplet::from_canonical_name("x64-linux"))
+ .value_or_exit(VCPKG_LINE_INFO),
+ {}};
+ var_provider.dep_info_vars[linspec_a.package_spec].emplace("VCPKG_CMAKE_SYSTEM_NAME", "Linux");
+ auto plan2 = vcpkg::Dependencies::create_feature_install_plan(map_port, var_provider, {linspec_a}, {});
+ REQUIRE(plan2.install_actions.size() == 2);
+ REQUIRE(plan2.install_actions.at(0).feature_list == std::vector<std::string>{"b1", "core"});
}
diff --git a/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp b/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp
new file mode 100644
index 000000000..eda1a7a64
--- /dev/null
+++ b/toolsrc/src/vcpkg-test/mockcmakevarsprovider.cpp
@@ -0,0 +1,28 @@
+#include <vcpkg-test/mockcmakevarprovider.h>
+
+namespace vcpkg::Test
+{
+ Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_generic_triplet_vars(
+ const Triplet& triplet) const
+ {
+ auto it = generic_triplet_vars.find(triplet);
+ if (it == generic_triplet_vars.end()) return nullopt;
+ return it->second;
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_dep_info_vars(
+ const PackageSpec& spec) const
+ {
+ auto it = dep_info_vars.find(spec);
+ if (it == dep_info_vars.end()) return nullopt;
+ return it->second;
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_tag_vars(
+ const PackageSpec& spec) const
+ {
+ auto it = tag_vars.find(spec);
+ if (it == tag_vars.end()) return nullopt;
+ return it->second;
+ }
+} \ No newline at end of file
diff --git a/toolsrc/src/vcpkg-test/paragraph.cpp b/toolsrc/src/vcpkg-test/paragraph.cpp
index 85c37851d..2ee4efe2f 100644
--- a/toolsrc/src/vcpkg-test/paragraph.cpp
+++ b/toolsrc/src/vcpkg-test/paragraph.cpp
@@ -10,10 +10,11 @@ namespace Strings = vcpkg::Strings;
TEST_CASE ("SourceParagraph construct minimum", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "zlib"},
+ {"Version", "1.2.8"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -28,15 +29,15 @@ TEST_CASE ("SourceParagraph construct minimum", "[paragraph]")
TEST_CASE ("SourceParagraph construct maximum", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "s"},
- {"Version", "v"},
- {"Maintainer", "m"},
- {"Description", "d"},
- {"Build-Depends", "bd"},
- {"Default-Features", "df"},
- {"Supports", "x64"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "s"},
+ {"Version", "v"},
+ {"Maintainer", "m"},
+ {"Description", "d"},
+ {"Build-Depends", "bd"},
+ {"Default-Features", "df"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -48,18 +49,17 @@ TEST_CASE ("SourceParagraph construct maximum", "[paragraph]")
REQUIRE(pgh.core_paragraph->depends[0].name() == "bd");
REQUIRE(pgh.core_paragraph->default_features.size() == 1);
REQUIRE(pgh.core_paragraph->default_features[0] == "df");
- REQUIRE(pgh.core_paragraph->supports.size() == 1);
- REQUIRE(pgh.core_paragraph->supports[0] == "x64");
}
TEST_CASE ("SourceParagraph two depends", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "z, openssl"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "zlib"},
+ {"Version", "1.2.8"},
+ {"Build-Depends", "z, openssl"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -71,11 +71,12 @@ TEST_CASE ("SourceParagraph two depends", "[paragraph]")
TEST_CASE ("SourceParagraph three depends", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "z, openssl, xyz"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "zlib"},
+ {"Version", "1.2.8"},
+ {"Build-Depends", "z, openssl, xyz"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -85,31 +86,15 @@ TEST_CASE ("SourceParagraph three depends", "[paragraph]")
REQUIRE(pgh.core_paragraph->depends[2].name() == "xyz");
}
-TEST_CASE ("SourceParagraph three supports", "[paragraph]")
-{
- auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Supports", "x64, windows, uwp"},
- }});
- REQUIRE(m_pgh.has_value());
- auto& pgh = **m_pgh.get();
-
- REQUIRE(pgh.core_paragraph->supports.size() == 3);
- REQUIRE(pgh.core_paragraph->supports[0] == "x64");
- REQUIRE(pgh.core_paragraph->supports[1] == "windows");
- REQUIRE(pgh.core_paragraph->supports[2] == "uwp");
-}
-
TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "zlib"},
- {"Version", "1.2.8"},
- {"Build-Depends", "libA (windows), libB (uwp)"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "zlib"},
+ {"Version", "1.2.8"},
+ {"Build-Depends", "libA (windows), libB (uwp)"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -127,11 +112,12 @@ TEST_CASE ("SourceParagraph construct qualified depends", "[paragraph]")
TEST_CASE ("SourceParagraph default features", "[paragraph]")
{
auto m_pgh =
- vcpkg::SourceControlFile::parse_control_file(std::vector<std::unordered_map<std::string, std::string>>{{
- {"Source", "a"},
- {"Version", "1.0"},
- {"Default-Features", "a1"},
- }});
+ vcpkg::SourceControlFile::parse_control_file("",
+ std::vector<std::unordered_map<std::string, std::string>>{{
+ {"Source", "a"},
+ {"Version", "1.0"},
+ {"Default-Features", "a1"},
+ }});
REQUIRE(m_pgh.has_value());
auto& pgh = **m_pgh.get();
@@ -380,11 +366,12 @@ TEST_CASE ("BinaryParagraph serialize min", "[paragraph]")
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO);
REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 4);
+ REQUIRE(pghs[0].size() == 5);
REQUIRE(pghs[0]["Package"] == "zlib");
REQUIRE(pghs[0]["Version"] == "1.2.8");
REQUIRE(pghs[0]["Architecture"] == "x86-windows");
REQUIRE(pghs[0]["Multi-Arch"] == "same");
+ REQUIRE(pghs[0]["Type"] == "Port");
}
TEST_CASE ("BinaryParagraph serialize max", "[paragraph]")
@@ -402,13 +389,14 @@ TEST_CASE ("BinaryParagraph serialize max", "[paragraph]")
auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO);
REQUIRE(pghs.size() == 1);
- REQUIRE(pghs[0].size() == 7);
+ REQUIRE(pghs[0].size() == 8);
REQUIRE(pghs[0]["Package"] == "zlib");
REQUIRE(pghs[0]["Version"] == "1.2.8");
REQUIRE(pghs[0]["Architecture"] == "x86-windows");
REQUIRE(pghs[0]["Multi-Arch"] == "same");
REQUIRE(pghs[0]["Description"] == "first line\n second line");
REQUIRE(pghs[0]["Depends"] == "dep");
+ REQUIRE(pghs[0]["Type"] == "Port");
}
TEST_CASE ("BinaryParagraph serialize multiple deps", "[paragraph]")
diff --git a/toolsrc/src/vcpkg-test/plan.cpp b/toolsrc/src/vcpkg-test/plan.cpp
index e354b7551..594c9783b 100644
--- a/toolsrc/src/vcpkg-test/plan.cpp
+++ b/toolsrc/src/vcpkg-test/plan.cpp
@@ -1,7 +1,10 @@
#include <catch2/catch.hpp>
+#include <vcpkg-test/mockcmakevarprovider.h>
#include <vcpkg-test/util.h>
+#include <vcpkg/base/graphs.h>
#include <vcpkg/dependencies.h>
+#include <vcpkg/portfileprovider.h>
#include <vcpkg/sourceparagraph.h>
#include <vcpkg/triplet.h>
@@ -11,54 +14,28 @@
using namespace vcpkg;
+using Test::make_control_file;
using Test::make_status_feature_pgh;
using Test::make_status_pgh;
+using Test::MockCMakeVarProvider;
+using Test::PackageSpecMap;
using Test::unsafe_pspec;
-static std::unique_ptr<SourceControlFile> make_control_file(
- const char* name,
- const char* depends,
- const std::vector<std::pair<const char*, const char*>>& features = {},
- const std::vector<const char*>& default_features = {})
-{
- using Pgh = std::unordered_map<std::string, std::string>;
- std::vector<Pgh> scf_pghs;
- scf_pghs.push_back(Pgh{{"Source", name},
- {"Version", "0"},
- {"Build-Depends", depends},
- {"Default-Features", Strings::join(", ", default_features)}});
- for (auto&& feature : features)
- {
- scf_pghs.push_back(Pgh{
- {"Feature", feature.first},
- {"Description", "feature"},
- {"Build-Depends", feature.second},
- });
- }
- auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs));
- REQUIRE(m_pgh.has_value());
- return std::move(*m_pgh.get());
-}
-
/// <summary>
/// Assert that the given action an install of given features from given package.
/// </summary>
-static void features_check(Dependencies::AnyAction& install_action,
+static void features_check(Dependencies::InstallPlanAction& plan,
std::string pkg_name,
- std::vector<std::string> vec,
+ std::vector<std::string> expected_features,
const Triplet& triplet = Triplet::X86_WINDOWS)
{
- REQUIRE(install_action.install_action.has_value());
- const auto& plan = install_action.install_action.value_or_exit(VCPKG_LINE_INFO);
const auto& feature_list = plan.feature_list;
REQUIRE(plan.spec.triplet().to_string() == triplet.to_string());
+ REQUIRE(pkg_name == plan.spec.name());
+ REQUIRE(feature_list.size() == expected_features.size());
- auto& scfl = *plan.source_control_file_location.get();
- REQUIRE(pkg_name == scfl.source_control_file->core_paragraph->name);
- REQUIRE(feature_list.size() == vec.size());
-
- for (auto&& feature_name : vec)
+ for (auto&& feature_name : expected_features)
{
// TODO: see if this can be simplified
if (feature_name == "core" || feature_name == "")
@@ -74,42 +51,14 @@ static void features_check(Dependencies::AnyAction& install_action,
/// <summary>
/// Assert that the given action is a remove of given package.
/// </summary>
-static void remove_plan_check(Dependencies::AnyAction& remove_action,
+static void remove_plan_check(Dependencies::RemovePlanAction& plan,
std::string pkg_name,
const Triplet& triplet = Triplet::X86_WINDOWS)
{
- const auto& plan = remove_action.remove_action.value_or_exit(VCPKG_LINE_INFO);
REQUIRE(plan.spec.triplet().to_string() == triplet.to_string());
REQUIRE(pkg_name == plan.spec.name());
}
-/// <summary>
-/// Map of source control files by their package name.
-/// </summary>
-struct PackageSpecMap
-{
- std::unordered_map<std::string, SourceControlFileLocation> map;
- Triplet triplet;
- PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept { triplet = t; }
-
- PackageSpec emplace(const char* name,
- const char* depends = "",
- const std::vector<std::pair<const char*, const char*>>& features = {},
- const std::vector<const char*>& default_features = {})
- {
- auto scfl = SourceControlFileLocation{make_control_file(name, depends, features, default_features), ""};
- return emplace(std::move(scfl));
- }
-
- PackageSpec emplace(vcpkg::SourceControlFileLocation&& scfl)
- {
- auto spec = PackageSpec::from_name_and_triplet(scfl.source_control_file->core_paragraph->name, triplet);
- REQUIRE(spec.has_value());
- map.emplace(scfl.source_control_file->core_paragraph->name, std::move(scfl));
- return PackageSpec{*spec.get()};
- }
-};
-
TEST_CASE ("basic install scheme", "[plan]")
{
std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
@@ -119,14 +68,16 @@ TEST_CASE ("basic install scheme", "[plan]")
auto spec_b = spec_map.emplace("b", "c");
auto spec_c = spec_map.emplace("c");
- Dependencies::MapPortFileProvider map_port(spec_map.map);
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
- map_port, {FeatureSpec{spec_a, ""}}, StatusParagraphs(std::move(status_paragraphs)));
+ map_port, var_provider, {FullPackageSpec{spec_a, {}}}, StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- REQUIRE(install_plan.at(0).spec().name() == "c");
- REQUIRE(install_plan.at(1).spec().name() == "b");
- REQUIRE(install_plan.at(2).spec().name() == "a");
+ REQUIRE(install_plan.install_actions.at(0).spec.name() == "c");
+ REQUIRE(install_plan.install_actions.at(1).spec.name() == "b");
+ REQUIRE(install_plan.install_actions.at(2).spec.name() == "a");
}
TEST_CASE ("multiple install scheme", "[plan]")
@@ -143,17 +94,21 @@ TEST_CASE ("multiple install scheme", "[plan]")
auto spec_g = spec_map.emplace("g");
auto spec_h = spec_map.emplace("h");
- Dependencies::MapPortFileProvider map_port(spec_map.map);
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
map_port,
- {FeatureSpec{spec_a, ""}, FeatureSpec{spec_b, ""}, FeatureSpec{spec_c, ""}},
+ var_provider,
+ {FullPackageSpec{spec_a}, FullPackageSpec{spec_b}, FullPackageSpec{spec_c}},
StatusParagraphs(std::move(status_paragraphs)));
auto iterator_pos = [&](const PackageSpec& spec) {
- auto it =
- std::find_if(install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec() == spec; });
- REQUIRE(it != install_plan.end());
- return it - install_plan.begin();
+ auto it = std::find_if(install_plan.install_actions.begin(),
+ install_plan.install_actions.end(),
+ [&](auto& action) { return action.spec == spec; });
+ REQUIRE(it != install_plan.install_actions.end());
+ return it - install_plan.install_actions.begin();
};
const auto a_pos = iterator_pos(spec_a);
@@ -184,12 +139,14 @@ TEST_CASE ("existing package scheme", "[plan]")
PackageSpecMap spec_map;
auto spec_a = FullPackageSpec{spec_map.emplace("a")};
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_a}), StatusParagraphs(std::move(status_paragraphs)));
+ map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 1);
- const auto p = install_plan.at(0).install_action.get();
- REQUIRE(p);
+ const auto p = &install_plan.already_installed.at(0);
REQUIRE(p->spec.name() == "a");
REQUIRE(p->plan_type == Dependencies::InstallPlanType::ALREADY_INSTALLED);
REQUIRE(p->request_type == Dependencies::RequestType::USER_REQUESTED);
@@ -203,18 +160,19 @@ TEST_CASE ("user requested package scheme", "[plan]")
const auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")};
const auto spec_b = FullPackageSpec{spec_map.emplace("b")};
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
const auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_a}), StatusParagraphs(std::move(status_paragraphs)));
+ map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 2);
- const auto p = install_plan.at(0).install_action.get();
- REQUIRE(p);
+ const auto p = &install_plan.install_actions.at(0);
REQUIRE(p->spec.name() == "b");
REQUIRE(p->plan_type == Dependencies::InstallPlanType::BUILD_AND_INSTALL);
REQUIRE(p->request_type == Dependencies::RequestType::AUTO_SELECTED);
- const auto p2 = install_plan.at(1).install_action.get();
- REQUIRE(p2);
+ const auto p2 = &install_plan.install_actions.at(1);
REQUIRE(p2->spec.name() == "a");
REQUIRE(p2->plan_type == Dependencies::InstallPlanType::BUILD_AND_INSTALL);
REQUIRE(p2->request_type == Dependencies::RequestType::USER_REQUESTED);
@@ -239,19 +197,21 @@ TEST_CASE ("long install scheme", "[plan]")
auto spec_j = spec_map.emplace("j", "k");
auto spec_k = spec_map.emplace("k");
- Dependencies::MapPortFileProvider map_port(spec_map.map);
- auto install_plan = Dependencies::create_feature_install_plan(
- map_port, {FeatureSpec{spec_a, ""}}, StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {FullPackageSpec{spec_a}}, StatusParagraphs(std::move(status_paragraphs)));
+ auto& install_plan = plan.install_actions;
REQUIRE(install_plan.size() == 8);
- REQUIRE(install_plan.at(0).spec().name() == "h");
- REQUIRE(install_plan.at(1).spec().name() == "g");
- REQUIRE(install_plan.at(2).spec().name() == "f");
- REQUIRE(install_plan.at(3).spec().name() == "e");
- REQUIRE(install_plan.at(4).spec().name() == "d");
- REQUIRE(install_plan.at(5).spec().name() == "c");
- REQUIRE(install_plan.at(6).spec().name() == "b");
- REQUIRE(install_plan.at(7).spec().name() == "a");
+ REQUIRE(install_plan.at(0).spec.name() == "h");
+ REQUIRE(install_plan.at(1).spec.name() == "g");
+ REQUIRE(install_plan.at(2).spec.name() == "f");
+ REQUIRE(install_plan.at(3).spec.name() == "e");
+ REQUIRE(install_plan.at(4).spec.name() == "d");
+ REQUIRE(install_plan.at(5).spec.name() == "c");
+ REQUIRE(install_plan.at(6).spec.name() == "b");
+ REQUIRE(install_plan.at(7).spec.name() == "a");
}
TEST_CASE ("basic feature test 1", "[plan]")
@@ -265,14 +225,17 @@ TEST_CASE ("basic feature test 1", "[plan]")
auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}};
auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})};
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_a}), StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
- REQUIRE(install_plan.size() == 4);
- remove_plan_check(install_plan.at(0), "a");
- remove_plan_check(install_plan.at(1), "b");
- features_check(install_plan.at(2), "b", {"b1", "core", "b1"});
- features_check(install_plan.at(3), "a", {"a1", "core"});
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
+
+ REQUIRE(plan.size() == 4);
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ remove_plan_check(plan.remove_actions.at(1), "b");
+ features_check(plan.install_actions.at(0), "b", {"b1", "core", "b1"});
+ features_check(plan.install_actions.at(1), "a", {"a1", "core"});
}
TEST_CASE ("basic feature test 2", "[plan]")
@@ -284,9 +247,13 @@ TEST_CASE ("basic feature test 2", "[plan]")
auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}};
auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})};
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_a}), StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
+ auto& install_plan = plan.install_actions;
REQUIRE(install_plan.size() == 2);
features_check(install_plan.at(0), "b", {"b1", "b2", "core"});
features_check(install_plan.at(1), "a", {"a1", "core"});
@@ -303,15 +270,18 @@ TEST_CASE ("basic feature test 3", "[plan]")
auto spec_b = FullPackageSpec{spec_map.emplace("b")};
auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
- auto install_plan = Dependencies::create_feature_install_plan(spec_map.map,
- FullPackageSpec::to_feature_specs({spec_c, spec_a}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {spec_c, spec_a}, StatusParagraphs(std::move(status_paragraphs)));
- REQUIRE(install_plan.size() == 4);
- remove_plan_check(install_plan.at(0), "a");
- features_check(install_plan.at(1), "b", {"core"});
- features_check(install_plan.at(2), "a", {"a1", "core"});
- features_check(install_plan.at(3), "c", {"core"});
+ REQUIRE(plan.size() == 4);
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ auto& install_plan = plan.install_actions;
+ features_check(install_plan.at(0), "b", {"core"});
+ features_check(install_plan.at(1), "a", {"a1", "core"});
+ features_check(install_plan.at(2), "c", {"core"});
}
TEST_CASE ("basic feature test 4", "[plan]")
@@ -326,11 +296,14 @@ TEST_CASE ("basic feature test 4", "[plan]")
auto spec_b = FullPackageSpec{spec_map.emplace("b")};
auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_c}), StatusParagraphs(std::move(status_paragraphs)));
+ map_port, var_provider, {spec_c}, StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "c", {"core"});
+ features_check(install_plan.install_actions.at(0), "c", {"core"});
}
TEST_CASE ("basic feature test 5", "[plan]")
@@ -343,12 +316,15 @@ TEST_CASE ("basic feature test 5", "[plan]")
FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}};
auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})};
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_a}), StatusParagraphs(std::move(status_paragraphs)));
+ map_port, var_provider, {spec_a}, StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 2);
- features_check(install_plan.at(0), "b", {"core", "b2"});
- features_check(install_plan.at(1), "a", {"core", "a3", "a2"});
+ features_check(install_plan.install_actions.at(0), "b", {"core", "b2"});
+ features_check(install_plan.install_actions.at(1), "a", {"core", "a3", "a2"});
}
TEST_CASE ("basic feature test 6", "[plan]")
@@ -360,14 +336,16 @@ TEST_CASE ("basic feature test 6", "[plan]")
auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}};
auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}};
- auto install_plan = Dependencies::create_feature_install_plan(spec_map.map,
- FullPackageSpec::to_feature_specs({spec_a, spec_b}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
- REQUIRE(install_plan.size() == 3);
- remove_plan_check(install_plan.at(0), "b");
- features_check(install_plan.at(1), "b", {"core", "b1"});
- features_check(install_plan.at(2), "a", {"core"});
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {spec_a, spec_b}, StatusParagraphs(std::move(status_paragraphs)));
+
+ REQUIRE(plan.size() == 3);
+ remove_plan_check(plan.remove_actions.at(0), "b");
+ features_check(plan.install_actions.at(0), "b", {"core", "b1"});
+ features_check(plan.install_actions.at(1), "a", {"core"});
}
TEST_CASE ("basic feature test 7", "[plan]")
@@ -382,20 +360,23 @@ TEST_CASE ("basic feature test 7", "[plan]")
auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}};
auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}};
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, FullPackageSpec::to_feature_specs({spec_b}), StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto plan = Dependencies::create_feature_install_plan(
+ map_port, var_provider, {spec_b}, StatusParagraphs(std::move(status_paragraphs)));
- REQUIRE(install_plan.size() == 5);
- remove_plan_check(install_plan.at(0), "x");
- remove_plan_check(install_plan.at(1), "b");
+ REQUIRE(plan.size() == 5);
+ remove_plan_check(plan.remove_actions.at(0), "x");
+ remove_plan_check(plan.remove_actions.at(1), "b");
// TODO: order here may change but A < X, and B anywhere
- features_check(install_plan.at(2), "b", {"core", "b1"});
- features_check(install_plan.at(3), "a", {"core"});
- features_check(install_plan.at(4), "x", {"core"});
+ features_check(plan.install_actions.at(0), "b", {"core", "b1"});
+ features_check(plan.install_actions.at(1), "a", {"core"});
+ features_check(plan.install_actions.at(2), "x", {"core"});
}
-TEST_CASE ("basic feature test 8", "[plan][!mayfail]")
+TEST_CASE ("basic feature test 8", "[plan]")
{
std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
status_paragraphs.push_back(make_status_pgh("a"));
@@ -413,19 +394,23 @@ TEST_CASE ("basic feature test 8", "[plan][!mayfail]")
auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")};
auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}};
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {spec_c_64, spec_a_86, spec_a_64, spec_c_86},
+ StatusParagraphs(std::move(status_paragraphs)));
- remove_plan_check(install_plan.at(0), "a", Triplet::X64_WINDOWS);
- remove_plan_check(install_plan.at(1), "a");
- features_check(install_plan.at(2), "b", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(3), "a", {"a1", "core"}, Triplet::X64_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(0), "a", Triplet::X64_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(1), "a");
+ auto& install_plan = plan.install_actions;
+ features_check(install_plan.at(0), "b", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.at(1), "a", {"a1", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.at(2), "b", {"core"});
+ features_check(install_plan.at(3), "a", {"a1", "core"});
features_check(install_plan.at(4), "c", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(5), "b", {"core"});
- features_check(install_plan.at(6), "a", {"a1", "core"});
- features_check(install_plan.at(7), "c", {"core"});
+ features_check(install_plan.at(5), "c", {"core"});
}
TEST_CASE ("install all features test", "[plan]")
@@ -438,13 +423,17 @@ TEST_CASE ("install all features test", "[plan]")
auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS);
REQUIRE(install_specs.has_value());
if (!install_specs.has_value()) return;
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"0", "1", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"0", "1", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("install default features test 1", "[plan]")
@@ -457,14 +446,18 @@ TEST_CASE ("install default features test 1", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
// Expect the default feature "1" to be installed, but not "0"
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"1", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"1", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("install default features test 2", "[plan]")
@@ -482,16 +475,20 @@ TEST_CASE ("install default features test 2", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
// Expect "a" to get removed for rebuild and then installed with default
// features.
REQUIRE(install_plan.size() == 2);
- remove_plan_check(install_plan.at(0), "a", Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "a", {"a1", "core"}, Triplet::X64_WINDOWS);
+ remove_plan_check(install_plan.remove_actions.at(0), "a", Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"a1", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("install default features test 3", "[plan]")
@@ -504,14 +501,18 @@ TEST_CASE ("install default features test 3", "[plan]")
// Explicitly install "a" without default features
auto install_specs = FullPackageSpec::from_string("a[core]", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
// Expect the default feature not to get installed.
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("install default features of dependency test 1", "[plan]")
@@ -526,16 +527,76 @@ TEST_CASE ("install default features of dependency test 1", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
+
+ // Expect "a" to get installed and defaults of "b" through the dependency,
+ // as no explicit features of "b" are installed by the user.
+ REQUIRE(install_plan.size() == 2);
+ features_check(install_plan.install_actions.at(0), "b", {"b1", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
+}
+
+TEST_CASE ("do not install default features of dependency test 1", "[plan]")
+{
+ std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
+
+ // Add a port "a" which depends on the core of "b"
+ PackageSpecMap spec_map(Triplet::X64_WINDOWS);
+ spec_map.emplace("a", "b[core]");
+ // "b" has two features, of which "b1" is default.
+ spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
+
+ // Install "a" (without explicit feature specification)
+ auto spec_a = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
+ auto spec_b = FullPackageSpec::from_string("b[core]", Triplet::X64_WINDOWS);
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
+ map_port,
+ var_provider,
+ {spec_a.value_or_exit(VCPKG_LINE_INFO), spec_b.value_or_exit(VCPKG_LINE_INFO)},
StatusParagraphs(std::move(status_paragraphs)));
// Expect "a" to get installed and defaults of "b" through the dependency,
// as no explicit features of "b" are installed by the user.
REQUIRE(install_plan.size() == 2);
- features_check(install_plan.at(0), "b", {"b1", "core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "b", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
+}
+
+TEST_CASE ("install default features of dependency test 2", "[plan]")
+{
+ std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
+
+ // Add a port "a" which depends on the default features of "b"
+ PackageSpecMap spec_map(Triplet::X64_WINDOWS);
+ spec_map.emplace("a", "b");
+ // "b" has two features, of which "b1" is default.
+ spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b1"});
+
+ // Install "a" (without explicit feature specification)
+ auto spec_a = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
+ auto spec_b = FullPackageSpec::from_string("b[core]", Triplet::X64_WINDOWS);
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(
+ map_port,
+ var_provider,
+ {spec_a.value_or_exit(VCPKG_LINE_INFO), spec_b.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
+
+ // Expect "a" to get installed and defaults of "b" through the dependency
+ REQUIRE(install_plan.size() == 2);
+ features_check(install_plan.install_actions.at(0), "b", {"b1", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("do not install default features of existing dependency", "[plan]")
@@ -554,17 +615,20 @@ TEST_CASE ("do not install default features of existing dependency", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
// Expect "a" to get installed, but not require rebuilding "b"
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
}
-TEST_CASE ("install default features of dependency test 2", "[plan]")
+TEST_CASE ("install default features of dependency test 3", "[plan]")
{
std::vector<std::unique_ptr<StatusParagraph>> status_paragraphs;
status_paragraphs.push_back(make_status_pgh("b"));
@@ -580,15 +644,18 @@ TEST_CASE ("install default features of dependency test 2", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
// Expect "a" to get installed, not the defaults of "b", as the required
// dependencies are already there, installed explicitly by the user.
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "a", {"core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("install plan action dependencies", "[plan]")
@@ -604,19 +671,23 @@ TEST_CASE ("install plan action dependencies", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- features_check(install_plan.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
- REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
+ // TODO: Figure out what to do with these tests
+ features_check(install_plan.install_actions.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
+ // REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
- features_check(install_plan.at(2), "a", {"core"}, Triplet::X64_WINDOWS);
- REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b});
+ features_check(install_plan.install_actions.at(2), "a", {"core"}, Triplet::X64_WINDOWS);
+ // REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b});
}
TEST_CASE ("install plan action dependencies 2", "[plan]")
@@ -632,19 +703,23 @@ TEST_CASE ("install plan action dependencies 2", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- features_check(install_plan.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
- REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
+ features_check(install_plan.install_actions.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
+ // REQUIRE(install_plan.at(1).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_c});
- features_check(install_plan.at(2), "a", {"core"}, Triplet::X64_WINDOWS);
- REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b, spec_c});
+ features_check(install_plan.install_actions.at(2), "a", {"core"}, Triplet::X64_WINDOWS);
+ // REQUIRE(install_plan.at(2).install_action.get()->computed_dependencies == std::vector<PackageSpec>{spec_b,
+ // spec_c});
}
TEST_CASE ("install plan action dependencies 3", "[plan]")
@@ -658,14 +733,17 @@ TEST_CASE ("install plan action dependencies 3", "[plan]")
// Install "a" (without explicit feature specification)
auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS);
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan = Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 1);
- features_check(install_plan.at(0), "a", {"1", "0", "core"}, Triplet::X64_WINDOWS);
- REQUIRE(install_plan.at(0).install_action.get()->computed_dependencies == std::vector<PackageSpec>{});
+ features_check(install_plan.install_actions.at(0), "a", {"1", "0", "core"}, Triplet::X64_WINDOWS);
+ // REQUIRE(install_plan.at(0).install_action.get()->computed_dependencies == std::vector<PackageSpec>{});
}
TEST_CASE ("install with default features", "[plan]")
@@ -678,14 +756,20 @@ TEST_CASE ("install with default features", "[plan]")
auto b_spec = spec_map.emplace("b", "", {{"0", ""}}, {"0"});
auto a_spec = spec_map.emplace("a", "b[core]", {{"0", ""}});
- // Install "a" and indicate that "b" should not install default features
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map, {FeatureSpec{a_spec, "0"}, FeatureSpec{b_spec, "core"}}, status_db);
+ PortFileProvider::MapPortFileProvider map_port{spec_map.map};
+ MockCMakeVarProvider var_provider;
+
+ auto install_plan =
+ Dependencies::create_feature_install_plan(map_port,
+ var_provider,
+ {FullPackageSpec{a_spec, {"0"}}, FullPackageSpec{b_spec, {"core"}}},
+ StatusParagraphs(std::move(status_db)));
+ // Install "a" and indicate that "b" should not install default features
REQUIRE(install_plan.size() == 3);
- remove_plan_check(install_plan.at(0), "a");
- features_check(install_plan.at(1), "b", {"core"});
- features_check(install_plan.at(2), "a", {"0", "core"});
+ remove_plan_check(install_plan.remove_actions.at(0), "a");
+ features_check(install_plan.install_actions.at(0), "b", {"core"});
+ features_check(install_plan.install_actions.at(1), "a", {"0", "core"});
}
TEST_CASE ("upgrade with default features 1", "[plan]")
@@ -699,18 +783,15 @@ TEST_CASE ("upgrade with default features 1", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}}, {"1"});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
// The upgrade should not install the default feature
REQUIRE(plan.size() == 2);
- REQUIRE(plan.at(0).spec().name() == "a");
- remove_plan_check(plan.at(0), "a");
- features_check(plan.at(1), "a", {"core", "0"});
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"core", "0"});
}
TEST_CASE ("upgrade with default features 2", "[plan]")
@@ -726,19 +807,16 @@ TEST_CASE ("upgrade with default features 2", "[plan]")
auto spec_a = spec_map.emplace("a", "b[core]");
auto spec_b = spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0", "b1"});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
- graph.upgrade(spec_b);
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a, spec_b}, status_db);
// The upgrade should install the new default feature b1 but not b0
REQUIRE(plan.size() == 4);
- remove_plan_check(plan.at(0), "a", Triplet::X64_WINDOWS);
- remove_plan_check(plan.at(1), "b", Triplet::X64_WINDOWS);
- features_check(plan.at(2), "b", {"core", "b1"}, Triplet::X64_WINDOWS);
- features_check(plan.at(3), "a", {"core"}, Triplet::X64_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(0), "a", Triplet::X64_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(1), "b", Triplet::X64_WINDOWS);
+ features_check(plan.install_actions.at(0), "b", {"core", "b1"}, Triplet::X64_WINDOWS);
+ features_check(plan.install_actions.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("upgrade with default features 3", "[plan]")
@@ -754,17 +832,15 @@ TEST_CASE ("upgrade with default features 3", "[plan]")
auto spec_a = spec_map.emplace("a", "b[core]");
spec_map.emplace("b", "", {{"b0", ""}, {"b1", ""}}, {"b0"});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
// The upgrade should install the default feature
REQUIRE(plan.size() == 3);
- remove_plan_check(plan.at(0), "a", Triplet::X64_WINDOWS);
- features_check(plan.at(1), "b", {"b0", "core"}, Triplet::X64_WINDOWS);
- features_check(plan.at(2), "a", {"core"}, Triplet::X64_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(0), "a", Triplet::X64_WINDOWS);
+ features_check(plan.install_actions.at(0), "b", {"b0", "core"}, Triplet::X64_WINDOWS);
+ features_check(plan.install_actions.at(1), "a", {"core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("upgrade with new default feature", "[plan]")
@@ -777,16 +853,14 @@ TEST_CASE ("upgrade with new default feature", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a", "", {{"0", ""}, {"1", ""}, {"2", ""}}, {"0", "1"});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
// The upgrade should install the new default feature but not the old default feature 0
REQUIRE(plan.size() == 2);
- remove_plan_check(plan.at(0), "a", Triplet::X86_WINDOWS);
- features_check(plan.at(1), "a", {"core", "1"}, Triplet::X86_WINDOWS);
+ remove_plan_check(plan.remove_actions.at(0), "a", Triplet::X86_WINDOWS);
+ features_check(plan.install_actions.at(0), "a", {"core", "1"}, Triplet::X86_WINDOWS);
}
TEST_CASE ("transitive features test", "[plan]")
@@ -801,15 +875,18 @@ TEST_CASE ("transitive features test", "[plan]")
auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS);
REQUIRE(install_specs.has_value());
if (!install_specs.has_value()) return;
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto install_plan = Dependencies::create_feature_install_plan(provider,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- features_check(install_plan.at(0), "c", {"0", "core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "b", {"0", "core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "c", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "b", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("no transitive features test", "[plan]")
@@ -824,15 +901,17 @@ TEST_CASE ("no transitive features test", "[plan]")
auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS);
REQUIRE(install_specs.has_value());
if (!install_specs.has_value()) return;
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto install_plan = Dependencies::create_feature_install_plan(provider,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- features_check(install_plan.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "c", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "b", {"core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("only transitive features test", "[plan]")
@@ -847,15 +926,17 @@ TEST_CASE ("only transitive features test", "[plan]")
auto install_specs = FullPackageSpec::from_string("a[*]", Triplet::X64_WINDOWS);
REQUIRE(install_specs.has_value());
if (!install_specs.has_value()) return;
- auto install_plan = Dependencies::create_feature_install_plan(
- spec_map.map,
- FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}),
- StatusParagraphs(std::move(status_paragraphs)));
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto install_plan = Dependencies::create_feature_install_plan(provider,
+ var_provider,
+ {install_specs.value_or_exit(VCPKG_LINE_INFO)},
+ StatusParagraphs(std::move(status_paragraphs)));
REQUIRE(install_plan.size() == 3);
- features_check(install_plan.at(0), "c", {"0", "core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(1), "b", {"0", "core"}, Triplet::X64_WINDOWS);
- features_check(install_plan.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(0), "c", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(1), "b", {"0", "core"}, Triplet::X64_WINDOWS);
+ features_check(install_plan.install_actions.at(2), "a", {"0", "core"}, Triplet::X64_WINDOWS);
}
TEST_CASE ("basic remove scheme", "[plan]")
@@ -973,18 +1054,13 @@ TEST_CASE ("basic upgrade scheme", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a");
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 2);
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
- REQUIRE(plan.at(1).spec().name() == "a");
- REQUIRE(plan.at(1).install_action.has_value());
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"core"});
}
TEST_CASE ("basic upgrade scheme with recurse", "[plan]")
@@ -998,25 +1074,15 @@ TEST_CASE ("basic upgrade scheme with recurse", "[plan]")
auto spec_a = spec_map.emplace("a");
spec_map.emplace("b", "a");
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 4);
- REQUIRE(plan.at(0).spec().name() == "b");
- REQUIRE(plan.at(0).remove_action.has_value());
-
- REQUIRE(plan.at(1).spec().name() == "a");
- REQUIRE(plan.at(1).remove_action.has_value());
-
- REQUIRE(plan.at(2).spec().name() == "a");
- REQUIRE(plan.at(2).install_action.has_value());
-
- REQUIRE(plan.at(3).spec().name() == "b");
- REQUIRE(plan.at(3).install_action.has_value());
+ remove_plan_check(plan.remove_actions.at(0), "b");
+ remove_plan_check(plan.remove_actions.at(1), "a");
+ features_check(plan.install_actions.at(0), "a", {"core"});
+ features_check(plan.install_actions.at(1), "b", {"core"});
}
TEST_CASE ("basic upgrade scheme with bystander", "[plan]")
@@ -1030,18 +1096,13 @@ TEST_CASE ("basic upgrade scheme with bystander", "[plan]")
auto spec_a = spec_map.emplace("a");
spec_map.emplace("b", "a");
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 2);
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
- REQUIRE(plan.at(1).spec().name() == "a");
- REQUIRE(plan.at(1).install_action.has_value());
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"core"});
}
TEST_CASE ("basic upgrade scheme with new dep", "[plan]")
@@ -1054,20 +1115,14 @@ TEST_CASE ("basic upgrade scheme with new dep", "[plan]")
auto spec_a = spec_map.emplace("a", "b");
spec_map.emplace("b");
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 3);
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
- REQUIRE(plan.at(1).spec().name() == "b");
- REQUIRE(plan.at(1).install_action.has_value());
- REQUIRE(plan.at(2).spec().name() == "a");
- REQUIRE(plan.at(2).install_action.has_value());
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "b", {"core"});
+ features_check(plan.install_actions.at(1), "a", {"core"});
}
TEST_CASE ("basic upgrade scheme with features", "[plan]")
@@ -1080,19 +1135,13 @@ TEST_CASE ("basic upgrade scheme with features", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a", "", {{"a1", ""}});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 2);
-
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
-
- features_check(plan.at(1), "a", {"core", "a1"});
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"core", "a1"});
}
TEST_CASE ("basic upgrade scheme with new default feature", "[plan]")
@@ -1106,19 +1155,13 @@ TEST_CASE ("basic upgrade scheme with new default feature", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a", "", {{"a1", ""}}, {"a1"});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 2);
-
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
-
- features_check(plan.at(1), "a", {"core", "a1"});
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"core", "a1"});
}
TEST_CASE ("basic upgrade scheme with self features", "[plan]")
@@ -1132,21 +1175,13 @@ TEST_CASE ("basic upgrade scheme with self features", "[plan]")
PackageSpecMap spec_map;
auto spec_a = spec_map.emplace("a", "", {{"a1", ""}, {"a2", "a[a1]"}});
- Dependencies::MapPortFileProvider provider(spec_map.map);
- Dependencies::PackageGraph graph(provider, status_db);
-
- graph.upgrade(spec_a);
-
- auto plan = graph.serialize();
+ PortFileProvider::MapPortFileProvider provider(spec_map.map);
+ MockCMakeVarProvider var_provider;
+ auto plan = Dependencies::create_upgrade_plan(provider, var_provider, {spec_a}, status_db);
REQUIRE(plan.size() == 2);
-
- REQUIRE(plan.at(0).spec().name() == "a");
- REQUIRE(plan.at(0).remove_action.has_value());
-
- REQUIRE(plan.at(1).spec().name() == "a");
- REQUIRE(plan.at(1).install_action.has_value());
- REQUIRE(plan.at(1).install_action.get()->feature_list == std::set<std::string>{"core", "a1", "a2"});
+ remove_plan_check(plan.remove_actions.at(0), "a");
+ features_check(plan.install_actions.at(0), "a", {"a1", "a2", "core"});
}
TEST_CASE ("basic export scheme", "[plan]")
diff --git a/toolsrc/src/vcpkg-test/specifier.cpp b/toolsrc/src/vcpkg-test/specifier.cpp
index 33df8ba83..a0a3725e8 100644
--- a/toolsrc/src/vcpkg-test/specifier.cpp
+++ b/toolsrc/src/vcpkg-test/specifier.cpp
@@ -1,5 +1,6 @@
#include <catch2/catch.hpp>
+#include <vcpkg/base/system.print.h>
#include <vcpkg/base/util.h>
#include <vcpkg/packagespec.h>
@@ -14,11 +15,13 @@ TEST_CASE ("specifier conversion", "[specifier]")
auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO);
auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO);
- auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}});
-
+ auto fspecs = FullPackageSpec{a_spec, {"0", "1"}}.to_feature_specs({}, {});
+ auto fspecs2 = FullPackageSpec{b_spec, {"2", "3"}}.to_feature_specs({}, {});
+ Util::Vectors::append(&fspecs, fspecs2);
+ Util::sort(fspecs);
REQUIRE(fspecs.size() == SPEC_SIZE);
- std::array<const char*, SPEC_SIZE> features = {"", "0", "1", "", "2", "3"};
+ std::array<const char*, SPEC_SIZE> features = {"0", "1", "core", "2", "3", "core"};
std::array<PackageSpec*, SPEC_SIZE> specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec};
for (std::size_t i = 0; i < SPEC_SIZE; ++i)
@@ -101,19 +104,20 @@ TEST_CASE ("specifier parsing", "[specifier]")
auto zlib = vcpkg::FullPackageSpec::from_string("zlib[0,1]", Triplet::X86_UWP).value_or_exit(VCPKG_LINE_INFO);
auto openssl =
vcpkg::FullPackageSpec::from_string("openssl[*]", Triplet::X86_UWP).value_or_exit(VCPKG_LINE_INFO);
- auto specs = FullPackageSpec::to_feature_specs({zlib, openssl});
+ auto specs = zlib.to_feature_specs({}, {});
+ auto specs2 = openssl.to_feature_specs({}, {});
+ Util::Vectors::append(&specs, specs2);
Util::sort(specs);
+
auto spectargets = FeatureSpec::from_strings_and_triplet(
{
"openssl",
"zlib",
- "openssl[*]",
"zlib[0]",
"zlib[1]",
},
Triplet::X86_UWP);
Util::sort(spectargets);
-
REQUIRE(specs.size() == spectargets.size());
REQUIRE(Util::all_equal(specs, spectargets));
}
diff --git a/toolsrc/src/vcpkg-test/supports.cpp b/toolsrc/src/vcpkg-test/supports.cpp
deleted file mode 100644
index f4d8dc65a..000000000
--- a/toolsrc/src/vcpkg-test/supports.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <catch2/catch.hpp>
-
-#include <vcpkg/sourceparagraph.h>
-
-using namespace vcpkg;
-using Parse::parse_comma_list;
-
-TEST_CASE ("parse supports all", "[supports]")
-{
- auto v = Supports::parse({
- "x64",
- "x86",
- "arm",
- "windows",
- "uwp",
- "v140",
- "v141",
- "crt-static",
- "crt-dynamic",
- });
-
- REQUIRE(v.has_value());
-
- REQUIRE(v.get()->is_supported(System::CPUArchitecture::X64,
- Supports::Platform::UWP,
- Supports::Linkage::DYNAMIC,
- Supports::ToolsetVersion::V140));
- REQUIRE(v.get()->is_supported(System::CPUArchitecture::ARM,
- Supports::Platform::WINDOWS,
- Supports::Linkage::STATIC,
- Supports::ToolsetVersion::V141));
-}
-
-TEST_CASE ("parse supports invalid", "[supports]")
-{
- auto v = Supports::parse({"arm64"});
-
- REQUIRE_FALSE(v.has_value());
-
- REQUIRE(v.error().size() == 1);
- REQUIRE(v.error().at(0) == "arm64");
-}
-
-TEST_CASE ("parse supports case sensitive", "[supports]")
-{
- auto v = Supports::parse({"Windows"});
-
- REQUIRE_FALSE(v.has_value());
- REQUIRE(v.error().size() == 1);
- REQUIRE(v.error().at(0) == "Windows");
-}
-
-TEST_CASE ("parse supports some", "[supports]")
-{
- auto v = Supports::parse({
- "x64",
- "x86",
- "windows",
- });
-
- REQUIRE(v.has_value());
-
- REQUIRE(v.get()->is_supported(System::CPUArchitecture::X64,
- Supports::Platform::WINDOWS,
- Supports::Linkage::DYNAMIC,
- Supports::ToolsetVersion::V140));
- REQUIRE_FALSE(v.get()->is_supported(System::CPUArchitecture::ARM,
- Supports::Platform::WINDOWS,
- Supports::Linkage::DYNAMIC,
- Supports::ToolsetVersion::V140));
- REQUIRE_FALSE(v.get()->is_supported(System::CPUArchitecture::X64,
- Supports::Platform::UWP,
- Supports::Linkage::DYNAMIC,
- Supports::ToolsetVersion::V140));
- REQUIRE(v.get()->is_supported(System::CPUArchitecture::X64,
- Supports::Platform::WINDOWS,
- Supports::Linkage::STATIC,
- Supports::ToolsetVersion::V141));
-}
diff --git a/toolsrc/src/vcpkg-test/update.cpp b/toolsrc/src/vcpkg-test/update.cpp
index 6f1a87d23..a362df720 100644
--- a/toolsrc/src/vcpkg-test/update.cpp
+++ b/toolsrc/src/vcpkg-test/update.cpp
@@ -20,9 +20,9 @@ TEST_CASE ("find outdated packages basic", "[update]")
StatusParagraphs status_db(std::move(status_paragraphs));
std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}}));
+ auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}}));
map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- Dependencies::MapPortFileProvider provider(map);
+ PortFileProvider::MapPortFileProvider provider(map);
auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
&OutdatedPackage::compare_by_name);
@@ -44,9 +44,9 @@ TEST_CASE ("find outdated packages features", "[update]")
StatusParagraphs status_db(std::move(status_paragraphs));
std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}}));
+ auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}}));
map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- Dependencies::MapPortFileProvider provider(map);
+ PortFileProvider::MapPortFileProvider provider(map);
auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
&OutdatedPackage::compare_by_name);
@@ -70,9 +70,9 @@ TEST_CASE ("find outdated packages features 2", "[update]")
StatusParagraphs status_db(std::move(status_paragraphs));
std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}}));
+ auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "0"}}}));
map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- Dependencies::MapPortFileProvider provider(map);
+ PortFileProvider::MapPortFileProvider provider(map);
auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
&OutdatedPackage::compare_by_name);
@@ -91,9 +91,9 @@ TEST_CASE ("find outdated packages none", "[update]")
StatusParagraphs status_db(std::move(status_paragraphs));
std::unordered_map<std::string, SourceControlFileLocation> map;
- auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}}));
+ auto scf = unwrap(SourceControlFile::parse_control_file("", Pgh{{{"Source", "a"}, {"Version", "2"}}}));
map.emplace("a", SourceControlFileLocation{std::move(scf), ""});
- Dependencies::MapPortFileProvider provider(map);
+ PortFileProvider::MapPortFileProvider provider(map);
auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db),
&OutdatedPackage::compare_by_name);
diff --git a/toolsrc/src/vcpkg-test/util.cpp b/toolsrc/src/vcpkg-test/util.cpp
index daa21567d..db310f7a0 100644
--- a/toolsrc/src/vcpkg-test/util.cpp
+++ b/toolsrc/src/vcpkg-test/util.cpp
@@ -38,6 +38,31 @@
namespace vcpkg::Test
{
+ std::unique_ptr<SourceControlFile> make_control_file(
+ const char* name,
+ const char* depends,
+ const std::vector<std::pair<const char*, const char*>>& features,
+ const std::vector<const char*>& default_features)
+ {
+ using Pgh = std::unordered_map<std::string, std::string>;
+ std::vector<Pgh> scf_pghs;
+ scf_pghs.push_back(Pgh{{"Source", name},
+ {"Version", "0"},
+ {"Build-Depends", depends},
+ {"Default-Features", Strings::join(", ", default_features)}});
+ for (auto&& feature : features)
+ {
+ scf_pghs.push_back(Pgh{
+ {"Feature", feature.first},
+ {"Description", "feature"},
+ {"Build-Depends", feature.second},
+ });
+ }
+ auto m_pgh = vcpkg::SourceControlFile::parse_control_file("", std::move(scf_pghs));
+ REQUIRE(m_pgh.has_value());
+ return std::move(*m_pgh.get());
+ }
+
std::unique_ptr<vcpkg::StatusParagraph> make_status_pgh(const char* name,
const char* depends,
const char* default_features,
@@ -68,6 +93,23 @@ namespace vcpkg::Test
{"Status", "install ok installed"}});
}
+ PackageSpec PackageSpecMap::emplace(const char* name,
+ const char* depends,
+ const std::vector<std::pair<const char*, const char*>>& features,
+ const std::vector<const char*>& default_features)
+ {
+ auto scfl = SourceControlFileLocation{make_control_file(name, depends, features, default_features), ""};
+ return emplace(std::move(scfl));
+ }
+
+ PackageSpec PackageSpecMap::emplace(vcpkg::SourceControlFileLocation&& scfl)
+ {
+ auto spec = PackageSpec::from_name_and_triplet(scfl.source_control_file->core_paragraph->name, triplet);
+ REQUIRE(spec.has_value());
+ map.emplace(scfl.source_control_file->core_paragraph->name, std::move(scfl));
+ return PackageSpec{*spec.get()};
+ }
+
PackageSpec unsafe_pspec(std::string name, Triplet t)
{
auto m_ret = PackageSpec::from_name_and_triplet(name, t);
diff --git a/toolsrc/src/vcpkg/base/machinetype.cpp b/toolsrc/src/vcpkg/base/machinetype.cpp
index 2b7bd5e3a..237e1eb8b 100644
--- a/toolsrc/src/vcpkg/base/machinetype.cpp
+++ b/toolsrc/src/vcpkg/base/machinetype.cpp
@@ -35,7 +35,7 @@ namespace vcpkg
case MachineType::SH5:
case MachineType::THUMB:
case MachineType::WCEMIPSV2: return t;
- default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%x", value);
+ default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%hx", value);
}
}
}
diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp
index 5a446a330..b71ab7c44 100644
--- a/toolsrc/src/vcpkg/base/system.cpp
+++ b/toolsrc/src/vcpkg/base/system.cpp
@@ -444,7 +444,7 @@ namespace vcpkg
Debug::print("_wpopen(", actual_cmd_line, ")\n");
std::wstring output;
- wchar_t buf[1024];
+ auto buf = std::make_unique<wchar_t[]>(1024 * 32);
g_ctrl_c_state.transition_to_spawn_process();
// Flush stdout before launching external process
fflush(stdout);
@@ -454,9 +454,9 @@ namespace vcpkg
g_ctrl_c_state.transition_from_spawn_process();
return {1, Strings::to_utf8(output.c_str())};
}
- while (fgetws(buf, 1024, pipe))
+ while (fgetws(buf.get(), 1024 * 32, pipe))
{
- output.append(buf);
+ output.append(buf.get());
}
if (!feof(pipe))
{
diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp
index 8b1886098..3404a6a48 100644
--- a/toolsrc/src/vcpkg/binaryparagraph.cpp
+++ b/toolsrc/src/vcpkg/binaryparagraph.cpp
@@ -2,6 +2,8 @@
#include <vcpkg/base/checks.h>
#include <vcpkg/base/system.print.h>
+#include <vcpkg/base/util.h>
+
#include <vcpkg/binaryparagraph.h>
#include <vcpkg/parse.h>
@@ -23,6 +25,7 @@ namespace vcpkg
static const std::string MAINTAINER = "Maintainer";
static const std::string DEPENDS = "Depends";
static const std::string DEFAULTFEATURES = "Default-Features";
+ static const std::string TYPE = "Type";
}
BinaryParagraph::BinaryParagraph() = default;
@@ -60,6 +63,8 @@ namespace vcpkg
this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES));
}
+ this->type = Type::from_string(parser.optional_field(Fields::TYPE));
+
if (const auto err = parser.error_info(this->spec.to_string()))
{
System::print2(System::Color::error, "Error: while parsing the Binary Paragraph for ", this->spec, '\n');
@@ -71,18 +76,30 @@ namespace vcpkg
Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch);
}
- BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet, const std::string& abi_tag)
- : version(spgh.version), description(spgh.description), maintainer(spgh.maintainer), abi(abi_tag)
+ BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh,
+ const Triplet& triplet,
+ const std::string& abi_tag,
+ const std::vector<FeatureSpec>& deps)
+ : version(spgh.version)
+ , description(spgh.description)
+ , maintainer(spgh.maintainer)
+ , abi(abi_tag)
+ , type(spgh.type)
{
this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO);
- this->depends = filter_dependencies(spgh.depends, triplet);
+ this->depends = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.to_string(); });
+ Util::sort_unique_erase(this->depends);
}
- BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet)
- : version(), description(fpgh.description), maintainer(), feature(fpgh.name)
+ BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh,
+ const FeatureParagraph& fpgh,
+ const Triplet& triplet,
+ const std ::vector<FeatureSpec>& deps)
+ : version(), description(fpgh.description), maintainer(), feature(fpgh.name), type(spgh.type)
{
this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO);
- this->depends = filter_dependencies(fpgh.depends, triplet);
+ this->depends = Util::fmap(deps, [](const FeatureSpec& spec) { return spec.to_string(); });
+ Util::sort_unique_erase(this->depends);
}
std::string BinaryParagraph::displayname() const
@@ -119,5 +136,7 @@ namespace vcpkg
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("Type: ").append(Type::to_string(pgh.type)).push_back('\n');
}
}
diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index 654142696..bcacb331a 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -23,10 +23,11 @@
#include <vcpkg/statusparagraphs.h>
#include <vcpkg/vcpkglib.h>
+using namespace vcpkg;
using vcpkg::Build::BuildResult;
-using vcpkg::Dependencies::PathsPortFileProvider;
using vcpkg::Parse::ParseControlErrorInfo;
using vcpkg::Parse::ParseExpected;
+using vcpkg::PortFileProvider::PathsPortFileProvider;
namespace vcpkg::Build::Command
{
@@ -35,12 +36,21 @@ namespace vcpkg::Build::Command
void perform_and_exit_ex(const FullPackageSpec& full_spec,
const SourceControlFileLocation& scfl,
+ const PathsPortFileProvider& provider,
const ParsedArguments& options,
const VcpkgPaths& paths)
{
vcpkg::Util::unused(options);
- const StatusParagraphs status_db = database_load_check(paths);
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
+ var_provider.load_dep_info_vars(std::array<PackageSpec, 1>{full_spec.package_spec});
+ var_provider.load_tag_vars(std::array<FullPackageSpec, 1>{full_spec}, provider);
+
+ StatusParagraphs status_db = database_load_check(paths);
+
+ auto action_plan = Dependencies::create_feature_install_plan(
+ provider, var_provider, std::vector<FullPackageSpec>{full_spec}, status_db);
+
const PackageSpec& spec = full_spec.package_spec;
const SourceControlFile& scf = *scfl.source_control_file;
@@ -62,10 +72,39 @@ namespace vcpkg::Build::Command
Build::FailOnTombstone::NO,
};
- std::set<std::string> features_as_set(full_spec.features.begin(), full_spec.features.end());
- features_as_set.emplace("core");
+ std::unordered_map<std::string, std::vector<FeatureSpec>>* feature_dependencies = nullptr;
+ std::vector<PackageSpec>* package_dependencies = nullptr;
+ std::vector<std::string>* feature_list = nullptr;
+ for (auto& install_action : action_plan.already_installed)
+ {
+ if (install_action.spec == full_spec.package_spec)
+ {
+ feature_dependencies = &install_action.feature_dependencies;
+ package_dependencies = &install_action.package_dependencies;
+ feature_list = &install_action.feature_list;
+ }
+ }
+ for (auto& install_action : action_plan.install_actions)
+ {
+ if (install_action.spec == full_spec.package_spec)
+ {
+ feature_dependencies = &install_action.feature_dependencies;
+ package_dependencies = &install_action.package_dependencies;
+ feature_list = &install_action.feature_list;
+ }
+ }
+
+ Checks::check_exit(VCPKG_LINE_INFO, feature_dependencies != nullptr);
+ Checks::check_exit(VCPKG_LINE_INFO, package_dependencies != nullptr);
+ Checks::check_exit(VCPKG_LINE_INFO, feature_list != nullptr);
- const Build::BuildPackageConfig build_config{scfl, spec.triplet(), build_package_options, features_as_set};
+ const Build::BuildPackageConfig build_config{scfl,
+ spec.triplet(),
+ build_package_options,
+ var_provider,
+ *feature_dependencies,
+ *package_dependencies,
+ *feature_list};
const auto build_timer = Chrono::ElapsedTimer::create_started();
const auto result = Build::build_package(paths, build_config, status_db);
@@ -121,7 +160,7 @@ namespace vcpkg::Build::Command
Checks::check_exit(VCPKG_LINE_INFO, scfl != nullptr, "Error: Couldn't find port '%s'", port_name);
- perform_and_exit_ex(spec, *scfl, options, paths);
+ perform_and_exit_ex(spec, *scfl, provider, options, paths);
}
}
@@ -133,6 +172,7 @@ namespace vcpkg::Build
static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT";
static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder";
static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt";
+ static const std::string NAME_ALLOW_RESTRICTED_HEADERS = "PolicyAllowRestrictedHeaders";
const std::string& to_string(BuildPolicy policy)
{
@@ -144,6 +184,7 @@ namespace vcpkg::Build
case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT;
case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER;
case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT;
+ case BuildPolicy::ALLOW_RESTRICTED_HEADERS: return NAME_ALLOW_RESTRICTED_HEADERS;
default: Checks::unreachable(VCPKG_LINE_INFO);
}
}
@@ -158,6 +199,7 @@ namespace vcpkg::Build
case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT";
case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER";
case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT";
+ case BuildPolicy::ALLOW_RESTRICTED_HEADERS: return "VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS";
default: Checks::unreachable(VCPKG_LINE_INFO);
}
}
@@ -260,20 +302,15 @@ namespace vcpkg::Build
tonull);
}
- static BinaryParagraph create_binary_feature_control_file(const SourceParagraph& source_paragraph,
- const FeatureParagraph& feature_paragraph,
- const Triplet& triplet)
- {
- return BinaryParagraph(source_paragraph, feature_paragraph, triplet);
- }
-
- static std::unique_ptr<BinaryControlFile> create_binary_control_file(const SourceParagraph& source_paragraph,
- const Triplet& triplet,
- const BuildInfo& build_info,
- const std::string& abi_tag)
+ static std::unique_ptr<BinaryControlFile> create_binary_control_file(
+ const SourceParagraph& source_paragraph,
+ const Triplet& triplet,
+ const BuildInfo& build_info,
+ const std::string& abi_tag,
+ const std::vector<FeatureSpec>& core_dependencies)
{
auto bcf = std::make_unique<BinaryControlFile>();
- BinaryParagraph bpgh(source_paragraph, triplet, abi_tag);
+ BinaryParagraph bpgh(source_paragraph, triplet, abi_tag, core_dependencies);
if (const auto p_ver = build_info.version.get())
{
bpgh.version = *p_ver;
@@ -294,71 +331,6 @@ namespace vcpkg::Build
paths.get_filesystem().write_contents(binary_control_file, start, VCPKG_LINE_INFO);
}
- static std::vector<Features> get_dependencies(const SourceControlFile& scf,
- const std::set<std::string>& feature_list,
- const Triplet& triplet)
- {
- return Util::fmap_flatten(feature_list, [&](std::string const& feature) -> std::vector<Features> {
- if (feature == "core")
- {
- return filter_dependencies_to_features(scf.core_paragraph->depends, triplet);
- }
-
- auto maybe_feature = scf.find_feature(feature);
- Checks::check_exit(VCPKG_LINE_INFO, maybe_feature.has_value());
-
- return filter_dependencies_to_features(maybe_feature.get()->depends, triplet);
- });
- }
-
- static std::vector<std::string> get_dependency_names(const SourceControlFile& scf,
- const std::set<std::string>& feature_list,
- const Triplet& triplet)
- {
- return Util::sort_unique_erase(
- Util::fmap(get_dependencies(scf, feature_list, triplet), [&](const Features& feat) { return feat.name; }));
- }
-
- static std::vector<FeatureSpec> compute_required_feature_specs(const BuildPackageConfig& config,
- const StatusParagraphs& status_db)
- {
- const Triplet& triplet = config.triplet;
-
- const std::vector<std::string> dep_strings = get_dependency_names(config.scf, config.feature_list, triplet);
-
- auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet);
- Util::sort_unique_erase(dep_fspecs);
-
- // expand defaults
- std::vector<FeatureSpec> ret;
- for (auto&& fspec : dep_fspecs)
- {
- if (fspec.feature().empty())
- {
- // reference to default features
- const auto it = status_db.find_installed(fspec.spec());
- if (it == status_db.end())
- {
- // not currently installed, so just leave the default reference so it will fail later
- ret.push_back(fspec);
- }
- else
- {
- ret.emplace_back(fspec.spec(), "core");
- for (auto&& default_feature : it->get()->package.default_features)
- ret.emplace_back(fspec.spec(), default_feature);
- }
- }
- else
- {
- ret.push_back(fspec);
- }
- }
- Util::sort_unique_erase(ret);
-
- return ret;
- }
-
static int get_concurrency()
{
static int concurrency = [] {
@@ -423,30 +395,22 @@ namespace vcpkg::Build
}
const Files::Filesystem& fs = paths.get_filesystem();
- if (fs.is_regular_file(config.port_dir / "environment-overrides.cmake"))
- {
- variables.emplace_back("VCPKG_ENV_OVERRIDES_FILE", config.port_dir / "environment-overrides.cmake");
- }
-
- std::vector<FeatureSpec> dependencies =
- filter_dependencies_to_specs(config.scfl.source_control_file->core_paragraph->depends, triplet);
- std::vector<std::string> port_toolchains;
- for (const FeatureSpec& dependency : dependencies)
+ std::vector<std::string> port_configs;
+ for (const PackageSpec& dependency : config.package_dependencies)
{
- const fs::path port_toolchain_path = paths.installed / dependency.triplet().canonical_name() / "share" /
- dependency.spec().name() / "port-toolchain.cmake";
+ const fs::path port_config_path = paths.installed / dependency.triplet().canonical_name() / "share" /
+ dependency.name() / "vcpkg-port-config.cmake";
- if (fs.is_regular_file(port_toolchain_path))
+ if (fs.is_regular_file(port_config_path))
{
- System::print2(port_toolchain_path.u8string());
- port_toolchains.emplace_back(port_toolchain_path.u8string());
+ port_configs.emplace_back(port_config_path.u8string());
}
}
- if (!port_toolchains.empty())
+ if (!port_configs.empty())
{
- variables.emplace_back("VCPKG_PORT_TOOLCHAINS", Strings::join(";", port_toolchains));
+ variables.emplace_back("VCPKG_PORT_CONFIGS", Strings::join(";", port_configs));
}
return variables;
@@ -554,7 +518,9 @@ namespace vcpkg::Build
if (Strings::case_insensitive_ascii_starts_with(triplet_file_path, paths.community_triplets.u8string()))
{
- System::printf(vcpkg::System::Color::warning, "-- Using community triplet %s. This triplet configuration is not guaranteed to succeed.\n", triplet.canonical_name());
+ System::printf(vcpkg::System::Color::warning,
+ "-- Using community triplet %s. This triplet configuration is not guaranteed to succeed.\n",
+ triplet.canonical_name());
System::printf("-- [COMMUNITY] Loading triplet configuration from: %s\n", triplet_file_path);
}
else if (!Strings::case_insensitive_ascii_starts_with(triplet_file_path, paths.triplets.u8string()))
@@ -613,8 +579,11 @@ namespace vcpkg::Build
const size_t error_count =
PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info, config.port_dir);
- std::unique_ptr<BinaryControlFile> bcf =
- create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag);
+ auto find_itr = config.feature_dependencies.find("core");
+ Checks::check_exit(VCPKG_LINE_INFO, find_itr != config.feature_dependencies.end());
+
+ std::unique_ptr<BinaryControlFile> bcf = create_binary_control_file(
+ *config.scf.core_paragraph, triplet, build_info, abi_tag, std::move(find_itr->second));
if (error_count != 0)
{
@@ -625,8 +594,13 @@ namespace vcpkg::Build
for (auto&& f_pgh : config.scf.feature_paragraphs)
{
if (f_pgh->name == feature)
- bcf->features.push_back(
- create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet));
+ {
+ find_itr = config.feature_dependencies.find(feature);
+ Checks::check_exit(VCPKG_LINE_INFO, find_itr != config.feature_dependencies.end());
+
+ bcf->features.emplace_back(
+ *config.scf.core_paragraph, *f_pgh, triplet, std::move(find_itr->second));
+ }
}
}
@@ -721,8 +695,11 @@ namespace vcpkg::Build
paths.scripts / "cmake" / "vcpkg_fixup_cmake_targets.cmake",
Hash::Algorithm::Sha1));
+ abi_tag_entries.emplace_back("post_build_checks", "2");
abi_tag_entries.emplace_back("triplet", pre_build_info.triplet_abi_tag);
- abi_tag_entries.emplace_back("features", Strings::join(";", config.feature_list));
+ std::vector<std::string> sorted_feature_list(std::begin(config.feature_list), std::end(config.feature_list));
+ Util::sort(sorted_feature_list);
+ abi_tag_entries.emplace_back("features", Strings::join(";", sorted_feature_list));
if (pre_build_info.public_abi_override)
{
@@ -732,6 +709,14 @@ namespace vcpkg::Build
Hash::Algorithm::Sha1));
}
+ // No need to sort, the variables are stored in the same order they are written down in the abi-settings file
+ for (const auto& env_var : pre_build_info.passthrough_env_vars)
+ {
+ abi_tag_entries.emplace_back(
+ "ENV:" + env_var,
+ Hash::get_string_hash(System::get_environment_variable(env_var).value_or(""), Hash::Algorithm::Sha1));
+ }
+
if (config.build_package_options.use_head_version == UseHeadVersion::YES)
abi_tag_entries.emplace_back("head", "");
@@ -740,12 +725,13 @@ namespace vcpkg::Build
if (Debug::g_debugging)
{
- System::print2("[DEBUG] <abientries>\n");
+ std::string message = "[DEBUG] <abientries>\n";
for (auto&& entry : abi_tag_entries)
{
- System::print2("[DEBUG] ", entry.key, "|", entry.value, "\n");
+ Strings::append(message, "[DEBUG] ", entry.key, "|", entry.value, "\n");
}
- System::print2("[DEBUG] </abientries>\n");
+ Strings::append(message, "[DEBUG] </abientries>\n");
+ System::print2(message);
}
auto abi_tag_entries_missing = abi_tag_entries;
@@ -827,33 +813,27 @@ namespace vcpkg::Build
const Triplet& triplet = config.triplet;
const std::string& name = config.scf.core_paragraph->name;
- std::vector<FeatureSpec> required_fspecs = compute_required_feature_specs(config, status_db);
-
- // extract out the actual package ids
- auto dep_pspecs = Util::fmap(required_fspecs, [](FeatureSpec const& fspec) { return fspec.spec(); });
- Util::sort_unique_erase(dep_pspecs);
-
- // Find all features that aren't installed. This mutates required_fspecs.
- // Skip this validation when running in Download Mode.
- if (config.build_package_options.only_downloads != Build::OnlyDownloads::YES)
+ std::vector<FeatureSpec> missing_fspecs;
+ for (const auto& kv : config.feature_dependencies)
{
- Util::erase_remove_if(required_fspecs, [&](FeatureSpec const& fspec) {
- return status_db.is_installed(fspec) || fspec.name() == name;
- });
-
- if (!required_fspecs.empty())
+ for (const FeatureSpec& spec : kv.second)
{
- return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)};
+ if (!(status_db.is_installed(spec) || spec.name() == name))
+ {
+ missing_fspecs.emplace_back(spec);
+ }
}
}
- const PackageSpec spec =
- PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO);
+ if (!missing_fspecs.empty())
+ {
+ return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_fspecs)};
+ }
- std::vector<AbiEntry> dependency_abis;
+ const PackageSpec spec = PackageSpec::from_name_and_triplet(name, triplet).value_or_exit(VCPKG_LINE_INFO);
- // dep_pspecs was not destroyed
- for (auto&& pspec : dep_pspecs)
+ std::vector<AbiEntry> dependency_abis;
+ for (auto&& pspec : config.package_dependencies)
{
if (pspec == spec || Util::Enum::to_bool(config.build_package_options.only_downloads))
{
@@ -865,7 +845,9 @@ namespace vcpkg::Build
AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi});
}
- const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet, config.scfl);
+ const std::unordered_map<std::string, std::string>& cmake_vars =
+ config.var_provider.get_tag_vars(spec).value_or_exit(VCPKG_LINE_INFO);
+ const PreBuildInfo pre_build_info(paths, triplet, cmake_vars);
auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis);
if (!maybe_abi_tag_and_file)
@@ -895,12 +877,22 @@ namespace vcpkg::Build
if (archive_result != 0)
{
System::print2("Failed to decompress archive package\n");
- return BuildResult::BUILD_FAILED;
+ if (config.build_package_options.purge_decompress_failure == PurgeDecompressFailure::NO)
+ {
+ return BuildResult::BUILD_FAILED;
+ }
+ else
+ {
+ System::print2("Purging bad archive\n");
+ fs.remove(archive_path, ec);
+ }
+ }
+ else
+ {
+ auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec);
+ auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
+ return {BuildResult::SUCCEEDED, std::move(bcf)};
}
-
- auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec);
- auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
- return {BuildResult::SUCCEEDED, std::move(bcf)};
}
if (fs.exists(archive_tombstone_path))
@@ -1085,110 +1077,55 @@ namespace vcpkg::Build
return inner_create_buildinfo(*pghs.get());
}
- PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths,
- const Triplet& triplet,
- Optional<const SourceControlFileLocation&> port)
+ PreBuildInfo::PreBuildInfo(const VcpkgPaths& paths,
+ const Triplet& triplet,
+ const std::unordered_map<std::string, std::string>& cmakevars)
{
- static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb";
-
- const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE);
- const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake";
- const fs::path triplet_file_path = paths.get_triplet_file_path(triplet);
-
- std::vector<System::CMakeVariable> args{{"CMAKE_TRIPLET_FILE", triplet_file_path}};
-
- if (port)
+ for (auto&& kv : VCPKG_OPTIONS)
{
- const SourceControlFileLocation& scfl = port.value_or_exit(VCPKG_LINE_INFO);
-
- if (paths.get_filesystem().is_regular_file(scfl.source_location / "environment-overrides.cmake"))
+ auto find_itr = cmakevars.find(kv.first);
+ if (find_itr == cmakevars.end())
{
- args.emplace_back("VCPKG_ENV_OVERRIDES_FILE", scfl.source_location / "environment-overrides.cmake");
+ continue;
}
- }
-
- const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, ports_cmake_script_path, args);
-
- const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake);
- Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output);
-
- const std::vector<std::string> lines = Strings::split(ec_data.output, "\n");
-
- PreBuildInfo pre_build_info;
-
- pre_build_info.port = port;
-
- const auto e = lines.cend();
- auto cur = std::find(lines.cbegin(), e, FLAG_GUID);
- if (cur != e) ++cur;
-
- for (; cur != e; ++cur)
- {
- auto&& line = *cur;
- const std::vector<std::string> s = Strings::split(line, "=");
- Checks::check_exit(VCPKG_LINE_INFO,
- s.size() == 1 || s.size() == 2,
- "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]",
- line);
+ const std::string& variable_value = find_itr->second;
- const bool variable_with_no_value = s.size() == 1;
- const std::string variable_name = s.at(0);
- const std::string variable_value = variable_with_no_value ? "" : s.at(1);
-
- auto maybe_option = VCPKG_OPTIONS.find(variable_name);
- if (maybe_option != VCPKG_OPTIONS.end())
+ switch (kv.second)
{
- switch (maybe_option->second)
- {
- case VcpkgTripletVar::TARGET_ARCHITECTURE:
- pre_build_info.target_architecture = variable_value;
- break;
- case VcpkgTripletVar::CMAKE_SYSTEM_NAME: pre_build_info.cmake_system_name = variable_value; break;
- case VcpkgTripletVar::CMAKE_SYSTEM_VERSION:
- pre_build_info.cmake_system_version = variable_value;
- break;
- case VcpkgTripletVar::PLATFORM_TOOLSET:
- pre_build_info.platform_toolset =
- variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- case VcpkgTripletVar::VISUAL_STUDIO_PATH:
- pre_build_info.visual_studio_path =
- variable_value.empty() ? nullopt : Optional<fs::path>{variable_value};
- break;
- case VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE:
- pre_build_info.external_toolchain_file =
- variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- case VcpkgTripletVar::BUILD_TYPE:
- if (variable_value.empty())
- pre_build_info.build_type = nullopt;
- else if (Strings::case_insensitive_ascii_equals(variable_value, "debug"))
- pre_build_info.build_type = ConfigurationType::DEBUG;
- else if (Strings::case_insensitive_ascii_equals(variable_value, "release"))
- pre_build_info.build_type = ConfigurationType::RELEASE;
- else
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value);
- break;
- case VcpkgTripletVar::ENV_PASSTHROUGH:
- pre_build_info.passthrough_env_vars = Strings::split(variable_value, ";");
- break;
- case VcpkgTripletVar::PUBLIC_ABI_OVERRIDE:
- pre_build_info.public_abi_override =
- variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
- break;
- }
- }
- else
- {
- Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line);
+ case VcpkgTripletVar::TARGET_ARCHITECTURE: target_architecture = variable_value; break;
+ case VcpkgTripletVar::CMAKE_SYSTEM_NAME: cmake_system_name = variable_value; break;
+ case VcpkgTripletVar::CMAKE_SYSTEM_VERSION: cmake_system_version = variable_value; break;
+ case VcpkgTripletVar::PLATFORM_TOOLSET:
+ platform_toolset = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
+ break;
+ case VcpkgTripletVar::VISUAL_STUDIO_PATH:
+ visual_studio_path = variable_value.empty() ? nullopt : Optional<fs::path>{variable_value};
+ break;
+ case VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE:
+ external_toolchain_file = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
+ break;
+ case VcpkgTripletVar::BUILD_TYPE:
+ if (variable_value.empty())
+ build_type = nullopt;
+ else if (Strings::case_insensitive_ascii_equals(variable_value, "debug"))
+ build_type = ConfigurationType::DEBUG;
+ else if (Strings::case_insensitive_ascii_equals(variable_value, "release"))
+ build_type = ConfigurationType::RELEASE;
+ else
+ Checks::exit_with_message(
+ VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value);
+ break;
+ case VcpkgTripletVar::ENV_PASSTHROUGH:
+ passthrough_env_vars = Strings::split(variable_value, ";");
+ break;
+ case VcpkgTripletVar::PUBLIC_ABI_OVERRIDE:
+ public_abi_override = variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
+ break;
}
}
- pre_build_info.triplet_abi_tag = get_triplet_abi(paths, pre_build_info, triplet);
-
- return pre_build_info;
+ triplet_abi_tag = get_triplet_abi(paths, *this, triplet);
}
ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) {}
diff --git a/toolsrc/src/vcpkg/cmakevars.cpp b/toolsrc/src/vcpkg/cmakevars.cpp
new file mode 100644
index 000000000..6a9d26ec8
--- /dev/null
+++ b/toolsrc/src/vcpkg/cmakevars.cpp
@@ -0,0 +1,259 @@
+#include "pch.h"
+
+#include <vcpkg/base/optional.h>
+#include <vcpkg/base/span.h>
+#include <vcpkg/base/util.h>
+
+#include <vcpkg/cmakevars.h>
+
+using namespace vcpkg;
+using vcpkg::Optional;
+using vcpkg::CMakeVars::TripletCMakeVarProvider;
+
+namespace vcpkg::CMakeVars
+{
+ fs::path TripletCMakeVarProvider::create_tag_extraction_file(
+ const Span<const std::pair<const FullPackageSpec*, std::string>>& spec_abi_settings) const
+ {
+ Files::Filesystem& fs = paths.get_filesystem();
+ static int tag_extract_id = 0;
+
+ std::string extraction_file("include(" + get_tags_path.generic_u8string() + ")\n\n");
+
+ std::map<Triplet, int> emitted_triplets;
+ int emitted_triplet_id = 0;
+ for (const auto& spec_abi_setting : spec_abi_settings)
+ {
+ emitted_triplets[spec_abi_setting.first->package_spec.triplet()] = emitted_triplet_id++;
+ }
+ Strings::append(extraction_file, "macro(vcpkg_triplet_file VCPKG_TRIPLET_ID)\n");
+ for (auto& p : emitted_triplets)
+ {
+ Strings::append(extraction_file,
+ "if(VCPKG_TRIPLET_ID EQUAL ",
+ p.second,
+ ")\n",
+ fs.read_contents(paths.get_triplet_file_path(p.first), VCPKG_LINE_INFO),
+ "\nendif()\n");
+ }
+ Strings::append(extraction_file, "endmacro()\n");
+ for (const auto& spec_abi_setting : spec_abi_settings)
+ {
+ const FullPackageSpec& spec = *spec_abi_setting.first;
+
+ Strings::append(extraction_file,
+ "vcpkg_get_tags(\"",
+ spec.package_spec.name(),
+ "\" \"",
+ Strings::join(";", spec.features),
+ "\" \"",
+ emitted_triplets[spec.package_spec.triplet()],
+ "\" \"",
+ spec_abi_setting.second,
+ "\")\n");
+ }
+
+ fs::path path = paths.buildtrees / Strings::concat(tag_extract_id++, ".vcpkg_tags.cmake");
+
+ std::error_code ec;
+ fs.create_directories(paths.buildtrees, ec);
+ fs.write_contents(path, extraction_file, VCPKG_LINE_INFO);
+
+ return path;
+ }
+
+ fs::path TripletCMakeVarProvider::create_dep_info_extraction_file(const Span<const PackageSpec> specs) const
+ {
+ static int dep_info_id = 0;
+ Files::Filesystem& fs = paths.get_filesystem();
+
+ std::string extraction_file("include(" + get_dep_info_path.generic_u8string() + ")\n\n");
+
+ std::map<Triplet, int> emitted_triplets;
+ int emitted_triplet_id = 0;
+ for (const auto& spec : specs)
+ {
+ emitted_triplets[spec.triplet()] = emitted_triplet_id++;
+ }
+ Strings::append(extraction_file, "macro(vcpkg_triplet_file VCPKG_TRIPLET_ID)\n");
+ for (auto& p : emitted_triplets)
+ {
+ Strings::append(extraction_file,
+ "if(VCPKG_TRIPLET_ID EQUAL ",
+ p.second,
+ ")\n",
+ fs.read_contents(paths.get_triplet_file_path(p.first), VCPKG_LINE_INFO),
+ "\nendif()\n");
+ }
+ Strings::append(extraction_file, "endmacro()\n");
+
+ for (const PackageSpec& spec : specs)
+ {
+ Strings::append(
+ extraction_file, "vcpkg_get_dep_info(", spec.name(), " ", emitted_triplets[spec.triplet()], ")\n");
+ }
+
+ fs::path path = paths.buildtrees / Strings::concat(dep_info_id++, ".vcpkg_dep_info.cmake");
+
+ std::error_code ec;
+ fs.create_directories(paths.buildtrees, ec);
+ fs.write_contents(path, extraction_file, VCPKG_LINE_INFO);
+
+ return path;
+ }
+
+ void TripletCMakeVarProvider::launch_and_split(
+ const fs::path& script_path, std::vector<std::vector<std::pair<std::string, std::string>>>& vars) const
+ {
+ static constexpr CStringView PORT_START_GUID = "d8187afd-ea4a-4fc3-9aa4-a6782e1ed9af";
+ static constexpr CStringView PORT_END_GUID = "8c504940-be29-4cba-9f8f-6cd83e9d87b7";
+ static constexpr CStringView BLOCK_START_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb";
+ static constexpr CStringView BLOCK_END_GUID = "e1e74b5c-18cb-4474-a6bd-5c1c8bc81f3f";
+
+ const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, script_path, {});
+ const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake);
+ Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output);
+
+ const std::vector<std::string> lines = Strings::split(ec_data.output, "\n");
+
+ const auto end = lines.cend();
+
+ auto port_start = std::find(lines.cbegin(), end, PORT_START_GUID);
+ auto port_end = std::find(port_start, end, PORT_END_GUID);
+
+ for (auto var_itr = vars.begin(); port_start != end && var_itr != vars.end(); ++var_itr)
+ {
+ auto block_start = std::find(port_start, port_end, BLOCK_START_GUID);
+ auto block_end = std::find(++block_start, port_end, BLOCK_END_GUID);
+
+ while (block_start != port_end)
+ {
+ while (block_start != block_end)
+ {
+ const std::string& line = *block_start;
+
+ std::vector<std::string> s = Strings::split(line, "=");
+ Checks::check_exit(VCPKG_LINE_INFO,
+ s.size() == 1 || s.size() == 2,
+ "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]",
+ line);
+
+ var_itr->emplace_back(std::move(s[0]), s.size() == 1 ? "" : std::move(s[1]));
+
+ ++block_start;
+ }
+
+ block_start = std::find(block_end, port_end, BLOCK_START_GUID);
+ block_end = std::find(block_start, port_end, BLOCK_END_GUID);
+ }
+
+ port_start = std::find(port_end, end, PORT_START_GUID);
+ port_end = std::find(port_start, end, PORT_END_GUID);
+ }
+ }
+
+ void TripletCMakeVarProvider::load_generic_triplet_vars(const Triplet& triplet) const
+ {
+ std::vector<std::vector<std::pair<std::string, std::string>>> vars(1);
+ FullPackageSpec full_spec = FullPackageSpec::from_string("", triplet).value_or_exit(VCPKG_LINE_INFO);
+ const fs::path file_path =
+ create_tag_extraction_file(std::array<std::pair<const FullPackageSpec*, std::string>, 1>{
+ std::pair<const FullPackageSpec*, std::string>{&full_spec, ""}});
+ launch_and_split(file_path, vars);
+ paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
+
+ generic_triplet_vars[triplet].insert(std::make_move_iterator(vars.front().begin()),
+ std::make_move_iterator(vars.front().end()));
+ }
+
+ void TripletCMakeVarProvider::load_dep_info_vars(Span<const PackageSpec> specs) const
+ {
+ if (specs.size() == 0) return;
+ std::vector<std::vector<std::pair<std::string, std::string>>> vars(specs.size());
+ const fs::path file_path = create_dep_info_extraction_file(specs);
+ if (specs.size() > 100)
+ {
+ System::print2("Loading dependency information for ", specs.size(), " packages...\n");
+ }
+ launch_and_split(file_path, vars);
+ paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
+
+ auto var_list_itr = vars.begin();
+ for (const PackageSpec& spec : specs)
+ {
+ dep_resolution_vars.emplace(std::piecewise_construct,
+ std::forward_as_tuple(spec),
+ std::forward_as_tuple(std::make_move_iterator(var_list_itr->begin()),
+ std::make_move_iterator(var_list_itr->end())));
+ ++var_list_itr;
+ }
+ }
+
+ void TripletCMakeVarProvider::load_tag_vars(Span<const FullPackageSpec> specs,
+ const PortFileProvider::PortFileProvider& port_provider) const
+ {
+ if (specs.size() == 0) return;
+ std::vector<std::pair<const FullPackageSpec*, std::string>> spec_abi_settings;
+ spec_abi_settings.reserve(specs.size());
+
+ for (const FullPackageSpec& spec : specs)
+ {
+ auto& scfl = port_provider.get_control_file(spec.package_spec.name()).value_or_exit(VCPKG_LINE_INFO);
+ const fs::path override_path = scfl.source_location / "vcpkg-abi-settings.cmake";
+ spec_abi_settings.emplace_back(&spec, override_path.generic_u8string());
+ }
+
+ std::vector<std::vector<std::pair<std::string, std::string>>> vars(spec_abi_settings.size());
+ const fs::path file_path = create_tag_extraction_file(spec_abi_settings);
+ launch_and_split(file_path, vars);
+ paths.get_filesystem().remove(file_path, VCPKG_LINE_INFO);
+
+ auto var_list_itr = vars.begin();
+ for (const auto& spec_abi_setting : spec_abi_settings)
+ {
+ const FullPackageSpec& spec = *spec_abi_setting.first;
+
+ tag_vars.emplace(std::piecewise_construct,
+ std::forward_as_tuple(spec.package_spec),
+ std::forward_as_tuple(std::make_move_iterator(var_list_itr->begin()),
+ std::make_move_iterator(var_list_itr->end())));
+ ++var_list_itr;
+ }
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_generic_triplet_vars(
+ const Triplet& triplet) const
+ {
+ auto find_itr = generic_triplet_vars.find(triplet);
+ if (find_itr != generic_triplet_vars.end())
+ {
+ return find_itr->second;
+ }
+
+ return nullopt;
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_dep_info_vars(
+ const PackageSpec& spec) const
+ {
+ auto find_itr = dep_resolution_vars.find(spec);
+ if (find_itr != dep_resolution_vars.end())
+ {
+ return find_itr->second;
+ }
+
+ return nullopt;
+ }
+
+ Optional<const std::unordered_map<std::string, std::string>&> TripletCMakeVarProvider::get_tag_vars(
+ const PackageSpec& spec) const
+ {
+ auto find_itr = tag_vars.find(spec);
+ if (find_itr != tag_vars.end())
+ {
+ return find_itr->second;
+ }
+
+ return nullopt;
+ }
+}
diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp
index d4149ae6d..2857988ba 100644
--- a/toolsrc/src/vcpkg/commands.autocomplete.cpp
+++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp
@@ -159,7 +159,7 @@ namespace vcpkg::Commands::Autocomplete
{
const auto port_at_each_triplet =
combine_port_with_triplets(results[0], paths.get_available_triplets_names());
- Util::Vectors::concatenate(&results, port_at_each_triplet);
+ Util::Vectors::append(&results, port_at_each_triplet);
}
output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(results));
diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp
index 1c3c511c2..135ef132b 100644
--- a/toolsrc/src/vcpkg/commands.buildexternal.cpp
+++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include <vcpkg/build.h>
+#include <vcpkg/cmakevars.h>
#include <vcpkg/commands.h>
#include <vcpkg/help.h>
#include <vcpkg/input.h>
@@ -25,10 +26,13 @@ namespace vcpkg::Commands::BuildExternal
auto overlays = args.overlay_ports ? *args.overlay_ports : std::vector<std::string>();
overlays.insert(overlays.begin(), args.command_arguments.at(1));
- Dependencies::PathsPortFileProvider provider(paths, &overlays);
+
+ PortFileProvider::PathsPortFileProvider provider(paths, &overlays);
auto maybe_scfl = provider.get_control_file(spec.package_spec.name());
+
Checks::check_exit(
VCPKG_LINE_INFO, maybe_scfl.has_value(), "could not load control file for %s", spec.package_spec.name());
- Build::Command::perform_and_exit_ex(spec, maybe_scfl.value_or_exit(VCPKG_LINE_INFO), options, paths);
+
+ Build::Command::perform_and_exit_ex(spec, maybe_scfl.value_or_exit(VCPKG_LINE_INFO), provider, options, paths);
}
}
diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp
index 419d65f03..b8ac97563 100644
--- a/toolsrc/src/vcpkg/commands.ci.cpp
+++ b/toolsrc/src/vcpkg/commands.ci.cpp
@@ -13,8 +13,12 @@
#include <vcpkg/help.h>
#include <vcpkg/input.h>
#include <vcpkg/install.h>
+#include <vcpkg/logicexpression.h>
+#include <vcpkg/packagespec.h>
#include <vcpkg/vcpkglib.h>
+using namespace vcpkg;
+
namespace vcpkg::Commands::CI
{
using Build::BuildResult;
@@ -178,7 +182,7 @@ namespace vcpkg::Commands::CI
std::string feature_list;
for (const auto& feature : test.features)
{
- if (!feature_list.empty())
+ if (!feature_list.empty())
{
feature_list += ", ";
}
@@ -215,14 +219,44 @@ namespace vcpkg::Commands::CI
std::vector<FullPackageSpec> unknown;
std::map<PackageSpec, Build::BuildResult> known;
std::map<PackageSpec, std::vector<std::string>> features;
+ std::unordered_map<std::string, SourceControlFileLocation> default_feature_provider;
std::map<PackageSpec, std::string> abi_tag_map;
};
+ static bool supported_for_triplet(const CMakeVars::TripletCMakeVarProvider& var_provider,
+
+ const InstallPlanAction* install_plan)
+ {
+ const std::string& supports_expression =
+ install_plan->source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
+ .source_control_file->core_paragraph->supports_expression;
+ if (supports_expression.empty())
+ {
+ return true; // default to 'supported'
+ }
+
+ 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);
+ }
+ }
+
static std::unique_ptr<UnknownCIPortsResults> find_unknown_ports_for_ci(
const VcpkgPaths& paths,
const std::set<std::string>& exclusions,
- const Dependencies::PortFileProvider& provider,
- const std::vector<FeatureSpec>& fspecs,
+ const PortFileProvider::PortFileProvider& provider,
+ const CMakeVars::TripletCMakeVarProvider& var_provider,
+ const std::vector<FullPackageSpec>& specs,
const bool purge_tombstones)
{
auto ret = std::make_unique<UnknownCIPortsResults>();
@@ -243,101 +277,149 @@ namespace vcpkg::Commands::CI
Build::FailOnTombstone::YES,
};
- vcpkg::Cache<Triplet, Build::PreBuildInfo> pre_build_info_cache;
-
- auto action_plan = Dependencies::create_feature_install_plan(provider, fspecs, {}, {});
-
- auto timer = Chrono::ElapsedTimer::create_started();
-
- for (auto&& action : action_plan)
+ std::vector<PackageSpec> packages_with_qualified_deps;
+ auto has_qualifier = [](Dependency const& dep) { return !dep.qualifier.empty(); };
+ for (auto&& spec : specs)
{
- if (auto p = action.install_action.get())
+ 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) ||
+ Util::any_of(scfl.source_control_file->feature_paragraphs,
+ [&](auto&& pgh) { return Util::any_of(pgh->depends, has_qualifier); }))
{
- // determine abi tag
- std::string abi;
- if (auto scfl = p->source_control_file_location.get())
- {
- auto triplet = p->spec.triplet();
+ packages_with_qualified_deps.push_back(spec.package_spec);
+ }
+ }
+
+ var_provider.load_dep_info_vars(packages_with_qualified_deps);
+ auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, {}, {});
- const Build::BuildPackageConfig build_config{*scfl, triplet, build_options, p->feature_list};
+ std::vector<FullPackageSpec> install_specs;
+ for (auto&& install_action : action_plan.install_actions)
+ {
+ install_specs.emplace_back(FullPackageSpec{
+ install_action.spec,
+ std::vector<std::string>{install_action.feature_list.begin(), install_action.feature_list.end()}});
+ }
- auto dependency_abis =
- Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry {
- auto it = ret->abi_tag_map.find(spec);
+ var_provider.load_tag_vars(install_specs, provider);
- if (it == ret->abi_tag_map.end())
- return {spec.name(), ""};
- else
- return {spec.name(), it->second};
- });
- const auto& pre_build_info = pre_build_info_cache.get_lazy(
- triplet, [&]() { return Build::PreBuildInfo::from_triplet_file(paths, triplet, *scfl); });
+ auto timer = Chrono::ElapsedTimer::create_started();
- auto maybe_tag_and_file =
- Build::compute_abi_tag(paths, build_config, pre_build_info, dependency_abis);
- if (auto tag_and_file = maybe_tag_and_file.get())
- {
- abi = tag_and_file->tag;
- ret->abi_tag_map.emplace(p->spec, abi);
- }
- }
- else if (auto ipv = p->installed_package.get())
+ Checks::check_exit(VCPKG_LINE_INFO,
+ action_plan.already_installed.empty(),
+ "Cannot use CI command with packages already installed.");
+ std::string stdout_buffer;
+ for (auto&& action : action_plan.install_actions)
+ {
+ auto p = &action;
+ // determine abi tag
+ std::string abi;
+ if (auto scfl = p->source_control_file_location.get())
+ {
+ auto emp = ret->default_feature_provider.emplace(p->spec.name(), *scfl);
+ emp.first->second.source_control_file->core_paragraph->default_features = p->feature_list;
+
+ auto triplet = p->spec.triplet();
+
+ const Build::BuildPackageConfig build_config{*scfl,
+ triplet,
+ build_options,
+ var_provider,
+ p->feature_dependencies,
+ p->package_dependencies,
+ p->feature_list};
+
+ auto dependency_abis =
+ Util::fmap(build_config.package_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry {
+ auto it = ret->abi_tag_map.find(spec);
+
+ if (it == ret->abi_tag_map.end())
+ return {spec.name(), ""};
+ else
+ return {spec.name(), it->second};
+ });
+
+ const auto pre_build_info = Build::PreBuildInfo(
+ paths, triplet, var_provider.get_tag_vars(p->spec).value_or_exit(VCPKG_LINE_INFO));
+
+ auto maybe_tag_and_file = Build::compute_abi_tag(paths, build_config, pre_build_info, dependency_abis);
+ if (auto tag_and_file = maybe_tag_and_file.get())
{
- abi = ipv->core->package.abi;
- if (!abi.empty()) ret->abi_tag_map.emplace(p->spec, abi);
+ abi = tag_and_file->tag;
+ ret->abi_tag_map.emplace(p->spec, abi);
}
+ }
+ else if (auto ipv = p->installed_package.get())
+ {
+ abi = ipv->core->package.abi;
+ if (!abi.empty()) ret->abi_tag_map.emplace(p->spec, abi);
+ }
- std::string state;
-
- auto archives_root_dir = paths.root / "archives";
- auto archive_name = abi + ".zip";
- auto archive_subpath = fs::u8path(abi.substr(0, 2)) / archive_name;
- auto archive_path = archives_root_dir / archive_subpath;
- auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath;
+ auto archives_root_dir = paths.root / "archives";
+ auto archive_name = abi + ".zip";
+ auto archive_subpath = fs::u8path(abi.substr(0, 2)) / archive_name;
+ auto archive_path = archives_root_dir / archive_subpath;
+ auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath;
- if (purge_tombstones)
- {
- std::error_code ec;
- fs.remove(archive_tombstone_path, ec); // Ignore error
- }
+ if (purge_tombstones)
+ {
+ std::error_code ec;
+ fs.remove(archive_tombstone_path, ec); // Ignore error
+ }
- bool b_will_build = false;
+ bool b_will_build = false;
- ret->features.emplace(p->spec,
- std::vector<std::string>{p->feature_list.begin(), p->feature_list.end()});
+ std::string state;
- if (Util::Sets::contains(exclusions, p->spec.name()))
- {
- ret->known.emplace(p->spec, BuildResult::EXCLUDED);
- will_fail.emplace(p->spec);
- }
- else if (std::any_of(p->computed_dependencies.begin(),
- p->computed_dependencies.end(),
- [&](const PackageSpec& spec) { return Util::Sets::contains(will_fail, spec); }))
- {
- ret->known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES);
- will_fail.emplace(p->spec);
- }
- else if (fs.exists(archive_path))
- {
- state += "pass";
- ret->known.emplace(p->spec, BuildResult::SUCCEEDED);
- }
- else if (fs.exists(archive_tombstone_path))
- {
- state += "fail";
- ret->known.emplace(p->spec, BuildResult::BUILD_FAILED);
- will_fail.emplace(p->spec);
- }
- else
- {
- ret->unknown.push_back({p->spec, {p->feature_list.begin(), p->feature_list.end()}});
- b_will_build = true;
- }
+ if (Util::Sets::contains(exclusions, p->spec.name()))
+ {
+ state = "skip";
+ ret->known.emplace(p->spec, BuildResult::EXCLUDED);
+ will_fail.emplace(p->spec);
+ }
+ else if (!supported_for_triplet(var_provider, p))
+ {
+ // This treats unsupported ports as if they are excluded
+ // which means the ports dependent on it will be cascaded due to missing dependencies
+ // Should this be changed so instead it is a failure to depend on a unsupported port?
+ state = "n/a";
+ ret->known.emplace(p->spec, BuildResult::EXCLUDED);
+ will_fail.emplace(p->spec);
+ }
+ else if (Util::any_of(p->package_dependencies,
+ [&](const PackageSpec& spec) { return Util::Sets::contains(will_fail, spec); }))
+ {
+ state = "cascade";
+ ret->known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES);
+ will_fail.emplace(p->spec);
+ }
+ else if (fs.exists(archive_path))
+ {
+ state = "pass";
+ ret->known.emplace(p->spec, BuildResult::SUCCEEDED);
+ }
+ else if (fs.exists(archive_tombstone_path))
+ {
+ state = "fail";
+ ret->known.emplace(p->spec, BuildResult::BUILD_FAILED);
+ will_fail.emplace(p->spec);
+ }
+ else
+ {
+ ret->unknown.push_back(FullPackageSpec{p->spec, {p->feature_list.begin(), p->feature_list.end()}});
+ b_will_build = true;
+ }
- System::printf("%40s: %1s %8s: %s\n", p->spec, (b_will_build ? "*" : " "), state, abi);
+ Strings::append(stdout_buffer,
+ Strings::format("%40s: %1s %8s: %s\n", p->spec, (b_will_build ? "*" : " "), state, abi));
+ if (stdout_buffer.size() > 2048)
+ {
+ System::print2(stdout_buffer);
+ stdout_buffer.clear();
}
}
+ System::print2(stdout_buffer);
+ stdout_buffer.clear();
System::printf("Time to determine pass/fail: %s\n", timer.elapsed());
@@ -374,7 +456,8 @@ namespace vcpkg::Commands::CI
StatusParagraphs status_db = database_load_check(paths);
- Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
const Build::BuildPackageOptions install_plan_options = {
Build::UseHeadVersion::NO,
@@ -386,6 +469,7 @@ namespace vcpkg::Commands::CI
Build::DownloadTool::BUILT_IN,
GlobalState::g_binary_caching ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::YES,
+ Build::PurgeDecompressFailure::YES,
};
std::vector<std::map<PackageSpec, BuildResult>> all_known_results;
@@ -394,7 +478,7 @@ namespace vcpkg::Commands::CI
XunitTestResults xunitTestResults;
std::vector<std::string> all_ports =
- Util::fmap(provider.load_all_control_files(), [](auto&& scfl) -> std::string {
+ Util::fmap(provider.load_all_control_files(), [](const SourceControlFileLocation*& scfl) -> std::string {
return scfl->source_control_file.get()->core_paragraph->name;
});
std::vector<TripletAndSummary> results;
@@ -405,17 +489,18 @@ namespace vcpkg::Commands::CI
xunitTestResults.push_collection(triplet.canonical_name());
- Dependencies::PackageGraph pgraph(provider, status_db);
-
std::vector<PackageSpec> specs = PackageSpec::to_package_specs(all_ports, triplet);
// Install the default features for every package
- auto all_feature_specs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); });
- auto split_specs =
- find_unknown_ports_for_ci(paths, exclusions_set, provider, all_feature_specs, purge_tombstones);
- auto feature_specs = FullPackageSpec::to_feature_specs(split_specs->unknown);
+ auto all_default_full_specs = Util::fmap(specs, [&](auto& spec) {
+ std::vector<std::string> default_features =
+ provider.get_control_file(spec.name()).get()->source_control_file->core_paragraph->default_features;
+ default_features.emplace_back("core");
+ return FullPackageSpec{spec, std::move(default_features)};
+ });
- for (auto&& fspec : feature_specs)
- pgraph.install(fspec);
+ auto split_specs = find_unknown_ports_for_ci(
+ paths, exclusions_set, provider, var_provider, all_default_full_specs, purge_tombstones);
+ PortFileProvider::MapPortFileProvider new_default_provider(split_specs->default_feature_provider);
Dependencies::CreateInstallPlanOptions serialize_options;
@@ -436,36 +521,20 @@ namespace vcpkg::Commands::CI
serialize_options.randomizer = &randomizer_instance;
}
- auto action_plan = [&]() {
- int iterations = 0;
- do
- {
- bool inconsistent = false;
- auto action_plan = pgraph.serialize(serialize_options);
-
- for (auto&& action : action_plan)
- {
- if (auto p = action.install_action.get())
- {
- p->build_options = install_plan_options;
- if (Util::Sets::contains(exclusions_set, p->spec.name()))
- {
- p->plan_type = InstallPlanType::EXCLUDED;
- }
-
- for (auto&& feature : split_specs->features[p->spec])
- if (p->feature_list.find(feature) == p->feature_list.end())
- {
- pgraph.install({p->spec, feature});
- inconsistent = true;
- }
- }
- }
+ auto action_plan = Dependencies::create_feature_install_plan(
+ new_default_provider, var_provider, split_specs->unknown, status_db, serialize_options);
- if (!inconsistent) return action_plan;
- Checks::check_exit(VCPKG_LINE_INFO, ++iterations < 100);
- } while (true);
- }();
+ for (auto&& action : action_plan.install_actions)
+ {
+ if (Util::Sets::contains(exclusions_set, action.spec.name()))
+ {
+ action.plan_type = InstallPlanType::EXCLUDED;
+ }
+ else
+ {
+ action.build_options = install_plan_options;
+ }
+ }
if (is_dry_run)
{
@@ -474,7 +543,7 @@ namespace vcpkg::Commands::CI
else
{
auto collection_timer = Chrono::ElapsedTimer::create_started();
- auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db);
+ auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db, var_provider);
auto collection_time_elapsed = collection_timer.elapsed();
// Adding results for ports that were built or pulled from an archive
diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp
index 79cbba590..eecc45634 100644
--- a/toolsrc/src/vcpkg/commands.dependinfo.cpp
+++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp
@@ -11,10 +11,9 @@
#include <vcpkg/packagespec.h>
#include <vector>
-using vcpkg::Dependencies::AnyAction;
-using vcpkg::Dependencies::create_feature_install_plan;
+using vcpkg::Dependencies::ActionPlan;
using vcpkg::Dependencies::InstallPlanAction;
-using vcpkg::Dependencies::PathsPortFileProvider;
+using vcpkg::PortFileProvider::PathsPortFileProvider;
namespace vcpkg::Commands::DependInfo
{
@@ -44,7 +43,7 @@ namespace vcpkg::Commands::DependInfo
{
std::string package;
int depth;
- std::set<std::string> features;
+ std::unordered_set<std::string> features;
std::vector<std::string> dependencies;
};
@@ -205,9 +204,10 @@ namespace vcpkg::Commands::DependInfo
const InstallPlanAction& install_action = *pia;
const std::vector<std::string> dependencies = Util::fmap(
- install_action.computed_dependencies, [](const PackageSpec& spec) { return spec.name(); });
+ install_action.package_dependencies, [](const PackageSpec& spec) { return spec.name(); });
- std::set<std::string> features{install_action.feature_list};
+ std::unordered_set<std::string> features{install_action.feature_list.begin(),
+ install_action.feature_list.end()};
features.erase("core");
std::string port_name = install_action.spec.name();
@@ -252,19 +252,18 @@ namespace vcpkg::Commands::DependInfo
}
PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
// By passing an empty status_db, we should get a plan containing all dependencies.
// All actions in the plan should be install actions, as there's no installed packages to remove.
StatusParagraphs status_db;
- std::vector<AnyAction> action_plan =
- create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db);
- std::vector<const InstallPlanAction*> install_actions = Util::fmap(action_plan, [&](const AnyAction& action) {
- if (auto install_action = action.install_action.get())
- {
- return install_action;
- }
- Checks::exit_with_message(VCPKG_LINE_INFO, "Only install actions should exist in the plan");
- });
+ auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, action_plan.remove_actions.empty(), "Only install actions should exist in the plan");
+ std::vector<const InstallPlanAction*> install_actions =
+ Util::fmap(action_plan.already_installed, [&](const auto& action) { return &action; });
+ for (auto&& action : action_plan.install_actions)
+ install_actions.push_back(&action);
std::vector<PackageDependInfo> depend_info = extract_depend_info(install_actions, max_depth);
diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp
index b81aeae55..c54f73e76 100644
--- a/toolsrc/src/vcpkg/commands.env.cpp
+++ b/toolsrc/src/vcpkg/commands.env.cpp
@@ -2,7 +2,9 @@
#include <vcpkg/base/strings.h>
#include <vcpkg/base/system.process.h>
+
#include <vcpkg/build.h>
+#include <vcpkg/cmakevars.h>
#include <vcpkg/commands.h>
#include <vcpkg/help.h>
@@ -30,13 +32,20 @@ namespace vcpkg::Commands::Env
nullptr,
};
+ // This command should probably optionally take a port
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& triplet)
{
const auto& fs = paths.get_filesystem();
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, triplet);
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
+
+ var_provider.load_generic_triplet_vars(triplet);
+
+ const Build::PreBuildInfo pre_build_info(
+ paths, triplet, var_provider.get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO));
const Toolset& toolset = paths.get_toolset(pre_build_info);
auto env_cmd = Build::make_build_env_cmd(pre_build_info, toolset);
diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp
index 943233502..372c394fa 100644
--- a/toolsrc/src/vcpkg/commands.search.cpp
+++ b/toolsrc/src/vcpkg/commands.search.cpp
@@ -9,7 +9,7 @@
#include <vcpkg/sourceparagraph.h>
#include <vcpkg/vcpkglib.h>
-using vcpkg::Dependencies::PathsPortFileProvider;
+using vcpkg::PortFileProvider::PathsPortFileProvider;
namespace vcpkg::Commands::Search
{
diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp
index b1dbf6194..e8afabed5 100644
--- a/toolsrc/src/vcpkg/commands.upgrade.cpp
+++ b/toolsrc/src/vcpkg/commands.upgrade.cpp
@@ -44,8 +44,8 @@ namespace vcpkg::Commands::Upgrade
StatusParagraphs status_db = database_load_check(paths);
// Load ports from ports dirs
- Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get());
- Dependencies::PackageGraph graph(provider, status_db);
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
// input sanitization
const std::vector<PackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
@@ -57,6 +57,7 @@ namespace vcpkg::Commands::Upgrade
Input::check_triplet(spec.triplet(), paths);
}
+ Dependencies::ActionPlan action_plan;
if (specs.empty())
{
// If no packages specified, upgrade all outdated packages.
@@ -68,8 +69,11 @@ namespace vcpkg::Commands::Upgrade
Checks::exit_success(VCPKG_LINE_INFO);
}
- for (auto&& outdated_package : outdated_packages)
- graph.upgrade(outdated_package.spec);
+ action_plan = Dependencies::create_upgrade_plan(
+ provider,
+ var_provider,
+ Util::fmap(outdated_packages, [](const Update::OutdatedPackage& package) { return package.spec; }),
+ status_db);
}
else
{
@@ -143,13 +147,10 @@ namespace vcpkg::Commands::Upgrade
if (to_upgrade.empty()) Checks::exit_success(VCPKG_LINE_INFO);
- for (auto&& spec : to_upgrade)
- graph.upgrade(spec);
+ action_plan = Dependencies::create_upgrade_plan(provider, var_provider, to_upgrade, status_db);
}
- auto plan = graph.serialize();
-
- Checks::check_exit(VCPKG_LINE_INFO, !plan.empty());
+ Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty());
const Build::BuildPackageOptions install_plan_options = {
Build::UseHeadVersion::NO,
@@ -164,15 +165,12 @@ namespace vcpkg::Commands::Upgrade
};
// Set build settings for all install actions
- for (auto&& action : plan)
+ for (auto&& action : action_plan.install_actions)
{
- if (auto p_install = action.install_action.get())
- {
- p_install->build_options = install_plan_options;
- }
+ action.build_options = install_plan_options;
}
- Dependencies::print_plan(plan, true, paths.ports);
+ Dependencies::print_plan(action_plan, true, paths.ports);
if (!no_dry_run)
{
@@ -182,7 +180,8 @@ namespace vcpkg::Commands::Upgrade
Checks::exit_fail(VCPKG_LINE_INFO);
}
- const Install::InstallSummary summary = Install::perform(plan, keep_going, paths, status_db);
+ const Install::InstallSummary summary =
+ Install::perform(action_plan, keep_going, paths, status_db, var_provider);
System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp
index 7c3f2df4c..a395b167f 100644
--- a/toolsrc/src/vcpkg/dependencies.cpp
+++ b/toolsrc/src/vcpkg/dependencies.cpp
@@ -7,25 +7,40 @@
#include <vcpkg/dependencies.h>
#include <vcpkg/packagespec.h>
#include <vcpkg/paragraphs.h>
+#include <vcpkg/portfileprovider.h>
#include <vcpkg/statusparagraphs.h>
#include <vcpkg/vcpkglib.h>
#include <vcpkg/vcpkgpaths.h>
+using namespace vcpkg;
+
namespace vcpkg::Dependencies
{
namespace
{
struct ClusterInstalled
{
+ ClusterInstalled(const InstalledPackageView& ipv) : ipv(ipv)
+ {
+ original_features.emplace("core");
+ for (auto&& feature : ipv.features)
+ {
+ original_features.emplace(feature->package.feature);
+ }
+ }
+
InstalledPackageView ipv;
- std::set<PackageSpec> remove_edges;
- std::set<std::string> original_features;
+ std::unordered_set<PackageSpec> remove_edges;
+ std::unordered_set<std::string> original_features;
+
+ // Tracks whether an incoming request has asked for the default features -- on reinstall, add them
+ bool defaults_requested = false;
};
- struct ClusterSource
+ struct ClusterInstallInfo
{
- const SourceControlFileLocation* scfl = nullptr;
std::unordered_map<std::string, std::vector<FeatureSpec>> build_edges;
+ bool defaults_requested = false;
};
/// <summary>
@@ -33,56 +48,189 @@ namespace vcpkg::Dependencies
/// </summary>
struct Cluster : Util::MoveOnlyBase
{
- PackageSpec spec;
+ Cluster(const InstalledPackageView& ipv, const SourceControlFileLocation& scfl)
+ : m_spec(ipv.spec()), m_scfl(scfl), m_installed(ipv)
+ {
+ }
+
+ Cluster(const PackageSpec& spec, const SourceControlFileLocation& scfl) : m_spec(spec), m_scfl(scfl) {}
+
+ bool has_feature_installed(const std::string& feature) const
+ {
+ if (const ClusterInstalled* inst = m_installed.get())
+ {
+ return inst->original_features.find(feature) != inst->original_features.end();
+ }
+ return false;
+ }
+
+ bool has_defaults_installed() const
+ {
+ if (const ClusterInstalled* inst = m_installed.get())
+ {
+ return std::all_of(inst->ipv.core->package.default_features.begin(),
+ inst->ipv.core->package.default_features.end(),
+ [&](const std::string& feature) {
+ return inst->original_features.find(feature) !=
+ inst->original_features.end();
+ });
+ }
+ return false;
+ }
+
+ // Returns dependencies which were added as a result of this call.
+ // Precondition: must have called "mark_for_reinstall()" or "create_install_info()" on this cluster
+ void add_feature(const std::string& feature,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ std::vector<FeatureSpec>& out_new_dependencies)
+ {
+ ClusterInstallInfo& info = m_install_info.value_or_exit(VCPKG_LINE_INFO);
+ if (feature == "default")
+ {
+ if (!info.defaults_requested)
+ {
+ info.defaults_requested = true;
+ for (auto&& f : m_scfl.source_control_file->core_paragraph->default_features)
+ out_new_dependencies.emplace_back(m_spec, f);
+ }
+ return;
+ }
+
+ if (Util::Sets::contains(info.build_edges, feature))
+ {
+ // This feature has already been completely handled
+ return;
+ }
+ auto maybe_vars = var_provider.get_dep_info_vars(m_spec);
+ const std::vector<Dependency>* qualified_deps =
+ &m_scfl.source_control_file->find_dependencies_for_feature(feature).value_or_exit(VCPKG_LINE_INFO);
+
+ std::vector<FeatureSpec> dep_list;
+ if (maybe_vars)
+ {
+ // Qualified dependency resolution is available
+ auto fullspec_list = filter_dependencies(
+ *qualified_deps, m_spec.triplet(), maybe_vars.value_or_exit(VCPKG_LINE_INFO));
+
+ for (auto&& fspec : fullspec_list)
+ {
+ // TODO: this is incorrect and does not handle default features nor "*"
+ Util::Vectors::append(&dep_list, fspec.to_feature_specs({"default"}, {}));
+ }
+
+ Util::sort_unique_erase(dep_list);
+ info.build_edges.emplace(feature, dep_list);
+ }
+ else
+ {
+ bool requires_qualified_resolution = false;
+ for (const Dependency& dep : *qualified_deps)
+ {
+ if (dep.qualifier.empty())
+ {
+ Util::Vectors::append(
+ &dep_list,
+ FullPackageSpec(PackageSpec::from_name_and_triplet(dep.depend.name, m_spec.triplet())
+ .value_or_exit(VCPKG_LINE_INFO),
+ dep.depend.features)
+ .to_feature_specs({"default"}, {}));
+ }
+ else
+ {
+ requires_qualified_resolution = true;
+ }
+ }
+ Util::sort_unique_erase(dep_list);
+ if (!requires_qualified_resolution)
+ {
+ info.build_edges.emplace(feature, dep_list);
+ }
+ }
+ Util::Vectors::append(&out_new_dependencies, dep_list);
+ }
+
+ void create_install_info(std::vector<FeatureSpec>& out_reinstall_requirements)
+ {
+ bool defaults_requested = false;
+ if (const ClusterInstalled* inst = m_installed.get())
+ {
+ for (const std::string& installed_feature : inst->original_features)
+ {
+ out_reinstall_requirements.emplace_back(m_spec, installed_feature);
+ }
+ defaults_requested = inst->defaults_requested;
+ }
+
+ Checks::check_exit(VCPKG_LINE_INFO, !m_install_info.has_value());
+ m_install_info = make_optional(ClusterInstallInfo{});
+
+ if (defaults_requested)
+ {
+ for (auto&& def_feature : m_scfl.source_control_file->core_paragraph->default_features)
+ out_reinstall_requirements.emplace_back(m_spec, def_feature);
+ }
+ else if (request_type != RequestType::USER_REQUESTED)
+ {
+ // If the user did not explicitly request this installation, we need to add all new default features
+ auto&& new_defaults = m_scfl.source_control_file->core_paragraph->default_features;
+ std::set<std::string> defaults_set{new_defaults.begin(), new_defaults.end()};
+
+ // Install only features that were not previously available
+ if (auto p_inst = m_installed.get())
+ {
+ for (auto&& prev_default : p_inst->ipv.core->package.default_features)
+ {
+ defaults_set.erase(prev_default);
+ }
+ }
+
+ for (const std::string& feature : defaults_set)
+ {
+ // Instead of dealing with adding default features to each of our dependencies right
+ // away we just defer to the next pass of the loop.
+ out_reinstall_requirements.emplace_back(m_spec, feature);
+ }
+ }
+ }
+
+ PackageSpec m_spec;
+ const SourceControlFileLocation& m_scfl;
- Optional<ClusterInstalled> installed;
- Optional<ClusterSource> source;
+ Optional<ClusterInstalled> m_installed;
+ Optional<ClusterInstallInfo> m_install_info;
- // Note: this map can contain "special" strings such as "" and "*"
- std::unordered_map<std::string, bool> plus;
- std::set<std::string> to_install_features;
- bool minus = false;
- bool transient_uninstalled = true;
RequestType request_type = RequestType::AUTO_SELECTED;
};
- struct ClusterPtr
+ struct PackageGraph
{
- Cluster* ptr;
+ PackageGraph(const PortFileProvider::PortFileProvider& provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const StatusParagraphs& status_db);
+ ~PackageGraph();
- Cluster* operator->() const { return ptr; }
- };
+ void install(Span<const FeatureSpec> specs);
+ void upgrade(Span<const PackageSpec> specs);
+ void mark_user_requested(const PackageSpec& spec);
- bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; }
- }
-}
+ ActionPlan serialize(const CreateInstallPlanOptions& options = {}) const;
-namespace std
-{
- template<>
- struct hash<vcpkg::Dependencies::ClusterPtr>
- {
- size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const
- {
- return std::hash<vcpkg::PackageSpec>()(value.ptr->spec);
- }
- };
-}
+ void mark_for_reinstall(const PackageSpec& spec, std::vector<FeatureSpec>& out_reinstall_requirements);
+ const CMakeVars::CMakeVarProvider& m_var_provider;
-namespace vcpkg::Dependencies
-{
- struct GraphPlan
- {
- Graphs::Graph<ClusterPtr> remove_graph;
- Graphs::Graph<ClusterPtr> install_graph;
- };
+ std::unique_ptr<ClusterGraph> m_graph;
+ };
+
+ }
/// <summary>
/// Directional graph representing a collection of packages with their features connected by their dependencies.
/// </summary>
struct ClusterGraph : Util::MoveOnlyBase
{
- explicit ClusterGraph(const PortFileProvider& provider) : m_provider(provider) {}
+ explicit ClusterGraph(const PortFileProvider::PortFileProvider& port_provider) : m_port_provider(port_provider)
+ {
+ }
/// <summary>
/// Find the cluster associated with spec or if not found, create it from the PortFileProvider.
@@ -94,35 +242,64 @@ namespace vcpkg::Dependencies
auto it = m_graph.find(spec);
if (it == m_graph.end())
{
- // Load on-demand from m_provider
- auto maybe_scfl = m_provider.get_control_file(spec.name());
- auto& clust = m_graph[spec];
- clust.spec = spec;
- if (auto p_scfl = maybe_scfl.get())
- {
- clust.source = cluster_from_scf(*p_scfl, clust.spec.triplet());
- }
- return clust;
+ const SourceControlFileLocation* scfl = m_port_provider.get_control_file(spec.name()).get();
+
+ Checks::check_exit(
+ VCPKG_LINE_INFO, scfl, "Error: Cannot find definition for package `%s`.", spec.name());
+
+ return m_graph
+ .emplace(std::piecewise_construct, std::forward_as_tuple(spec), std::forward_as_tuple(spec, *scfl))
+ .first->second;
}
+
return it->second;
}
- private:
- static ClusterSource cluster_from_scf(const SourceControlFileLocation& scfl, Triplet t)
+ Cluster& get(const InstalledPackageView& ipv)
{
- ClusterSource ret;
- ret.build_edges.emplace("core",
- filter_dependencies_to_specs(scfl.source_control_file->core_paragraph->depends, t));
+ auto it = m_graph.find(ipv.spec());
+
+ if (it == m_graph.end())
+ {
+ Optional<const SourceControlFileLocation&> maybe_scfl =
+ m_port_provider.get_control_file(ipv.spec().name());
+
+ if (!maybe_scfl)
+ Checks::exit_with_message(VCPKG_LINE_INFO,
+ "We could not find a CONTROL file for ",
+ ipv.spec().to_string(),
+ ". Please run \"vcpkg remove ",
+ ipv.spec().to_string(),
+ "\" and re-attempt.");
+
+ return m_graph
+ .emplace(std::piecewise_construct,
+ std::forward_as_tuple(ipv.spec()),
+ std::forward_as_tuple(ipv, *maybe_scfl.get()))
+ .first->second;
+ }
+
+ if (!it->second.m_installed)
+ {
+ it->second.m_installed = {ipv};
+ }
- for (const auto& feature : scfl.source_control_file->feature_paragraphs)
- ret.build_edges.emplace(feature->name, filter_dependencies_to_specs(feature->depends, t));
+ return it->second;
+ }
- ret.scfl = &scfl;
- return ret;
+ const Cluster& find_or_exit(const PackageSpec& spec, LineInfo linfo) const
+ {
+ auto it = m_graph.find(spec);
+ Checks::check_exit(linfo, it != m_graph.end(), "Failed to locate spec in graph");
+ return it->second;
}
+ auto begin() const { return m_graph.begin(); }
+ auto end() const { return m_graph.end(); }
+
+ private:
std::unordered_map<PackageSpec, Cluster> m_graph;
- const PortFileProvider& m_provider;
+ const PortFileProvider::PortFileProvider& m_port_provider;
};
static std::string to_output_string(RequestType request_type,
@@ -178,30 +355,44 @@ namespace vcpkg::Dependencies
InstallPlanAction::InstallPlanAction(const PackageSpec& spec,
const SourceControlFileLocation& scfl,
- const std::set<std::string>& features,
const RequestType& request_type,
- std::vector<PackageSpec>&& dependencies)
+ std::unordered_map<std::string, std::vector<FeatureSpec>>&& dependencies)
: spec(spec)
, source_control_file_location(scfl)
, plan_type(InstallPlanType::BUILD_AND_INSTALL)
, request_type(request_type)
, build_options{}
- , feature_list(features)
- , computed_dependencies(std::move(dependencies))
+ , feature_dependencies(std::move(dependencies))
{
+ for (const auto& kv : feature_dependencies)
+ {
+ feature_list.emplace_back(kv.first);
+ for (const FeatureSpec& fspec : kv.second)
+ {
+ if (spec != fspec.spec())
+ {
+ package_dependencies.emplace_back(fspec.spec());
+ }
+ }
+ }
+
+ Util::sort_unique_erase(package_dependencies);
+ Util::sort_unique_erase(feature_list);
}
- InstallPlanAction::InstallPlanAction(InstalledPackageView&& ipv,
- const std::set<std::string>& features,
- const RequestType& request_type)
+ InstallPlanAction::InstallPlanAction(InstalledPackageView&& ipv, const RequestType& request_type)
: spec(ipv.spec())
, installed_package(std::move(ipv))
, plan_type(InstallPlanType::ALREADY_INSTALLED)
, request_type(request_type)
, build_options{}
- , feature_list(features)
- , computed_dependencies(installed_package.get()->dependencies())
+ , feature_dependencies(installed_package.get()->feature_dependencies())
+ , package_dependencies(installed_package.get()->dependencies())
{
+ for (const auto& kv : feature_dependencies)
+ {
+ feature_list.emplace_back(kv.first);
+ }
}
std::string InstallPlanAction::displayname() const
@@ -211,7 +402,7 @@ namespace vcpkg::Dependencies
return this->spec.to_string();
}
- const std::string features = Strings::join(",", this->feature_list);
+ const std::string features = Strings::join(",", feature_list);
return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet());
}
@@ -232,21 +423,6 @@ namespace vcpkg::Dependencies
{
}
- const PackageSpec& AnyAction::spec() const
- {
- if (const auto p = install_action.get())
- {
- return p->spec;
- }
-
- if (const auto p = remove_action.get())
- {
- return p->spec;
- }
-
- Checks::exit_with_message(VCPKG_LINE_INFO, "Null action");
- }
-
bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right)
{
return left->spec.name() < right->spec.name();
@@ -294,145 +470,6 @@ namespace vcpkg::Dependencies
return left->spec.name() < right->spec.name();
}
- MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map)
- : ports(map)
- {
- }
-
- Optional<const SourceControlFileLocation&> MapPortFileProvider::get_control_file(const std::string& spec) const
- {
- auto scf = ports.find(spec);
- if (scf == ports.end()) return nullopt;
- return scf->second;
- }
-
- std::vector<const SourceControlFileLocation*> MapPortFileProvider::load_all_control_files() const
- {
- return Util::fmap(ports, [](auto&& kvpair) -> const SourceControlFileLocation* { return &kvpair.second; });
- }
-
- PathsPortFileProvider::PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
- const std::vector<std::string>* ports_dirs_paths)
- : filesystem(paths.get_filesystem())
- {
- auto& fs = Files::get_real_filesystem();
- if (ports_dirs_paths)
- {
- for (auto&& overlay_path : *ports_dirs_paths)
- {
- if (!overlay_path.empty())
- {
- auto overlay = fs::stdfs::canonical(fs::u8path(overlay_path));
-
- 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);
- }
-
- Optional<const SourceControlFileLocation&> PathsPortFileProvider::get_control_file(const std::string& spec) const
- {
- auto cache_it = cache.find(spec);
- if (cache_it != cache.end())
- {
- return cache_it->second;
- }
-
- for (auto&& ports_dir : ports_dirs)
- {
- // Try loading individual port
- if (filesystem.exists(ports_dir / "CONTROL"))
- {
- auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir);
- if (auto scf = maybe_scf.get())
- {
- if (scf->get()->core_paragraph->name == spec)
- {
- SourceControlFileLocation scfl{std::move(*scf), ports_dir};
- auto it = cache.emplace(spec, std::move(scfl));
- return it.first->second;
- }
- }
- else
- {
- vcpkg::print_error_message(maybe_scf.error());
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Error: Failed to load port from %s", spec, ports_dir.u8string());
- }
- }
-
- auto found_scf = Paragraphs::try_load_port(filesystem, ports_dir / spec);
- if (auto scf = found_scf.get())
- {
- if (scf->get()->core_paragraph->name == spec)
- {
- SourceControlFileLocation scfl{std::move(*scf), ports_dir / spec};
- auto it = cache.emplace(spec, std::move(scfl));
- return it.first->second;
- }
- }
- }
-
- return nullopt;
- }
-
- std::vector<const SourceControlFileLocation*> PathsPortFileProvider::load_all_control_files() const
- {
- // Reload cache with ports contained in all ports_dirs
- cache.clear();
- std::vector<const SourceControlFileLocation*> ret;
- for (auto&& ports_dir : ports_dirs)
- {
- // Try loading individual port
- if (filesystem.exists(ports_dir / "CONTROL"))
- {
- auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir);
- if (auto scf = maybe_scf.get())
- {
- auto port_name = scf->get()->core_paragraph->name;
- if (cache.find(port_name) == cache.end())
- {
- SourceControlFileLocation scfl{std::move(*scf), ports_dir};
- auto it = cache.emplace(port_name, std::move(scfl));
- ret.emplace_back(&it.first->second);
- }
- }
- else
- {
- vcpkg::print_error_message(maybe_scf.error());
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Error: Failed to load port from %s", ports_dir.u8string());
- }
- continue;
- }
-
- // Try loading all ports inside ports_dir
- auto found_scf = Paragraphs::load_all_ports(filesystem, ports_dir);
- for (auto&& scf : found_scf)
- {
- auto port_name = scf->core_paragraph->name;
- if (cache.find(port_name) == cache.end())
- {
- SourceControlFileLocation scfl{std::move(scf), ports_dir / port_name};
- auto it = cache.emplace(port_name, std::move(scfl));
- ret.emplace_back(&it.first->second);
- }
- }
- }
- return ret;
- }
-
std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs,
const StatusParagraphs& status_db)
{
@@ -488,7 +525,8 @@ namespace vcpkg::Dependencies
auto installed_ports = get_installed_ports(status_db);
const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
- return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}, {});
+ return Graphs::topological_sort(
+ std::move(specs), RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}, {});
}
std::vector<ExportPlanAction> create_export_plan(const std::vector<PackageSpec>& specs,
@@ -534,362 +572,333 @@ namespace vcpkg::Dependencies
return toposort;
}
- enum class MarkPlusResult
+ void PackageGraph::mark_user_requested(const PackageSpec& spec)
{
- FEATURE_NOT_FOUND,
- SUCCESS,
- };
+ m_graph->get(spec).request_type = RequestType::USER_REQUESTED;
+ }
- static MarkPlusResult mark_plus(const std::string& feature,
- Cluster& cluster,
- ClusterGraph& graph,
- GraphPlan& graph_plan,
- const std::unordered_set<std::string>& prevent_default_features);
-
- static void mark_minus(Cluster& cluster,
- ClusterGraph& graph,
- GraphPlan& graph_plan,
- const std::unordered_set<std::string>& prevent_default_features);
-
- static MarkPlusResult follow_plus_dependencies(const std::string& feature,
- Cluster& cluster,
- ClusterGraph& graph,
- GraphPlan& graph_plan,
- const std::unordered_set<std::string>& prevent_default_features)
+ ActionPlan create_feature_install_plan(const PortFileProvider::PortFileProvider& port_provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector<FullPackageSpec>& specs,
+ const StatusParagraphs& status_db,
+ const CreateInstallPlanOptions& options)
{
- if (auto p_source = cluster.source.get())
- {
- auto it_build_edges = p_source->build_edges.find(feature);
- if (it_build_edges != p_source->build_edges.end())
- {
- // mark this package for rebuilding if needed
- mark_minus(cluster, graph, graph_plan, prevent_default_features);
+ PackageGraph pgraph(port_provider, var_provider, status_db);
- graph_plan.install_graph.add_vertex({&cluster});
- cluster.to_install_features.insert(feature);
-
- if (feature != "core")
- {
- // All features implicitly depend on core
- auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features);
-
- // Should be impossible for "core" to not exist
- Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS);
- }
-
- if (!cluster.installed.get() && !Util::Sets::contains(prevent_default_features, cluster.spec.name()))
- {
- // Add the default features of this package if it was not previously installed and it isn't being
- // suppressed.
- auto res = mark_plus("", cluster, graph, graph_plan, prevent_default_features);
-
- Checks::check_exit(VCPKG_LINE_INFO,
- res == MarkPlusResult::SUCCESS,
- "Error: Unable to satisfy default dependencies of %s",
- cluster.spec);
- }
+ std::vector<FeatureSpec> feature_specs;
+ for (const FullPackageSpec& spec : specs)
+ {
+ const SourceControlFileLocation* scfl = port_provider.get_control_file(spec.package_spec.name()).get();
- for (auto&& depend : it_build_edges->second)
- {
- auto& depend_cluster = graph.get(depend.spec());
- auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan, prevent_default_features);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, scfl, "Error: Cannot find definition for package `%s`.", spec.package_spec.name());
- Checks::check_exit(VCPKG_LINE_INFO,
- res == MarkPlusResult::SUCCESS,
- "Error: Unable to satisfy dependency %s of %s",
- depend,
- FeatureSpec(cluster.spec, feature));
+ const std::vector<std::string> all_features =
+ Util::fmap(scfl->source_control_file->feature_paragraphs,
+ [](auto&& feature_paragraph) { return feature_paragraph->name; });
- if (&depend_cluster == &cluster) continue;
- graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster});
- }
+ auto fspecs =
+ spec.to_feature_specs(scfl->source_control_file->core_paragraph->default_features, all_features);
+ feature_specs.insert(
+ feature_specs.end(), std::make_move_iterator(fspecs.begin()), std::make_move_iterator(fspecs.end()));
+ }
+ Util::sort_unique_erase(feature_specs);
- return MarkPlusResult::SUCCESS;
- }
+ for (const FeatureSpec& spec : feature_specs)
+ {
+ pgraph.mark_user_requested(spec.spec());
}
+ pgraph.install(feature_specs);
- // The feature was not available in the installed package nor the source paragraph.
- return MarkPlusResult::FEATURE_NOT_FOUND;
+ return pgraph.serialize(options);
}
- MarkPlusResult mark_plus(const std::string& feature,
- Cluster& cluster,
- ClusterGraph& graph,
- GraphPlan& graph_plan,
- const std::unordered_set<std::string>& prevent_default_features)
+ void PackageGraph::mark_for_reinstall(const PackageSpec& first_remove_spec,
+ std::vector<FeatureSpec>& out_reinstall_requirements)
{
- auto& plus = cluster.plus[feature];
- if (plus) return MarkPlusResult::SUCCESS;
- plus = true;
+ std::set<PackageSpec> removed;
+ std::vector<PackageSpec> to_remove{first_remove_spec};
- const auto p_source = cluster.source.get();
- if (p_source == nullptr)
+ while (!to_remove.empty())
{
- Checks::exit_with_message(
- VCPKG_LINE_INFO, "Error: Cannot find definition for package `%s`.", cluster.spec.name());
- }
+ PackageSpec remove_spec = std::move(to_remove.back());
+ to_remove.pop_back();
- auto&& control_file = *p_source->scfl->source_control_file.get();
- if (feature.empty())
- {
- // Add default features for this package. This is an exact reference, so ignore prevent_default_features.
- for (auto&& default_feature : control_file.core_paragraph.get()->default_features)
- {
- auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features);
- if (res != MarkPlusResult::SUCCESS)
- {
- return res;
- }
- }
+ if (!removed.insert(remove_spec).second) continue;
- // "core" is always required.
- return mark_plus("core", cluster, graph, graph_plan, prevent_default_features);
- }
+ Cluster& clust = m_graph->get(remove_spec);
+ ClusterInstalled& info = clust.m_installed.value_or_exit(VCPKG_LINE_INFO);
- if (feature == "*")
- {
- for (auto&& fpgh : control_file.feature_paragraphs)
+ if (!clust.m_install_info)
{
- auto res = mark_plus(fpgh->name, cluster, graph, graph_plan, prevent_default_features);
-
- Checks::check_exit(VCPKG_LINE_INFO,
- res == MarkPlusResult::SUCCESS,
- "Error: Internal error while installing feature %s in %s",
- fpgh->name,
- cluster.spec);
+ clust.create_install_info(out_reinstall_requirements);
}
- auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features);
-
- Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS);
- return MarkPlusResult::SUCCESS;
+ to_remove.insert(to_remove.end(), info.remove_edges.begin(), info.remove_edges.end());
}
-
- if (auto p_installed = cluster.installed.get())
- {
- if (p_installed->original_features.find(feature) != p_installed->original_features.end())
- {
- return MarkPlusResult::SUCCESS;
- }
- }
-
- // The feature was not previously installed. Mark the cluster
- // (aka the entire port) to be removed before re-adding it.
- mark_minus(cluster, graph, graph_plan, prevent_default_features);
-
- return follow_plus_dependencies(feature, cluster, graph, graph_plan, prevent_default_features);
}
- void mark_minus(Cluster& cluster,
- ClusterGraph& graph,
- GraphPlan& graph_plan,
- const std::unordered_set<std::string>& prevent_default_features)
+ /// The list of specs to install should already have default features expanded
+ void PackageGraph::install(Span<const FeatureSpec> specs)
{
- if (cluster.minus) return;
- cluster.minus = true;
- cluster.transient_uninstalled = true;
-
- auto p_installed = cluster.installed.get();
- auto p_source = cluster.source.get();
-
- Checks::check_exit(
- VCPKG_LINE_INFO,
- p_source,
- "Error: cannot locate new portfile for %s. Please explicitly remove this package with `vcpkg remove %s`.",
- cluster.spec,
- cluster.spec);
+ // We batch resolving qualified dependencies, because it's an invocation of CMake which
+ // takes ~150ms per call.
+ std::vector<FeatureSpec> qualified_dependencies;
+ std::vector<FeatureSpec> next_dependencies{specs.begin(), specs.end()};
- if (p_installed)
+ // Keep running while there is any chance of finding more dependencies
+ while (!next_dependencies.empty())
{
- graph_plan.remove_graph.add_vertex({&cluster});
- for (auto&& edge : p_installed->remove_edges)
+ // Keep running until the only dependencies left are qualified
+ while (!next_dependencies.empty())
{
- auto& depend_cluster = graph.get(edge);
- Checks::check_exit(VCPKG_LINE_INFO, &cluster != &depend_cluster);
- graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster});
- mark_minus(depend_cluster, graph, graph_plan, prevent_default_features);
- }
+ // Extract the top of the stack
+ FeatureSpec spec = std::move(next_dependencies.back());
+ next_dependencies.pop_back();
- // Reinstall all original features. Don't use mark_plus because it will ignore them since they are
- // "already installed".
- for (auto&& f : p_installed->original_features)
- {
- auto res = follow_plus_dependencies(f, cluster, graph, graph_plan, prevent_default_features);
- if (res != MarkPlusResult::SUCCESS)
+ // Get the cluster for the PackageSpec of the FeatureSpec we are adding to the install graph
+ Cluster& clust = m_graph->get(spec.spec());
+
+ // If this spec hasn't already had its qualified dependencies resolved
+ if (!m_var_provider.get_dep_info_vars(spec.spec()).has_value())
{
- System::print2(System::Color::warning,
- "Warning: could not reinstall feature ",
- FeatureSpec{cluster.spec, f},
- "\n");
+ // TODO: There's always the chance that we don't find the feature we're looking for (probably a
+ // malformed CONTROL file somewhere). We should probably output a better error.
+ const std::vector<Dependency>* paragraph_depends = nullptr;
+ if (spec.feature() == "core")
+ {
+ paragraph_depends = &clust.m_scfl.source_control_file->core_paragraph->depends;
+ }
+ else if (spec.feature() == "default")
+ {
+ }
+ else
+ {
+ auto maybe_paragraph = clust.m_scfl.source_control_file->find_feature(spec.feature());
+ Checks::check_exit(VCPKG_LINE_INFO,
+ maybe_paragraph.has_value(),
+ "Package %s does not have a %s feature",
+ spec.name(),
+ spec.feature());
+ paragraph_depends = &maybe_paragraph.value_or_exit(VCPKG_LINE_INFO).depends;
+ }
+
+ // And it has at least one qualified dependency
+ if (paragraph_depends && Util::any_of(*paragraph_depends,
+ [](auto&& dep) { return !dep.qualifier.empty(); }))
+ {
+ // Add it to the next batch run
+ qualified_dependencies.emplace_back(spec);
+ }
}
- }
- // Check if any default features have been added
- auto& previous_df = p_installed->ipv.core->package.default_features;
- auto&& control_file = *p_source->scfl->source_control_file.get();
- for (auto&& default_feature : control_file.core_paragraph->default_features)
- {
- if (std::find(previous_df.begin(), previous_df.end(), default_feature) == previous_df.end())
+ if (clust.m_install_info.has_value())
{
- // This is a new default feature, mark it for installation
- auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features);
- if (res != MarkPlusResult::SUCCESS)
+ clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ }
+ else
+ {
+ if (!clust.m_installed.has_value())
+ {
+ clust.create_install_info(next_dependencies);
+ clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ }
+ else
{
- System::print2(System::Color::warning,
- "Warning: could not install new default feature ",
- FeatureSpec{cluster.spec, default_feature},
- "\n");
+ if (spec.feature() == "default")
+ {
+ if (!clust.m_installed.get()->defaults_requested)
+ {
+ clust.m_installed.get()->defaults_requested = true;
+ if (!clust.has_defaults_installed())
+ {
+ mark_for_reinstall(spec.spec(), next_dependencies);
+ }
+ }
+ }
+ else if (!clust.has_feature_installed(spec.feature()))
+ {
+ // If install_info is not present and it is already installed, we have never added a feature
+ // which hasn't already been installed to this cluster. In this case, we need to reinstall
+ // the port if the feature isn't already present.
+ mark_for_reinstall(spec.spec(), next_dependencies);
+ clust.add_feature(spec.feature(), m_var_provider, next_dependencies);
+ }
}
}
}
+
+ if (!qualified_dependencies.empty())
+ {
+ Util::sort_unique_erase(qualified_dependencies);
+
+ // Extract the package specs we need to get dependency info from. We don't run the triplet on a per
+ // feature basis. We run it once for the whole port.
+ auto qualified_package_specs =
+ Util::fmap(qualified_dependencies, [](const FeatureSpec& fspec) { return fspec.spec(); });
+ Util::sort_unique_erase(qualified_package_specs);
+ m_var_provider.load_dep_info_vars(qualified_package_specs);
+
+ // Put all the FeatureSpecs for which we had qualified dependencies back on the dependencies stack.
+ // We need to recheck if evaluating the triplet revealed any new dependencies.
+ next_dependencies.insert(next_dependencies.end(),
+ std::make_move_iterator(qualified_dependencies.begin()),
+ std::make_move_iterator(qualified_dependencies.end()));
+ qualified_dependencies.clear();
+ }
}
}
- std::vector<AnyAction> create_feature_install_plan(const PortFileProvider& provider,
- const std::vector<FeatureSpec>& specs,
- const StatusParagraphs& status_db,
- const CreateInstallPlanOptions& options)
+ void PackageGraph::upgrade(Span<const PackageSpec> specs)
{
- std::unordered_set<std::string> prevent_default_features;
- for (auto&& spec : specs)
- {
- // When "core" is explicitly listed, default features should not be installed.
- if (spec.feature() == "core") prevent_default_features.insert(spec.name());
- }
+ std::vector<FeatureSpec> reinstall_reqs;
- PackageGraph pgraph(provider, status_db);
- for (auto&& spec : specs)
- {
- // If preventing default features, ignore the automatically generated "" references
- if (spec.feature().empty() && Util::Sets::contains(prevent_default_features, spec.name())) continue;
- pgraph.install(spec, prevent_default_features);
- }
+ for (const PackageSpec& spec : specs)
+ mark_for_reinstall(spec, reinstall_reqs);
- return pgraph.serialize(options);
+ Util::sort_unique_erase(reinstall_reqs);
+
+ install(reinstall_reqs);
}
- /// <summary>Figure out which actions are required to install features specifications in `specs`.</summary>
- /// <param name="map">Map of all source control files in the current environment.</param>
- /// <param name="specs">Feature specifications to resolve dependencies for.</param>
- /// <param name="status_db">Status of installed packages in the current environment.</param>
- std::vector<AnyAction> create_feature_install_plan(
- const std::unordered_map<std::string, SourceControlFileLocation>& map,
- const std::vector<FeatureSpec>& specs,
- const StatusParagraphs& status_db)
+ ActionPlan create_upgrade_plan(const PortFileProvider::PortFileProvider& port_provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const std::vector<PackageSpec>& specs,
+ const StatusParagraphs& status_db,
+ const CreateInstallPlanOptions& options)
{
- MapPortFileProvider provider(map);
- return create_feature_install_plan(provider, specs, status_db);
+ PackageGraph pgraph(port_provider, var_provider, status_db);
+
+ pgraph.upgrade(specs);
+
+ return pgraph.serialize(options);
}
- /// <param name="prevent_default_features">
- /// List of package names for which default features should not be installed instead of the core package (e.g. if
- /// the user is currently installing specific features of that package).
- /// </param>
- void PackageGraph::install(const FeatureSpec& spec,
- const std::unordered_set<std::string>& prevent_default_features) const
+ ActionPlan PackageGraph::serialize(const CreateInstallPlanOptions& options) const
{
- Cluster& spec_cluster = m_graph->get(spec.spec());
- spec_cluster.request_type = RequestType::USER_REQUESTED;
+ struct BaseEdgeProvider : Graphs::AdjacencyProvider<PackageSpec, const Cluster*>
+ {
+ BaseEdgeProvider(const ClusterGraph& parent) : m_parent(parent) {}
- auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan, prevent_default_features);
+ std::string to_string(const PackageSpec& spec) const override { return spec.to_string(); }
+ const Cluster* load_vertex_data(const PackageSpec& spec) const override
+ {
+ return &m_parent.find_or_exit(spec, VCPKG_LINE_INFO);
+ }
- Checks::check_exit(VCPKG_LINE_INFO,
- res == MarkPlusResult::SUCCESS,
- "Error: `%s` is not a feature of package `%s`",
- spec.feature(),
- spec.name());
+ const ClusterGraph& m_parent;
+ };
- m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster});
- }
+ struct RemoveEdgeProvider final : BaseEdgeProvider
+ {
+ using BaseEdgeProvider::BaseEdgeProvider;
- void PackageGraph::upgrade(const PackageSpec& spec) const
- {
- Cluster& spec_cluster = m_graph->get(spec);
- spec_cluster.request_type = RequestType::USER_REQUESTED;
+ std::vector<PackageSpec> adjacency_list(const Cluster* const& vertex) const override
+ {
+ auto&& set = vertex->m_installed.value_or_exit(VCPKG_LINE_INFO).remove_edges;
+ return {set.begin(), set.end()};
+ }
+ } removeedgeprovider(*m_graph);
- mark_minus(spec_cluster, *m_graph, *m_graph_plan, {});
- }
+ struct InstallEdgeProvider final : BaseEdgeProvider
+ {
+ using BaseEdgeProvider::BaseEdgeProvider;
- std::vector<AnyAction> PackageGraph::serialize(const CreateInstallPlanOptions& options) const
- {
- auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list();
- auto remove_toposort =
- Graphs::topological_sort(remove_vertex_list, m_graph_plan->remove_graph, options.randomizer);
+ std::vector<PackageSpec> adjacency_list(const Cluster* const& vertex) const override
+ {
+ if (!vertex->m_install_info.has_value()) return {};
- auto insert_vertex_list = m_graph_plan->install_graph.vertex_list();
- auto insert_toposort =
- Graphs::topological_sort(insert_vertex_list, m_graph_plan->install_graph, options.randomizer);
+ auto& info = vertex->m_install_info.value_or_exit(VCPKG_LINE_INFO);
+ std::vector<PackageSpec> deps;
+ for (auto&& kv : info.build_edges)
+ for (auto&& e : kv.second)
+ {
+ auto spec = e.spec();
+ if (spec != vertex->m_spec) deps.push_back(std::move(spec));
+ }
+ Util::sort_unique_erase(deps);
+ return deps;
+ }
+ } installedgeprovider(*m_graph);
- std::vector<AnyAction> plan;
+ std::vector<PackageSpec> removed_vertices;
+ std::vector<PackageSpec> installed_vertices;
+ for (auto&& kv : *m_graph)
+ {
+ if (kv.second.m_install_info.has_value() && kv.second.m_installed.has_value())
+ {
+ removed_vertices.push_back(kv.first);
+ }
+ if (kv.second.m_install_info.has_value() || kv.second.request_type == RequestType::USER_REQUESTED)
+ {
+ installed_vertices.push_back(kv.first);
+ }
+ }
+ auto remove_toposort = Graphs::topological_sort(removed_vertices, removeedgeprovider, options.randomizer);
+ auto insert_toposort = Graphs::topological_sort(installed_vertices, installedgeprovider, options.randomizer);
+
+ ActionPlan plan;
for (auto&& p_cluster : remove_toposort)
{
- plan.emplace_back(RemovePlanAction{
- std::move(p_cluster->spec),
- RemovePlanType::REMOVE,
- p_cluster->request_type,
- });
+ plan.remove_actions.emplace_back(p_cluster->m_spec, RemovePlanType::REMOVE, p_cluster->request_type);
}
for (auto&& p_cluster : insert_toposort)
{
- if (p_cluster->transient_uninstalled)
+ // Every cluster that has an install_info needs to be built
+ // If a cluster only has an installed object and is marked as user requested we should still report it.
+ if (auto info_ptr = p_cluster->m_install_info.get())
{
- // If it will be transiently uninstalled, we need to issue a full installation command
- auto* pscfl = p_cluster->source.value_or_exit(VCPKG_LINE_INFO).scfl;
- Checks::check_exit(
- VCPKG_LINE_INFO, pscfl != nullptr, "Error: Expected a SourceControlFileLocation to exist");
- auto&& scfl = *pscfl;
-
- auto dep_specs = Util::fmap(m_graph_plan->install_graph.adjacency_list(p_cluster),
- [](ClusterPtr const& p) { return p->spec; });
- Util::sort_unique_erase(dep_specs);
-
- plan.emplace_back(InstallPlanAction{
- p_cluster->spec,
- scfl,
- p_cluster->to_install_features,
- p_cluster->request_type,
- std::move(dep_specs),
- });
+ auto&& scfl = p_cluster->m_scfl;
+
+ std::unordered_map<std::string, std::vector<FeatureSpec>> computed_edges;
+ for (auto&& kv : info_ptr->build_edges)
+ {
+ std::set<FeatureSpec> fspecs;
+ for (auto&& fspec : kv.second)
+ {
+ if (fspec.feature() != "default")
+ {
+ fspecs.insert(fspec);
+ continue;
+ }
+ auto&& dep_clust = m_graph->get(fspec.spec());
+ const auto& default_features =
+ [&]{
+ if (dep_clust.m_install_info.has_value()) return dep_clust.m_scfl.source_control_file->core_paragraph->default_features;
+ if (auto p = dep_clust.m_installed.get()) return p->ipv.core->package.default_features;
+ Checks::unreachable(VCPKG_LINE_INFO);
+ }();
+ for (auto&& default_feature : default_features)
+ fspecs.emplace(fspec.spec(), default_feature);
+ }
+ computed_edges[kv.first].assign(fspecs.begin(), fspecs.end());
+ }
+
+ plan.install_actions.emplace_back(
+ p_cluster->m_spec, scfl, p_cluster->request_type, std::move(computed_edges));
}
- else
+ else if (p_cluster->request_type == RequestType::USER_REQUESTED && p_cluster->m_installed.has_value())
{
- // If the package isn't transitively installed, still include it if the user explicitly requested it
- if (p_cluster->request_type != RequestType::USER_REQUESTED) continue;
- auto&& installed = p_cluster->installed.value_or_exit(VCPKG_LINE_INFO);
- plan.emplace_back(InstallPlanAction{
- InstalledPackageView{installed.ipv},
- installed.original_features,
- p_cluster->request_type,
- });
+ auto&& installed = p_cluster->m_installed.value_or_exit(VCPKG_LINE_INFO);
+ plan.already_installed.emplace_back(Util::copy(installed.ipv), p_cluster->request_type);
}
}
return plan;
}
- static std::unique_ptr<ClusterGraph> create_feature_install_graph(const PortFileProvider& map,
- const StatusParagraphs& status_db)
+ static std::unique_ptr<ClusterGraph> create_feature_install_graph(
+ const PortFileProvider::PortFileProvider& port_provider, const StatusParagraphs& status_db)
{
- std::unique_ptr<ClusterGraph> graph = std::make_unique<ClusterGraph>(map);
+ std::unique_ptr<ClusterGraph> graph = std::make_unique<ClusterGraph>(port_provider);
auto installed_ports = get_installed_ports(status_db);
for (auto&& ipv : installed_ports)
{
- Cluster& cluster = graph->get(ipv.spec());
-
- cluster.transient_uninstalled = false;
-
- cluster.installed = [](const InstalledPackageView& ipv) -> ClusterInstalled {
- ClusterInstalled ret;
- ret.ipv = ipv;
- ret.original_features.emplace("core");
- for (auto&& feature : ipv.features)
- ret.original_features.emplace(feature->package.feature);
- return ret;
- }(ipv);
+ graph->get(ipv);
}
// Populate the graph with "remove edges", which are the reverse of the Build-Depends edges.
@@ -899,7 +908,7 @@ namespace vcpkg::Dependencies
for (auto&& dep : deps)
{
- auto p_installed = graph->get(dep).installed.get();
+ auto p_installed = graph->get(dep).m_installed.get();
Checks::check_exit(VCPKG_LINE_INFO,
p_installed,
"Error: database corrupted. Package %s is installed but dependency %s is not.",
@@ -911,16 +920,16 @@ namespace vcpkg::Dependencies
return graph;
}
- PackageGraph::PackageGraph(const PortFileProvider& provider, const StatusParagraphs& status_db)
- : m_graph_plan(std::make_unique<GraphPlan>()), m_graph(create_feature_install_graph(provider, status_db))
+ PackageGraph::PackageGraph(const PortFileProvider::PortFileProvider& port_provider,
+ const CMakeVars::CMakeVarProvider& var_provider,
+ const StatusParagraphs& status_db)
+ : m_var_provider(var_provider), m_graph(create_feature_install_graph(port_provider, status_db))
{
}
PackageGraph::~PackageGraph() = default;
- void print_plan(const std::vector<AnyAction>& action_plan,
- const bool is_recursive,
- const fs::path& default_ports_dir)
+ void print_plan(const ActionPlan& action_plan, const bool is_recursive, const fs::path& default_ports_dir)
{
std::vector<const RemovePlanAction*> remove_plans;
std::vector<const InstallPlanAction*> rebuilt_plans;
@@ -929,44 +938,38 @@ namespace vcpkg::Dependencies
std::vector<const InstallPlanAction*> already_installed_plans;
std::vector<const InstallPlanAction*> excluded;
- const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool {
- if (auto iplan = package.install_action.get())
- return iplan->request_type != RequestType::USER_REQUESTED;
- else
- return false;
- }) != action_plan.cend();
+ const bool has_non_user_requested_packages =
+ Util::find_if(action_plan.install_actions, [](const InstallPlanAction& action) -> bool {
+ return action.request_type != RequestType::USER_REQUESTED;
+ }) != action_plan.install_actions.cend();
- for (auto&& action : action_plan)
+ for (auto&& remove_action : action_plan.remove_actions)
+ {
+ remove_plans.emplace_back(&remove_action);
+ }
+ for (auto&& install_action : action_plan.install_actions)
{
- if (auto install_action = action.install_action.get())
+ // remove plans are guaranteed to come before install plans, so we know the plan will be contained
+ // if at all.
+ auto it = Util::find_if(remove_plans,
+ [&](const RemovePlanAction* plan) { return plan->spec == install_action.spec; });
+ if (it != remove_plans.end())
{
- // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at
- // all.
- auto it = Util::find_if(
- remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; });
- if (it != remove_plans.end())
- {
- rebuilt_plans.emplace_back(install_action);
- }
- else
- {
- switch (install_action->plan_type)
- {
- case InstallPlanType::ALREADY_INSTALLED:
- if (install_action->request_type == RequestType::USER_REQUESTED)
- already_installed_plans.emplace_back(install_action);
- break;
- case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break;
- case InstallPlanType::EXCLUDED: excluded.emplace_back(install_action); break;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
+ rebuilt_plans.push_back(&install_action);
}
- else if (auto remove_action = action.remove_action.get())
+ else
{
- remove_plans.emplace_back(remove_action);
+ if (install_action.plan_type == InstallPlanType::EXCLUDED)
+ excluded.push_back(&install_action);
+ else
+ new_plans.push_back(&install_action);
}
}
+ for (auto&& action : action_plan.already_installed)
+ {
+ if (action.request_type == RequestType::USER_REQUESTED) already_installed_plans.emplace_back(&action);
+ }
+ already_installed_plans = Util::fmap(action_plan.already_installed, [](auto&& action) { return &action; });
std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name);
std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name);
diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp
index 34f9053ea..0094b712c 100644
--- a/toolsrc/src/vcpkg/export.cpp
+++ b/toolsrc/src/vcpkg/export.cpp
@@ -2,9 +2,9 @@
#include <vcpkg/commands.h>
#include <vcpkg/dependencies.h>
+#include <vcpkg/export.chocolatey.h>
#include <vcpkg/export.h>
#include <vcpkg/export.ifw.h>
-#include <vcpkg/export.chocolatey.h>
#include <vcpkg/help.h>
#include <vcpkg/input.h>
#include <vcpkg/install.h>
@@ -307,8 +307,10 @@ namespace vcpkg::Export
{OPTION_IFW_REPOSITORY_DIR_PATH, "Specify the directory path for the exported repository"},
{OPTION_IFW_CONFIG_FILE_PATH, "Specify the temporary file path for the installer configuration"},
{OPTION_IFW_INSTALLER_FILE_PATH, "Specify the file path for the exported installer"},
- {OPTION_CHOCOLATEY_MAINTAINER, "Specify the maintainer for the exported Chocolatey package (experimental feature)"},
- {OPTION_CHOCOLATEY_VERSION_SUFFIX, "Specify the version suffix to add for the exported Chocolatey package (experimental feature)"},
+ {OPTION_CHOCOLATEY_MAINTAINER,
+ "Specify the maintainer for the exported Chocolatey package (experimental feature)"},
+ {OPTION_CHOCOLATEY_VERSION_SUFFIX,
+ "Specify the version suffix to add for the exported Chocolatey package (experimental feature)"},
}};
const CommandStructure COMMAND_STRUCTURE = {
@@ -521,7 +523,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
const StatusParagraphs status_db = database_load_check(paths);
// Load ports from ports dirs
- Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(opts.specs, status_db);
Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty");
diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp
index a082f1b95..0af9a33a1 100644
--- a/toolsrc/src/vcpkg/install.cpp
+++ b/toolsrc/src/vcpkg/install.cpp
@@ -5,6 +5,7 @@
#include <vcpkg/base/system.print.h>
#include <vcpkg/base/util.h>
#include <vcpkg/build.h>
+#include <vcpkg/cmakevars.h>
#include <vcpkg/commands.h>
#include <vcpkg/dependencies.h>
#include <vcpkg/globalstate.h>
@@ -18,6 +19,7 @@
namespace vcpkg::Install
{
+ using namespace vcpkg;
using namespace Dependencies;
using file_pack = std::pair<std::string, std::string>;
@@ -295,8 +297,9 @@ namespace vcpkg::Install
using Build::ExtendedBuildResult;
ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths,
- const InstallPlanAction& action,
- StatusParagraphs& status_db)
+ InstallPlanAction& action,
+ StatusParagraphs& status_db,
+ const CMakeVars::CMakeVarProvider& var_provider)
{
const InstallPlanType& plan_type = action.plan_type;
const std::string display_name = action.spec.to_string();
@@ -338,8 +341,13 @@ namespace vcpkg::Install
auto result = [&]() -> Build::ExtendedBuildResult {
const auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
- const Build::BuildPackageConfig build_config{
- scfl, action.spec.triplet(), action.build_options, action.feature_list};
+ const Build::BuildPackageConfig build_config{scfl,
+ action.spec.triplet(),
+ action.build_options,
+ var_provider,
+ std::move(action.feature_dependencies),
+ std::move(action.package_dependencies),
+ std::move(action.feature_list)};
return Build::build_package(paths, build_config, status_db);
}();
@@ -422,53 +430,60 @@ namespace vcpkg::Install
}
}
- InstallSummary perform(const std::vector<AnyAction>& action_plan,
+ InstallSummary perform(ActionPlan& action_plan,
const KeepGoing keep_going,
const VcpkgPaths& paths,
- StatusParagraphs& status_db)
+ StatusParagraphs& status_db,
+ const CMakeVars::CMakeVarProvider& var_provider)
{
std::vector<SpecSummary> results;
const auto timer = Chrono::ElapsedTimer::create_started();
size_t counter = 0;
- const size_t package_count = action_plan.size();
+ const size_t package_count = action_plan.remove_actions.size() + action_plan.install_actions.size();
- for (const auto& action : action_plan)
- {
+ auto with_tracking = [&](const PackageSpec& spec, auto f) {
const auto build_timer = Chrono::ElapsedTimer::create_started();
counter++;
- const PackageSpec& spec = action.spec();
const std::string display_name = spec.to_string();
System::printf("Starting package %zd/%zd: %s\n", counter, package_count, display_name);
- results.emplace_back(spec, &action);
+ results.emplace_back(spec, nullptr);
- if (const auto install_action = action.install_action.get())
- {
- auto result = perform_install_plan_action(paths, *install_action, status_db);
+ f();
+
+ results.back().timing = build_timer.elapsed();
+ System::printf("Elapsed time for package %s: %s\n", display_name, results.back().timing);
+ };
+
+ for (auto&& action : action_plan.remove_actions)
+ {
+ with_tracking(action.spec,
+ [&]() { Remove::perform_remove_plan_action(paths, action, Remove::Purge::YES, &status_db); });
+ }
+
+ for (auto&& action : action_plan.already_installed)
+ {
+ results.emplace_back(action.spec, &action);
+ results.back().build_result = perform_install_plan_action(paths, action, status_db, var_provider);
+ }
+
+ for (auto&& action : action_plan.install_actions)
+ {
+ with_tracking(action.spec, [&]() {
+ auto result = perform_install_plan_action(paths, action, status_db, var_provider);
if (result.code != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO)
{
- System::print2(Build::create_user_troubleshooting_message(install_action->spec), '\n');
+ System::print2(Build::create_user_troubleshooting_message(action.spec), '\n');
Checks::exit_fail(VCPKG_LINE_INFO);
}
+ results.back().action = &action;
results.back().build_result = std::move(result);
- }
- else if (const auto remove_action = action.remove_action.get())
- {
- Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, &status_db);
- }
- else
- {
- Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- results.back().timing = build_timer.elapsed();
- System::printf("Elapsed time for package %s: %s\n", display_name, results.back().timing);
+ });
}
-
return InstallSummary{std::move(results), timer.to_string()};
}
@@ -514,7 +529,8 @@ namespace vcpkg::Install
static void print_cmake_information(const BinaryParagraph& bpgh, const VcpkgPaths& paths)
{
- static const std::regex cmake_library_regex(R"(\badd_library\(([^\s\)]+)\s)", std::regex_constants::ECMAScript);
+ static const std::regex cmake_library_regex(R"(\badd_library\(([^\$\s\)]+)\s)",
+ std::regex_constants::ECMAScript);
auto& fs = paths.get_filesystem();
@@ -651,6 +667,7 @@ 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;
@@ -669,33 +686,39 @@ namespace vcpkg::Install
};
//// Load ports from ports dirs
- PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ CMakeVars::TripletCMakeVarProvider var_provider(paths);
// Note: action_plan will hold raw pointers to SourceControlFileLocations from this map
- std::vector<AnyAction> action_plan =
- create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db);
+ auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
- for (auto&& action : action_plan)
+ std::vector<FullPackageSpec> install_package_specs;
+ for (auto&& action : action_plan.install_actions)
{
- if (auto p_install = action.install_action.get())
- {
- p_install->build_options = install_plan_options;
- if (p_install->request_type != RequestType::USER_REQUESTED)
- p_install->build_options.use_head_version = Build::UseHeadVersion::NO;
- }
+ action.build_options = install_plan_options;
+ if (action.request_type != RequestType::USER_REQUESTED)
+ action.build_options.use_head_version = Build::UseHeadVersion::NO;
+
+ install_package_specs.emplace_back(FullPackageSpec{action.spec, action.feature_list});
}
+ var_provider.load_tag_vars(install_package_specs, provider);
+
// install plan will be empty if it is already installed - need to change this at status paragraph part
Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty");
// log the plan
- const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) {
- if (auto iaction = action.install_action.get())
- return Hash::get_string_hash(iaction->spec.to_string(), Hash::Algorithm::Sha256);
- else if (auto raction = action.remove_action.get())
- return "R$" + Hash::get_string_hash(raction->spec.to_string(), Hash::Algorithm::Sha256);
- Checks::unreachable(VCPKG_LINE_INFO);
- });
+ std::string specs_string;
+ for (auto&& remove_action : action_plan.remove_actions)
+ {
+ if (!specs_string.empty()) specs_string += ",";
+ specs_string += "R$" + Hash::get_string_hash(remove_action.spec.to_string(), Hash::Algorithm::Sha256);
+ }
+ for (auto&& install_action : action_plan.install_actions)
+ {
+ if (!specs_string.empty()) specs_string += ",";
+ specs_string += Hash::get_string_hash(install_action.spec.to_string(), Hash::Algorithm::Sha256);
+ }
Metrics::g_metrics.lock()->track_property("installplan_1", specs_string);
@@ -706,7 +729,7 @@ namespace vcpkg::Install
Checks::exit_success(VCPKG_LINE_INFO);
}
- const InstallSummary summary = perform(action_plan, keep_going, paths, status_db);
+ const InstallSummary summary = perform(action_plan, keep_going, paths, status_db, var_provider);
System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");
@@ -729,19 +752,16 @@ namespace vcpkg::Install
for (auto&& result : summary.results)
{
if (!result.action) continue;
- if (auto p_install_action = result.action->install_action.get())
- {
- if (p_install_action->request_type != RequestType::USER_REQUESTED) continue;
- auto bpgh = result.get_binary_paragraph();
- if (!bpgh) continue;
- print_cmake_information(*bpgh, paths);
- }
+ if (result.action->request_type != RequestType::USER_REQUESTED) continue;
+ auto bpgh = result.get_binary_paragraph();
+ if (!bpgh) continue;
+ print_cmake_information(*bpgh, paths);
}
Checks::exit_success(VCPKG_LINE_INFO);
}
- SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::AnyAction* action)
+ SpecSummary::SpecSummary(const PackageSpec& spec, const Dependencies::InstallPlanAction* action)
: spec(spec), build_result{BuildResult::NULLVALUE, nullptr}, action(action)
{
}
@@ -750,12 +770,9 @@ namespace vcpkg::Install
{
if (build_result.binary_control_file) return &build_result.binary_control_file->core_paragraph;
if (action)
- if (auto p_install_plan = action->install_action.get())
+ if (auto p_status = action->installed_package.get())
{
- if (auto p_status = p_install_plan->installed_package.get())
- {
- return &p_status->core->package;
- }
+ return &p_status->core->package;
}
return nullptr;
}
diff --git a/toolsrc/src/vcpkg/logicexpression.cpp b/toolsrc/src/vcpkg/logicexpression.cpp
index ccb8b00c4..2f646e80a 100644
--- a/toolsrc/src/vcpkg/logicexpression.cpp
+++ b/toolsrc/src/vcpkg/logicexpression.cpp
@@ -1,7 +1,6 @@
-
#include "pch.h"
-#include <vcpkg/base/checks.h>
+#include <vcpkg/base/strings.h>
#include <vcpkg/base/system.print.h>
#include <vcpkg/logicexpression.h>
@@ -18,22 +17,37 @@ namespace vcpkg
const std::string line;
const std::string message;
- void print_error() const
+ std::string format_error() const
{
- System::print2(System::Color::error,
- "Error: ",
- message,
- "\n"
- " on expression: \"",
- line,
- "\"\n",
- " ",
- std::string(column, ' '),
- "^\n");
- Checks::exit_fail(VCPKG_LINE_INFO);
+ return Strings::concat("Error: ",
+ message,
+ "\n"
+ " on expression: \"",
+ line,
+ "\"\n",
+ " ",
+ std::string(column, ' '),
+ "^\n");
}
};
+ enum class Identifier
+ {
+ invalid, // not a recognized identifier
+ x64,
+ x86,
+ arm,
+ arm64,
+
+ windows,
+ linux,
+ osx,
+ uwp,
+ android,
+
+ static_link,
+ };
+
// logic expression supports the following :
// primary-expression:
// ( logic-expression )
@@ -53,12 +67,33 @@ namespace vcpkg
class ExpressionParser
{
public:
- ExpressionParser(const std::string& str, const std::string& evaluation_context)
+ ExpressionParser(const std::string& str, const ExpressionContext& context)
: raw_text(str)
- , evaluation_context(evaluation_context)
+ , evaluation_context(context)
, current_iter(raw_text.begin())
, current_char(get_current_char())
{
+ {
+ 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();
@@ -67,21 +102,18 @@ namespace vcpkg
{
add_error("Invalid logic expression");
}
-
- if (err)
- {
- err->print_error();
- final_result = false;
- }
}
bool get_result() const { return final_result; }
- bool has_error() const { return err == nullptr; }
+ const ParseError* get_error() const { return err.get(); }
private:
const std::string& raw_text;
- const std::string& evaluation_context;
+
+ const ExpressionContext& evaluation_context;
+ std::map<std::string, bool> context_override;
+
std::string::const_iterator current_iter;
char current_char;
@@ -143,9 +175,106 @@ namespace vcpkg
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '-');
}
- bool evaluate_identifier(const std::string name) const
+ // Legacy evaluation only searches for substrings. Use this only for diagnostic purposes.
+ bool evaluate_identifier_legacy(const std::string name) const
{
- return evaluation_context.find(name) != std::string::npos;
+ return evaluation_context.legacy_context.find(name) != std::string::npos;
+ }
+
+ static Identifier string2identifier(const std::string& name)
+ {
+ static const std::map<std::string, Identifier> 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},
+ {"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, int column)
+ {
+ 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.", column);
+ 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::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, int column)
+ {
+ 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, column);
+ 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: Identifier logic evaluation does not match legacy evaluation:\n ", name, '\n');
+ }
+ return cmake;
}
// identifier:
@@ -154,6 +283,7 @@ namespace vcpkg
{
auto curr = current();
std::string name;
+ auto starting_column = current_column();
for (curr = current(); is_alphanum(curr); curr = next())
{
@@ -166,7 +296,7 @@ namespace vcpkg
return false;
}
- bool result = evaluate_identifier(name);
+ bool result = evaluate_identifier(name, starting_column);
skip_whitespace();
return result;
}
@@ -194,6 +324,7 @@ namespace vcpkg
while (next() == oper)
{
};
+ skip_whitespace();
seed = operation(not_expression(), seed);
} while (current() == oper);
@@ -242,7 +373,7 @@ namespace vcpkg
bool result = logic_expression();
if (current() != ')')
{
- add_error("Error: missing closing )");
+ add_error("missing closing )");
return result;
}
next_skip_whitespace();
@@ -253,9 +384,14 @@ namespace vcpkg
}
};
- bool evaluate_expression(const std::string& expression, const std::string& evaluation_context)
+ ExpectedT<bool, std::string> evaluate_expression(const std::string& expression, const ExpressionContext& context)
{
- ExpressionParser parser(expression, evaluation_context);
+ ExpressionParser parser(expression, context);
+
+ if (auto err = parser.get_error())
+ {
+ return err->format_error();
+ }
return parser.get_result();
}
diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp
index 52edf4b6f..ea25f57e1 100644
--- a/toolsrc/src/vcpkg/packagespec.cpp
+++ b/toolsrc/src/vcpkg/packagespec.cpp
@@ -46,7 +46,7 @@ namespace vcpkg
for (auto&& feature : spec->features)
f_specs.push_back(FeatureSpec{pspec, feature});
- if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""});
+ if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, "core"});
}
else
{
@@ -59,16 +59,44 @@ namespace vcpkg
return f_specs;
}
- std::vector<FeatureSpec> FullPackageSpec::to_feature_specs(const std::vector<FullPackageSpec>& specs)
+ std::vector<FeatureSpec> FullPackageSpec::to_feature_specs(const std::vector<std::string>& default_features,
+ const std::vector<std::string>& all_features) const
{
- std::vector<FeatureSpec> ret;
- for (auto&& spec : specs)
+ std::vector<FeatureSpec> feature_specs;
+
+ if (Util::find(features, "*") != features.end())
{
- ret.emplace_back(spec.package_spec, "");
- for (auto&& feature : spec.features)
- ret.emplace_back(spec.package_spec, feature);
+ feature_specs.emplace_back(package_spec, "core");
+ for (const std::string& feature : all_features)
+ {
+ feature_specs.emplace_back(package_spec, feature);
+ }
}
- return ret;
+ else
+ {
+ bool core = false;
+ for (const std::string& feature : features)
+ {
+ feature_specs.emplace_back(package_spec, feature);
+
+ if (!core)
+ {
+ core = feature == "core";
+ }
+ }
+
+ if (!core)
+ {
+ feature_specs.emplace_back(package_spec, "core");
+
+ for (const std::string& def : default_features)
+ {
+ feature_specs.emplace_back(package_spec, def);
+ }
+ }
+ }
+
+ return feature_specs;
}
ExpectedT<FullPackageSpec, PackageSpecParseResult> FullPackageSpec::from_string(const std::string& spec_as_string,
diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp
index 9cb7caff1..797d681cd 100644
--- a/toolsrc/src/vcpkg/paragraphs.cpp
+++ b/toolsrc/src/vcpkg/paragraphs.cpp
@@ -205,10 +205,11 @@ namespace vcpkg::Paragraphs
ParseExpected<SourceControlFile> try_load_port(const Files::Filesystem& fs, const fs::path& path)
{
- Expected<std::vector<RawParagraph>> pghs = get_paragraphs(fs, path / "CONTROL");
+ const auto path_to_control = path / "CONTROL";
+ Expected<std::vector<RawParagraph>> pghs = get_paragraphs(fs, path_to_control);
if (auto vector_pghs = pghs.get())
{
- return SourceControlFile::parse_control_file(std::move(*vector_pghs));
+ return SourceControlFile::parse_control_file(path_to_control, std::move(*vector_pghs));
}
auto error_info = std::make_unique<ParseControlErrorInfo>();
error_info->name = path.filename().generic_u8string();
diff --git a/toolsrc/src/vcpkg/portfileprovider.cpp b/toolsrc/src/vcpkg/portfileprovider.cpp
new file mode 100644
index 000000000..6540f2949
--- /dev/null
+++ b/toolsrc/src/vcpkg/portfileprovider.cpp
@@ -0,0 +1,151 @@
+#include <pch.h>
+
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/portfileprovider.h>
+#include <vcpkg/sourceparagraph.h>
+
+namespace vcpkg::PortFileProvider
+{
+ MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map)
+ : ports(map)
+ {
+ }
+
+ Optional<const SourceControlFileLocation&> MapPortFileProvider::get_control_file(const std::string& spec) const
+ {
+ auto scf = ports.find(spec);
+ if (scf == ports.end()) return nullopt;
+ return scf->second;
+ }
+
+ std::vector<const SourceControlFileLocation*> MapPortFileProvider::load_all_control_files() const
+ {
+ return Util::fmap(ports, [](auto&& kvpair) -> const SourceControlFileLocation* { return &kvpair.second; });
+ }
+
+ PathsPortFileProvider::PathsPortFileProvider(const vcpkg::VcpkgPaths& paths,
+ const std::vector<std::string>* ports_dirs_paths)
+ : filesystem(paths.get_filesystem())
+ {
+ auto& fs = Files::get_real_filesystem();
+ if (ports_dirs_paths)
+ {
+ for (auto&& overlay_path : *ports_dirs_paths)
+ {
+ if (!overlay_path.empty())
+ {
+ auto overlay = fs::stdfs::canonical(fs::u8path(overlay_path));
+
+ 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);
+ }
+
+ Optional<const SourceControlFileLocation&> PathsPortFileProvider::get_control_file(const std::string& spec) const
+ {
+ auto cache_it = cache.find(spec);
+ if (cache_it != cache.end())
+ {
+ return cache_it->second;
+ }
+
+ for (auto&& ports_dir : ports_dirs)
+ {
+ // Try loading individual port
+ if (filesystem.exists(ports_dir / "CONTROL"))
+ {
+ auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir);
+ if (auto scf = maybe_scf.get())
+ {
+ if (scf->get()->core_paragraph->name == spec)
+ {
+ auto it = cache.emplace(std::piecewise_construct,
+ std::forward_as_tuple(spec),
+ std::forward_as_tuple(std::move(*scf), ports_dir));
+ return it.first->second;
+ }
+ }
+ else
+ {
+ vcpkg::print_error_message(maybe_scf.error());
+ Checks::exit_with_message(
+ VCPKG_LINE_INFO, "Error: Failed to load port from %s", spec, ports_dir.u8string());
+ }
+ }
+
+ auto found_scf = Paragraphs::try_load_port(filesystem, ports_dir / spec);
+ if (auto scf = found_scf.get())
+ {
+ if (scf->get()->core_paragraph->name == spec)
+ {
+ auto it = cache.emplace(std::piecewise_construct,
+ std::forward_as_tuple(spec),
+ std::forward_as_tuple(std::move(*scf), ports_dir / spec));
+ return it.first->second;
+ }
+ }
+ }
+
+ return nullopt;
+ }
+
+ std::vector<const SourceControlFileLocation*> PathsPortFileProvider::load_all_control_files() const
+ {
+ // Reload cache with ports contained in all ports_dirs
+ cache.clear();
+ std::vector<const SourceControlFileLocation*> ret;
+ for (auto&& ports_dir : ports_dirs)
+ {
+ // Try loading individual port
+ if (filesystem.exists(ports_dir / "CONTROL"))
+ {
+ auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir);
+ if (auto scf = maybe_scf.get())
+ {
+ auto port_name = scf->get()->core_paragraph->name;
+ if (cache.find(port_name) == cache.end())
+ {
+ auto it = cache.emplace(std::piecewise_construct,
+ std::forward_as_tuple(port_name),
+ std::forward_as_tuple(std::move(*scf), ports_dir));
+ ret.emplace_back(&it.first->second);
+ }
+ }
+ else
+ {
+ vcpkg::print_error_message(maybe_scf.error());
+ Checks::exit_with_message(
+ VCPKG_LINE_INFO, "Error: Failed to load port from %s", ports_dir.u8string());
+ }
+ continue;
+ }
+
+ // Try loading all ports inside ports_dir
+ auto found_scf = Paragraphs::load_all_ports(filesystem, ports_dir);
+ for (auto&& scf : found_scf)
+ {
+ auto port_name = scf->core_paragraph->name;
+ if (cache.find(port_name) == cache.end())
+ {
+ auto it = cache.emplace(std::piecewise_construct,
+ std::forward_as_tuple(port_name),
+ std::forward_as_tuple(std::move(scf), ports_dir / port_name));
+ ret.emplace_back(&it.first->second);
+ }
+ }
+ }
+ return ret;
+ }
+}
diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp
index 2a13d2786..b346e1721 100644
--- a/toolsrc/src/vcpkg/postbuildlint.cpp
+++ b/toolsrc/src/vcpkg/postbuildlint.cpp
@@ -98,6 +98,93 @@ namespace vcpkg::PostBuildLint
return LintStatus::SUCCESS;
}
+ static LintStatus check_for_restricted_include_files(const Files::Filesystem& fs,
+ const Build::BuildPolicies& policies,
+ const fs::path& package_dir)
+ {
+ if (policies.is_enabled(BuildPolicy::ALLOW_RESTRICTED_HEADERS))
+ {
+ return LintStatus::SUCCESS;
+ }
+
+ // These files are taken from the libc6-dev package on Ubuntu inside /usr/include/x86_64-linux-gnu/sys/
+ static constexpr StringLiteral restricted_sys_filenames[] = {
+ "acct.h", "auxv.h", "bitypes.h", "cdefs.h", "debugreg.h", "dir.h", "elf.h",
+ "epoll.h", "errno.h", "eventfd.h", "fanotify.h", "fcntl.h", "file.h", "fsuid.h",
+ "gmon.h", "gmon_out.h", "inotify.h", "io.h", "ioctl.h", "ipc.h", "kd.h",
+ "klog.h", "mman.h", "mount.h", "msg.h", "mtio.h", "param.h", "pci.h",
+ "perm.h", "personality.h", "poll.h", "prctl.h", "procfs.h", "profil.h", "ptrace.h",
+ "queue.h", "quota.h", "random.h", "raw.h", "reboot.h", "reg.h", "resource.h",
+ "select.h", "sem.h", "sendfile.h", "shm.h", "signal.h", "signalfd.h", "socket.h",
+ "socketvar.h", "soundcard.h", "stat.h", "statfs.h", "statvfs.h", "stropts.h", "swap.h",
+ "syscall.h", "sysctl.h", "sysinfo.h", "syslog.h", "sysmacros.h", "termios.h", "time.h",
+ "timeb.h", "timerfd.h", "times.h", "timex.h", "ttychars.h", "ttydefaults.h", "types.h",
+ "ucontext.h", "uio.h", "un.h", "unistd.h", "user.h", "ustat.h", "utsname.h",
+ "vfs.h", "vlimit.h", "vm86.h", "vt.h", "vtimes.h", "wait.h", "xattr.h",
+ };
+ // These files are taken from the libc6-dev package on Ubuntu inside the /usr/include/ folder
+ static constexpr StringLiteral restricted_crt_filenames[] = {
+ "_G_config.h", "aio.h", "aliases.h", "alloca.h", "ar.h", "argp.h",
+ "argz.h", "assert.h", "byteswap.h", "complex.h", "cpio.h", "crypt.h",
+ "ctype.h", "dirent.h", "dlfcn.h", "elf.h", "endian.h", "envz.h",
+ "err.h", "errno.h", "error.h", "execinfo.h", "fcntl.h", "features.h",
+ "fenv.h", "fmtmsg.h", "fnmatch.h", "fstab.h", "fts.h", "ftw.h",
+ "gconv.h", "getopt.h", "glob.h", "gnu-versions.h", "grp.h", "gshadow.h",
+ "iconv.h", "ifaddrs.h", "inttypes.h", "langinfo.h", "lastlog.h", "libgen.h",
+ "libintl.h", "libio.h", "limits.h", "link.h", "locale.h", "malloc.h",
+ "math.h", "mcheck.h", "memory.h", "mntent.h", "monetary.h", "mqueue.h",
+ "netash", "netdb.h", "nl_types.h", "nss.h", "obstack.h", "paths.h",
+ "poll.h", "printf.h", "proc_service.h", "pthread.h", "pty.h", "pwd.h",
+ "re_comp.h", "regex.h", "regexp.h", "resolv.h", "sched.h", "search.h",
+ "semaphore.h", "setjmp.h", "sgtty.h", "shadow.h", "signal.h", "spawn.h",
+ "stab.h", "stdc-predef.h", "stdint.h", "stdio.h", "stdio_ext.h", "stdlib.h",
+ "string.h", "strings.h", "stropts.h", "syscall.h", "sysexits.h", "syslog.h",
+ "tar.h", "termio.h", "termios.h", "tgmath.h", "thread_db.h", "time.h",
+ "ttyent.h", "uchar.h", "ucontext.h", "ulimit.h", "unistd.h", "ustat.h",
+ "utime.h", "utmp.h", "utmpx.h", "values.h", "wait.h", "wchar.h",
+ "wctype.h", "wordexp.h",
+ };
+ // These files are general names that have shown to be problematic in the past
+ static constexpr StringLiteral restricted_general_filenames[] = {
+ "json.h",
+ "parser.h",
+ "lexer.h",
+ "config.h",
+ "local.h",
+ "slice.h",
+ };
+ static constexpr Span<const StringLiteral> restricted_lists[] = {
+ restricted_sys_filenames, restricted_crt_filenames, restricted_general_filenames};
+ const fs::path include_dir = package_dir / "include";
+ auto files = fs.get_files_non_recursive(include_dir);
+ auto filenames_v = Util::fmap(files, [](const auto& file) { return file.filename().u8string(); });
+ std::set<std::string> filenames_s(filenames_v.begin(), filenames_v.end());
+
+ std::vector<fs::path> violations;
+ for (auto&& flist : restricted_lists)
+ for (auto&& f : flist)
+ {
+ if (Util::Sets::contains(filenames_s, f))
+ {
+ violations.push_back(fs::u8path("include") / fs::u8path(f.c_str()));
+ }
+ }
+
+ if (!violations.empty())
+ {
+ System::print2(System::Color::warning,
+ "Restricted headers paths are present. These files can prevent the core C++ runtime and "
+ "other packages from compiling correctly:\n");
+ Files::print_paths(violations);
+ System::print2("In exceptional circumstances, this policy can be disabled via ",
+ Build::to_cmake_variable(BuildPolicy::ALLOW_RESTRICTED_HEADERS),
+ "\n");
+ return LintStatus::ERROR_DETECTED;
+ }
+
+ return LintStatus::SUCCESS;
+ }
+
static LintStatus check_for_files_in_debug_include_directory(const Files::Filesystem& fs,
const fs::path& package_dir)
{
@@ -142,10 +229,10 @@ namespace vcpkg::PostBuildLint
const fs::path lib_cmake = package_dir / "lib" / "cmake";
if (fs.exists(lib_cmake))
{
- System::printf(
- System::Color::warning,
- "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.\n",
- spec.name());
+ System::printf(System::Color::warning,
+ "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to "
+ "/share/%s/cmake.\nPlease use the helper function `vcpkg_fixup_cmake_targets()`\n",
+ spec.name());
return LintStatus::ERROR_DETECTED;
}
@@ -295,10 +382,12 @@ namespace vcpkg::PostBuildLint
return LintStatus::SUCCESS;
}
- static LintStatus check_exports_of_dlls(const Build::BuildPolicies& policies, const std::vector<fs::path>& dlls, const fs::path& dumpbin_exe)
+ static LintStatus check_exports_of_dlls(const Build::BuildPolicies& policies,
+ const std::vector<fs::path>& dlls,
+ const fs::path& dumpbin_exe)
{
if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_EXPORTS)) return LintStatus::SUCCESS;
-
+
std::vector<fs::path> dlls_with_no_exports;
for (const fs::path& dll : dlls)
{
@@ -571,7 +660,7 @@ namespace vcpkg::PostBuildLint
R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)"
"\n"
"\n"
- R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL static))###"
+ R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL "static"))###"
"\n"
R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###"
"\n"
@@ -760,6 +849,7 @@ namespace vcpkg::PostBuildLint
}
error_count += check_for_files_in_include_directory(fs, build_info.policies, package_dir);
+ error_count += check_for_restricted_include_files(fs, build_info.policies, package_dir);
error_count += check_for_files_in_debug_include_directory(fs, package_dir);
error_count += check_for_files_in_debug_share_directory(fs, package_dir);
error_count += check_folder_lib_cmake(fs, package_dir, spec);
diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp
index 65e00668a..1bcfe58a0 100644
--- a/toolsrc/src/vcpkg/remove.cpp
+++ b/toolsrc/src/vcpkg/remove.cpp
@@ -229,7 +229,7 @@ namespace vcpkg::Remove
}
// Load ports from ports dirs
- Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
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 ebb9cd4f4..26681e107 100644
--- a/toolsrc/src/vcpkg/sourceparagraph.cpp
+++ b/toolsrc/src/vcpkg/sourceparagraph.cpp
@@ -23,10 +23,10 @@ namespace vcpkg
static const std::string FEATURE = "Feature";
static const std::string MAINTAINER = "Maintainer";
static const std::string SOURCE = "Source";
- static const std::string SUPPORTS = "Supports";
static const std::string VERSION = "Version";
static const std::string HOMEPAGE = "Homepage";
static const std::string TYPE = "Type";
+ static const std::string SUPPORTS = "Supports";
}
static Span<const std::string> get_list_of_valid_fields()
@@ -39,6 +39,7 @@ namespace vcpkg
SourceParagraphFields::BUILD_DEPENDS,
SourceParagraphFields::HOMEPAGE,
SourceParagraphFields::TYPE,
+ SourceParagraphFields::SUPPORTS,
};
return valid_fields;
@@ -101,7 +102,24 @@ namespace vcpkg
}
}
- static ParseExpected<SourceParagraph> parse_source_paragraph(RawParagraph&& fields)
+ std::string Type::to_string(const Type& t)
+ {
+ switch (t.type)
+ {
+ case Type::ALIAS: return "Alias";
+ case Type::PORT: return "Port";
+ default: return "Unknown";
+ }
+ }
+
+ Type Type::from_string(const std::string& t)
+ {
+ if (t == "Alias") return Type{Type::ALIAS};
+ if (t == "Port" || t == "") return Type{Type::PORT};
+ return Type{Type::UNKNOWN};
+ }
+
+ static ParseExpected<SourceParagraph> parse_source_paragraph(const fs::path& path_to_control, RawParagraph&& fields)
{
ParagraphParser parser(std::move(fields));
@@ -115,17 +133,18 @@ namespace vcpkg
spgh->homepage = parser.optional_field(SourceParagraphFields::HOMEPAGE);
spgh->depends = expand_qualified_dependencies(
parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)));
- spgh->supports = parse_comma_list(parser.optional_field(SourceParagraphFields::SUPPORTS));
spgh->default_features = parse_comma_list(parser.optional_field(SourceParagraphFields::DEFAULTFEATURES));
-
- auto err = parser.error_info(spgh->name);
+ spgh->supports_expression = parser.optional_field(SourceParagraphFields::SUPPORTS);
+ spgh->type = Type::from_string(parser.optional_field(SourceParagraphFields::TYPE));
+ auto err = parser.error_info(spgh->name.empty() ? path_to_control.u8string() : spgh->name);
if (err)
- return std::move(err);
+ return err;
else
- return std::move(spgh);
+ return spgh;
}
- static ParseExpected<FeatureParagraph> parse_feature_paragraph(RawParagraph&& fields)
+ static ParseExpected<FeatureParagraph> parse_feature_paragraph(const fs::path& path_to_control,
+ RawParagraph&& fields)
{
ParagraphParser parser(std::move(fields));
@@ -137,24 +156,26 @@ namespace vcpkg
fpgh->depends = expand_qualified_dependencies(
parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)));
- auto err = parser.error_info(fpgh->name);
+ auto err = parser.error_info(fpgh->name.empty() ? path_to_control.u8string() : fpgh->name);
if (err)
- return std::move(err);
+ return err;
else
- return std::move(fpgh);
+ return fpgh;
}
ParseExpected<SourceControlFile> SourceControlFile::parse_control_file(
- std::vector<Parse::RawParagraph>&& control_paragraphs)
+ const fs::path& path_to_control, std::vector<Parse::RawParagraph>&& control_paragraphs)
{
if (control_paragraphs.size() == 0)
{
- return std::make_unique<Parse::ParseControlErrorInfo>();
+ auto ret = std::make_unique<Parse::ParseControlErrorInfo>();
+ ret->name = path_to_control.u8string();
+ return ret;
}
auto control_file = std::make_unique<SourceControlFile>();
- auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front()));
+ auto maybe_source = parse_source_paragraph(path_to_control, std::move(control_paragraphs.front()));
if (const auto source = maybe_source.get())
control_file->core_paragraph = std::move(*source);
else
@@ -164,14 +185,14 @@ namespace vcpkg
for (auto&& feature_pgh : control_paragraphs)
{
- auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh));
+ auto maybe_feature = parse_feature_paragraph(path_to_control, std::move(feature_pgh));
if (const auto feature = maybe_feature.get())
control_file->feature_paragraphs.emplace_back(std::move(*feature));
else
return std::move(maybe_feature).error();
}
- return std::move(control_file);
+ return control_file;
}
Optional<const FeatureParagraph&> SourceControlFile::find_feature(const std::string& featurename) const
@@ -183,6 +204,18 @@ namespace vcpkg
else
return nullopt;
}
+ Optional<const std::vector<Dependency>&> SourceControlFile::find_dependencies_for_feature(
+ const std::string& featurename) const
+ {
+ if (featurename == "core")
+ {
+ return core_paragraph->depends;
+ }
+ else if (auto p_feature = find_feature(featurename).get())
+ return p_feature->depends;
+ else
+ return nullopt;
+ }
Dependency Dependency::parse_dependency(std::string name, std::string qualifier)
{
@@ -207,96 +240,62 @@ namespace vcpkg
std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends)
{
return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency {
- auto pos = depend_string.find(' ');
- if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, "");
- // expect of the form "\w+ \[\w+\]"
- if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')')
+ // First, try to find beginning and end of features list
+ auto end_of_features = depend_string.find(']');
+ if (end_of_features != std::string::npos)
{
- // Error, but for now just slurp the entire string.
- return Dependency::parse_dependency(depend_string, "");
+ ++end_of_features;
+ }
+ else
+ {
+ end_of_features = depend_string.find(' ');
+ if (end_of_features == std::string::npos) end_of_features = depend_string.size();
}
- return Dependency::parse_dependency(depend_string.substr(0, pos),
- depend_string.substr(pos + 2, depend_string.size() - pos - 3));
- });
- }
- std::vector<std::string> filter_dependencies(const std::vector<vcpkg::Dependency>& deps, const Triplet& t)
- {
- std::vector<std::string> ret;
- for (auto&& dep : deps)
- {
- const auto& qualifier = dep.qualifier;
- if (qualifier.empty() || evaluate_expression(qualifier, t.canonical_name()))
+ auto begin_of_qualifier = depend_string.find('(', end_of_features);
+ if (begin_of_qualifier == std::string::npos)
{
- ret.emplace_back(dep.name());
+ return Dependency::parse_dependency(depend_string.substr(0, end_of_features), "");
}
- }
- return ret;
+ else
+ {
+ int depth = 1;
+ auto i = begin_of_qualifier + 1;
+ for (; i != depend_string.size(); ++i)
+ {
+ auto ch = depend_string[i];
+ if (ch == '(')
+ ++depth;
+ else if (ch == ')')
+ --depth;
+
+ if (depth == 0) break;
+ }
+ return Dependency::parse_dependency(
+ depend_string.substr(0, end_of_features),
+ depend_string.substr(begin_of_qualifier + 1, i - begin_of_qualifier - 1));
+ }
+ });
}
- std::vector<Features> filter_dependencies_to_features(const std::vector<vcpkg::Dependency>& deps, const Triplet& t)
+ std::vector<FullPackageSpec> filter_dependencies(const std::vector<vcpkg::Dependency>& deps,
+ const Triplet& t,
+ const std::unordered_map<std::string, std::string>& cmake_vars)
{
- std::vector<Features> ret;
+ std::vector<FullPackageSpec> ret;
for (auto&& dep : deps)
{
const auto& qualifier = dep.qualifier;
- if (qualifier.empty() || evaluate_expression(qualifier, t.canonical_name()))
+ if (qualifier.empty() ||
+ evaluate_expression(qualifier, {cmake_vars, t.canonical_name()}).value_or_exit(VCPKG_LINE_INFO))
{
- ret.emplace_back(dep.depend);
+ ret.emplace_back(FullPackageSpec(
+ PackageSpec::from_name_and_triplet(dep.depend.name, t).value_or_exit(VCPKG_LINE_INFO),
+ dep.depend.features));
}
}
return ret;
}
- std::vector<FeatureSpec> filter_dependencies_to_specs(const std::vector<Dependency>& deps, const Triplet& t)
- {
- return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t);
- }
-
std::string to_string(const Dependency& dep) { return dep.name(); }
-
- ExpectedT<Supports, std::vector<std::string>> Supports::parse(const std::vector<std::string>& strs)
- {
- Supports ret;
- std::vector<std::string> unrecognized;
-
- for (auto&& str : strs)
- {
- if (str == "x64")
- ret.architectures.push_back(Architecture::X64);
- else if (str == "x86")
- ret.architectures.push_back(Architecture::X86);
- else if (str == "arm")
- ret.architectures.push_back(Architecture::ARM);
- else if (str == "windows")
- ret.platforms.push_back(Platform::WINDOWS);
- else if (str == "uwp")
- ret.platforms.push_back(Platform::UWP);
- else if (str == "v140")
- ret.toolsets.push_back(ToolsetVersion::V140);
- else if (str == "v141")
- ret.toolsets.push_back(ToolsetVersion::V141);
- else if (str == "crt-static")
- ret.crt_linkages.push_back(Linkage::STATIC);
- else if (str == "crt-dynamic")
- ret.crt_linkages.push_back(Linkage::DYNAMIC);
- else
- unrecognized.push_back(str);
- }
-
- if (unrecognized.empty())
- return std::move(ret);
- else
- return std::move(unrecognized);
- }
-
- bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools)
- {
- const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); };
- if (!is_in_or_empty(arch, architectures)) return false;
- if (!is_in_or_empty(plat, platforms)) return false;
- if (!is_in_or_empty(crt, crt_linkages)) return false;
- if (!is_in_or_empty(tools, toolsets)) return false;
- return true;
- }
}
diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp
index f7e00f21c..c0ecca3a0 100644
--- a/toolsrc/src/vcpkg/statusparagraph.cpp
+++ b/toolsrc/src/vcpkg/statusparagraph.cpp
@@ -85,6 +85,34 @@ namespace vcpkg
default: return "error";
}
}
+
+ std::unordered_map<std::string, std::vector<FeatureSpec>> InstalledPackageView::feature_dependencies() const
+ {
+ auto extract_deps = [&](const std::string& dep) {
+ FullPackageSpec dependency =
+ FullPackageSpec::from_string(dep, spec().triplet()).value_or_exit(VCPKG_LINE_INFO);
+ std::vector<FeatureSpec> fspecs;
+
+ for (std::string& feature : dependency.features)
+ {
+ fspecs.emplace_back(dependency.package_spec, std::move(feature));
+ }
+
+ return fspecs;
+ };
+
+ std::unordered_map<std::string, std::vector<FeatureSpec>> deps;
+
+ for (const StatusParagraph* const& feature : features)
+ {
+ deps.emplace(feature->package.feature, Util::fmap_flatten(feature->package.depends, extract_deps));
+ }
+
+ deps.emplace("core", Util::fmap_flatten(core->package.depends, extract_deps));
+
+ return deps;
+ }
+
std::vector<PackageSpec> InstalledPackageView::dependencies() const
{
// accumulate all features in installed dependencies
diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp
index 3c81728bb..2fa9df7df 100644
--- a/toolsrc/src/vcpkg/statusparagraphs.cpp
+++ b/toolsrc/src/vcpkg/statusparagraphs.cpp
@@ -46,7 +46,7 @@ namespace vcpkg
}
}
if (ipv.core != nullptr)
- return std::move(ipv);
+ return ipv;
else
return nullopt;
}
diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp
index 6320bae5b..8cb2ac557 100644
--- a/toolsrc/src/vcpkg/update.cpp
+++ b/toolsrc/src/vcpkg/update.cpp
@@ -14,7 +14,7 @@ namespace vcpkg::Update
return left.spec.name() < right.spec.name();
}
- std::vector<OutdatedPackage> find_outdated_packages(const Dependencies::PortFileProvider& provider,
+ std::vector<OutdatedPackage> find_outdated_packages(const PortFileProvider::PortFileProvider& provider,
const StatusParagraphs& status_db)
{
auto installed_packages = get_installed_ports(status_db);
@@ -57,7 +57,7 @@ namespace vcpkg::Update
const StatusParagraphs status_db = database_load_check(paths);
- Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ PortFileProvider::PathsPortFileProvider provider(paths, args.overlay_ports.get());
const auto outdated_packages = SortedVector<OutdatedPackage>(find_outdated_packages(provider, status_db),
&OutdatedPackage::compare_by_name);
diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj
index 92f115a70..5119c5833 100644
--- a/toolsrc/vcpkglib/vcpkglib.vcxproj
+++ b/toolsrc/vcpkglib/vcpkglib.vcxproj
@@ -223,6 +223,7 @@
<ClCompile Include="..\src\vcpkg\base\system.print.cpp" />
<ClCompile Include="..\src\vcpkg\binaryparagraph.cpp" />
<ClCompile Include="..\src\vcpkg\build.cpp" />
+ <ClCompile Include="..\src\vcpkg\cmakevars.cpp" />
<ClCompile Include="..\src\vcpkg\commands.autocomplete.cpp" />
<ClCompile Include="..\src\vcpkg\commands.buildexternal.cpp" />
<ClCompile Include="..\src\vcpkg\commands.cache.cpp" />
@@ -258,6 +259,7 @@
<ClCompile Include="..\src\vcpkg\paragraphparseresult.cpp" />
<ClCompile Include="..\src\vcpkg\paragraphs.cpp" />
<ClCompile Include="..\src\vcpkg\parse.cpp" />
+ <ClCompile Include="..\src\vcpkg\portfileprovider.cpp" />
<ClCompile Include="..\src\vcpkg\postbuildlint.buildtype.cpp" />
<ClCompile Include="..\src\vcpkg\postbuildlint.cpp" />
<ClCompile Include="..\src\vcpkg\remove.cpp" />
@@ -277,4 +279,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
index 54366e7a6..043a9a22f 100644
--- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
+++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters
@@ -225,6 +225,12 @@
<ClCompile Include="..\src\vcpkg\commands.porthistory.cpp">
<Filter>Source Files\vcpkg</Filter>
</ClCompile>
+ <ClCompile Include="..\src\vcpkg\cmakevars.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\vcpkg\portfileprovider.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\pch.h">
diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj
index d656de747..24bb7b29b 100644
--- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj
+++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj
@@ -24,12 +24,12 @@
<ClCompile Include="..\src\vcpkg-test\chrono.cpp" />
<ClCompile Include="..\src\vcpkg-test\dependencies.cpp" />
<ClCompile Include="..\src\vcpkg-test\files.cpp" />
+ <ClCompile Include="..\src\vcpkg-test\mockcmakevarsprovider.cpp" />
<ClCompile Include="..\src\vcpkg-test\paragraph.cpp" />
<ClCompile Include="..\src\vcpkg-test\plan.cpp" />
<ClCompile Include="..\src\vcpkg-test\specifier.cpp" />
<ClCompile Include="..\src\vcpkg-test\statusparagraphs.cpp" />
<ClCompile Include="..\src\vcpkg-test\strings.cpp" />
- <ClCompile Include="..\src\vcpkg-test\supports.cpp" />
<ClCompile Include="..\src\vcpkg-test\update.cpp" />
<ClCompile Include="..\src\vcpkg-test\util.cpp" />
</ItemGroup>
@@ -39,7 +39,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\include\vcpkg-test\catch.h" />
+ <ClInclude Include="..\include\catch2\catch.hpp" />
+ <ClInclude Include="..\include\vcpkg-test\mockcmakevarprovider.h" />
<ClInclude Include="..\include\vcpkg-test\util.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
@@ -51,13 +52,13 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
@@ -70,7 +71,7 @@
<UseOfMfc>false</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
@@ -151,6 +152,7 @@
<UseFullPaths>true</UseFullPaths>
<AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -171,6 +173,7 @@
<UseFullPaths>true</UseFullPaths>
<AdditionalOptions>/std:c++latest %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -183,4 +186,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters
index 74a746af1..481fe3b6e 100644
--- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters
+++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters
@@ -39,9 +39,6 @@
<ClCompile Include="..\src\vcpkg-test\statusparagraphs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\src\vcpkg-test\supports.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\src\vcpkg-test\update.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -54,13 +51,19 @@
<ClCompile Include="..\src\vcpkg-test\strings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\src\vcpkg-test\mockcmakevarsprovider.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\include\vcpkg-tests\catch.h">
+ <ClInclude Include="..\include\vcpkg-test\util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\catch2\catch.hpp">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\include\vcpkg-tests\util.h">
+ <ClInclude Include="..\include\vcpkg-test\mockcmakevarprovider.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
-</Project>
+</Project> \ No newline at end of file