Skip to content

Commit 1d8f0ac

Browse files
authored
[vcpkg manifest] Manifest Implementation (microsoft#11757)
==== Changes Related to manifests ==== * Add the `manifests` feature flag * This only says whether we look for a `vcpkg.json` in the cwd, not whether we support parsing manifests (for ports, for example) * Changes to the manifests RFC * `"authors"` -> `"maintainers"` * `--x-classic-mode` -> `-manifests` \in `vcpkg_feature_flags` * reserve `"core"` in addition to `"default"`, since that's already reserved for features * Add a small helper note about what identifiers must look like * `<license-string>`: SPDX v3.8 -> v3.9 * `"feature"."description"` is allowed to be an array of strings as well * `"version"` -> `"version-string"` for forward-compat with versions RFC * Add the `--feature-flags` option * Add the ability to turn off feature flags via passing `-<feature-flag>` to `VCPKG_FEATURE_FLAGS` or `--feature-flags` * Add CMake toolchain support for manifests * Requires either: * a feature flag of `manifests` in either `Env{VCPKG_FEATURE_FLAGS}` or `VCPKG_FEATURE_FLAGS` * Passing the `VCPKG_ENABLE_MANIFESTS` option * The toolchain will install your packages to `${VCPKG_MANIFEST_DIR}/vcpkg_installed`. * Add MSBuild `vcpkg integrate install` support for manifests * Requires `VcpkgEnableManifest` to be true * `vcpkg create` creates a port that has a `vcpkg.json` instead of a `CONTROL` * argparse, abseil, 3fd, and avisynthplus ports switched to manifest from CONTROL * Add support for `--x-manifest-root`, as well as code for finding it if not passed * Add support for parsing manifests! * Add a filesystem lock! ==== Important Changes which are somewhat unrelated to manifests ==== * Rename `logicexpression.{h,cpp}` to `platform-expression.{h,cpp}` * Add `PlatformExpression` type which takes the place of the old logic expression * Split the parsing of platform expressions from checking whether they're true or not * Eagerly parse PlatformExpressions as opposed to leaving them as strings * Add checking for feature flag consistency * i.e., if `-binarycaching` is passed, you shouldn't be passing `--binarysource` * Add the `Json::Reader` type which, with the help of user-defined visitors, converts JSON to your internal type * VcpkgArgParser: place the switch names into a constant as opposed to using magic constants * In general update the parsing code so that this ^ works * Add `Port-Version` fields to CONTROL files * This replaces the existing practice of `Version: <my-version>-<port-version>` ==== Smaller changes ==== * small drive-by cleanups to some CMake * `${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}` -> `${CURRENT_INSTALLED_DIR}` * Remove `-analyze` when compiling with clang-cl, since that's not a supported flag (vcpkg's build system) * Add a message about which compiler is detected by vcpkg's build system machinery * Fix `Expected::then` * Convert `""` to `{}` for `std::string` and `fs::path`, to avoid a `strlen` (additionally, `.empty()` instead of `== ""`, and `.clear()`) * Add `Strings::strto` which converts strings to numeric types * Support built-in arrays and `StringView` for `Strings::join` * Add `operator<` and friends to `StringView` * Add `substr` to `StringView` * SourceParagraphParser gets some new errors
1 parent 67ab613 commit 1d8f0ac

File tree

111 files changed

+6107
-3336
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+6107
-3336
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
toolsrc/out*
1515
toolsrc/CMakeSettings.json
16+
# fuzzing
17+
sync_dir*
1618

1719
# User-specific files (MonoDevelop/Xamarin Studio)
1820
*.userprefs
@@ -331,4 +333,4 @@ __pycache__/
331333
############################################################
332334
archives
333335
.DS_Store
334-
prefab/
336+
prefab/

docs/about/privacy.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ We collect various telemetry events such as the command line used, the time of i
4141

4242
You can see the telemetry events any command by appending `--printmetrics` after the vcpkg command line.
4343

44-
In the source code (included in `toolsrc\`), you can search for calls to the functions `track_property()` and `track_metric()` to see every specific data point we collect.
44+
In the source code (included in `toolsrc\`), you can search for calls to the functions `track_property()`, `track_feature()`, `track_metric()`, and `track_buildtime()`
45+
to see every specific data point we collect.
4546

4647
## Avoid inadvertent disclosure information
4748

docs/specifications/manifests.md

+58-70
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ rather than JSON5 or JSON with comments because JSON is the everywhere-supported
3434
standard. That is not necessarily true of JSON with comments. Additionally, if one needs
3535
to write a comment, they can do so via `"$reason"` or `"$comment"` fields.
3636

37-
### Why are `<platform-specification>`s so verbose?
38-
39-
In the initial implementation, we didn't want to do more parsing than is strictly necessary,
40-
especially parsing languages which aren't defined anywhere. We may add a shorter way of
41-
defining platform specifications in the future (more similar to those in control files).
42-
4337
## Specification
4438

4539
A manifest file shall have the name `vcpkg.json`, and shall be in the root directory of a package.
@@ -54,26 +48,28 @@ to specify the shape of a value. Note that any object may contain any directives
5448
a field key that starts with a `$`; these directive shall be ignored by `vcpkg`. Common
5549
directives may include `"$schema"`, `"$comment"`, `"$reason"`.
5650

57-
A manifest must be a top-level object, and must have at least the following properties:
51+
A manifest must be a top-level object, and must have at least:
5852

5953
* `"name"`: a `<package-name>`
60-
* `"version"`: A `string`. This will be defined further later.
61-
* [Semver](https://semver.org) is recommended but not required.
54+
* One (and only one) of the following version fields:
55+
* `"version-string"`: A `string`. Has no semantic meaning.
56+
Equivalent to `CONTROL`'s `Version:` field.
57+
* Other version fields will be defined by the Versions RFC
6258

6359
The simplest vcpkg.json looks like this:
6460

6561
```json
6662
{
6763
"name": "mypackage",
68-
"version": "0.1.0-dev"
64+
"version-string": "0.1.0-dev"
6965
}
7066
```
7167

7268
Additionally, it may contain the following properties:
7369
* `"port-version"`: A non-negative integer. If this field doesn't exist, it's assumed to be `0`.
7470
* Note that this is a change from existing CONTROL files, where versions were a part of the version string
75-
* `"authors"`: An array of `string`s which contain the authors of a package
76-
* `"authors": [ "Nicole Mazzuca <[email protected]>", "שלום עליכם <[email protected]>" ]`
71+
* `"maintainers"`: An array of `string`s which contain the authors of a package
72+
* `"maintainers": [ "Nicole Mazzuca <[email protected]>", "שלום עליכם <[email protected]>" ]`
7773
* `"description"`: A string or array of strings containing the description of a package
7874
* `"description": "mypackage is a package of mine"`
7975
* `"homepage"`: A url which points to the homepage of a package
@@ -86,8 +82,8 @@ Additionally, it may contain the following properties:
8682
* `"dev-dependencies"`: An array of `<dependency>`s which are required only for developers (testing and the like)
8783
* `"features"`: An array of `<feature>`s that the package supports
8884
* `"default-features"`: An array of `<identifier>`s that correspond to features, which will be used by default.
89-
* `"supports"`: A `<platform-specification>`
90-
* `"supports": { "and": [ "win", { "not": "arm" } ] }`
85+
* `"supports"`: A `<platform-expression>`
86+
* `"supports": "windows & !arm"`
9187

9288
Any properties which are not listed, and which do not start with a `$`,
9389
will be warned against and are reserved for future use.
@@ -105,7 +101,7 @@ Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!(win
105101
```json
106102
{
107103
"name": "pango",
108-
"version": "1.40.11",
104+
"version-string": "1.40.11",
109105
"port-version": 6,
110106
"homepage": "https://ftp.gnome.org/pub/GNOME/sources/pango/",
111107
"description": "Text and font handling library.",
@@ -118,22 +114,15 @@ Build-Depends: glib, gettext, cairo, fontconfig, freetype, harfbuzz[glib] (!(win
118114
{
119115
"name": "harfbuzz",
120116
"features": [ "glib" ],
121-
"platform": {
122-
"and": [
123-
{ "not": { "and": [ "windows", "static" ] } },
124-
{ "not": "osx" }
125-
]
126-
}
117+
"platform": "!(windows & static) & !osx"
127118
}
128119
]
129120
}
130121
```
131122

132-
You may notice that the platform specification is fairly wordy. See [reasoning](#why-are-platform-specifications-so-verbose) for why.
133-
134123
## Behavior of the Tool
135124

136-
There will be two "modes" for vcpkg from this point forward: "classic", and "modern".
125+
There will be two "modes" for vcpkg from this point forward: "classic", and "manifest".
137126
The former will act exactly like the existing vcpkg workflow, so as to avoid breaking
138127
anyone. The latter will be the mode only when the user either:
139128

@@ -146,61 +135,49 @@ anyone. The latter will be the mode only when the user either:
146135
* The environment variable `VCPKG_FEATURE_FLAGS`
147136
* The option `--feature-flags`
148137
* (e.g., `--feature-flags=binarycaching,manifests`)
138+
* If someone wants to use classic mode and silence the warning, they can add the
139+
`-manifests` feature flag to disable the mode.
149140

150-
Additionally, we'll add the `--x-classic-mode` flag to allow someone to force classic
151-
mode.
152-
153-
When in "modern" mode, the `installed` directory will be changed to
141+
When in "manifest" mode, the `installed` directory will be changed to
154142
`<manifest-root>/vcpkg_installed` (name up for bikeshedding).
155143
The following commands will change behavior:
156144

157145
* `vcpkg install` without any port arguments will install the dependencies listed in
158146
the manifest file, and will remove any dependencies
159147
which are no longer in the dependency tree implied by the manifest file.
160148
* `vcpkg install` with port arguments will give an error.
161-
* `vcpkg x-clean` will be added, and will delete your `vcpkg_installed` directory.
162149

163-
The following commands will not work in modern mode, at least initially:
150+
The following commands will not work in manifest mode, at least initially:
164151

165152
* `vcpkg x-set-installed`: `vcpkg install` serves the same function
166153
* `vcpkg remove`
167154
* `vcpkg export`
168-
* `vcpkg import`
169-
* `vcpkg create`
170155

171-
We may add these features back for modern mode once we understand how best to
156+
We may add these features back for manifest mode once we understand how best to
172157
implement them.
173158

174159
### Behavior of the Toolchain
175160

176-
Mostly, the toolchain file stays the same; however, we shall add one public cache variable:
177-
178-
```cmake
179-
VCPKG_MANIFEST_ROOT:PATH=<path to the directory containing the vcpkg.json file>
180-
```
181-
182-
and one function:
161+
Mostly, the toolchain file stays the same; however, we shall add
162+
two public options:
183163

184164
```cmake
185-
vcpkg_acquire_dependencies(
186-
[TRIPLET <triplet>]
187-
[MANIFEST <path to manifest>]
188-
[INSTALL_DIRECTORY <install directory>])
165+
VCPKG_MANIFEST_MODE:BOOL=<we found a manifest>
166+
VCPKG_MANIFEST_INSTALL:BOOL=ON
189167
```
190168

191-
which installs the dependencies required by the manifest file.
192-
193-
The default for `TRIPLET` is `VCPKG_TARGET_TRIPLET`
194-
(which is the default triplet for the configured system).
195-
For example, on x64 Windows, it defaults to `x64-windows`.
169+
The first option either explicitly turns on, or off, manifest mode;
170+
otherwise, we default to looking for a manifest file in the directory
171+
tree upwards from the source directory.
196172

197-
The default for `INSTALL_DIRECTORY` is `${CMAKE_BINARY_DIR}/vcpkg_installed`.
173+
The `VCPKG_MANIFEST_INSTALL` option tells the toolchain whether to
174+
install the packages or not -- if you wish to install the manifest
175+
dependencies manually, you can set this to off, and we also turn it
176+
off for packages installed by vcpkg.
198177

199-
Additionally, in the course of implementation, we would like to
200-
look at adding the following function, but may not be able to:
201-
202-
It is almost certain that one should guard any use of this function
203-
by `if(EXISTS CACHE{VCPKG_MANIFEST_FILE})`.
178+
Additionally, if `-manifests` is set in the feature flags environment
179+
variable, we turn off manifest mode in the toolchain, and we act like
180+
the classic toolchain.
204181

205182
### Example - CMake Integration
206183

@@ -232,7 +209,7 @@ Therefore, in `vcpkg.json`, we'll need to depend on `fmt`:
232209
```json
233210
{
234211
"name": "example",
235-
"version": "0.0.1",
212+
"version-string": "0.0.1",
236213
"dependencies": [
237214
"fmt"
238215
]
@@ -246,11 +223,6 @@ cmake_minimum_required(VERSION 3.14)
246223
247224
project(example CXX)
248225
249-
if(EXISTS CACHE{VCPKG_MANIFEST_FILE})
250-
vcpkg_acquire_dependencies()
251-
endif()
252-
253-
254226
add_executable(example src/main.cxx)
255227
256228
find_package(fmt REQUIRED)
@@ -285,7 +257,9 @@ Hello, world!
285257
* Does not have multiple consecutive hyphens
286258
* Does not begin nor end with a hyphen
287259
* Is not a Windows filesystem reserved name
288-
* Is not a vcpkg reserved name: "default".
260+
* Is not a vcpkg reserved name: "default" or "core".
261+
* In other words, it must follow the regex `[a-z0-9]+(-[a-z0-9]+)*`, and must not be any of:
262+
* `{ prn, aux, nul, con, lpt[1-9], com[1-9], core, default }`
289263
* `<package-name>`: A `string` consisting of a non-zero number of `<identifier>`s, separated by `.`.
290264
* `a.b.c` is valid
291265
* `a` is valid
@@ -296,15 +270,29 @@ Hello, world!
296270
* `"name"`: A `<package-name>`
297271
* Optionally, `"features"`: an array of `<identifier>`s corresponding to features in the package.
298272
* Optionally, `"default-features"`: a `boolean`. If this is false, then don't use the default features of the package; equivalent to core in existing CONTROL files. If this is true, do the default thing of including the default features.
299-
* Optionally, `"platform"`: a `<platform-specification>`
273+
* Optionally, `"platform"`: a `<platform-expression>`
300274
* `<dependency.port>`: No extra fields are required.
301-
* `<license-string>`: An SPDX license expression at version 3.8.
302-
* `<platform-specification>`: A specification of a set of platforms; used in platform-specific dependencies and supports fields. One of:
303-
* `<platform-specification.exact>`: A string denoting a triplet tag like “windows”, “osx”, etc.
304-
* `<platform-specification.not>`: An object containing a member with key "not" and value `<platform-specification>`.
305-
* `<platform-specification.and>`: An object containing a member with key "and" and value array of `<platform-specification>`s.
306-
* `<platform-specification.or>`: An object containing a member with key "or" and value array of `<platform-specification>`s.
275+
* `<license-string>`: An SPDX license expression at version 3.9.
276+
* `<platform-expression>`: A specification of a set of platforms; used in platform-specific dependencies and supports fields. A string that is parsed as follows:
277+
* `<platform-expression>`:
278+
* `<platform-expression.not>`
279+
* `<platform-expression.and>`
280+
* `<platform-expression.or>`
281+
* `<platform-expression.simple>`:
282+
* `( <platform-expression> )`
283+
* `<platform-expression.identifier>`
284+
* `<platform-expression.identifier>`:
285+
* regex: `/^[a-z0-9]+$/`
286+
* `<platform-expression.not>`:
287+
* `<platform-expression.simple>`
288+
* `! <platform-expression.simple>`
289+
* `<platform-expression.and>`
290+
* `<platform-expression.not>`
291+
* `<platform-expression.and> & <platform-expression.not>`
292+
* `<platform-expression.or>`
293+
* `<platform-expression.not>`
294+
* `<platform-expression.or> | <platform-expression.not>`
307295
* `<feature>`: An object containing the following:
308296
* `"name"`: An `<identifier>`, the name of the feature
309-
* `"description"`: A `string`, the description of the feature
297+
* `"description"`: A `string` or array of `string`s, the description of the feature
310298
* Optionally, `"dependencies"`: An array of `<dependency>`s, the dependencies used by this feature

docs/users/config-environment.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ subject to change without notice and should be considered highly unstable.
1515
Non-exhaustive list of off-by-default features:
1616

1717
- `binarycaching`
18+
- `manifest`
1819

1920
#### EDITOR
2021

ports/3fd/CONTROL

-4
This file was deleted.

ports/3fd/vcpkg.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "3fd",
3+
"version-string": "2.6.2",
4+
"port-version": 3,
5+
"description": "C++ Framework For Fast Development",
6+
"dependencies": [
7+
{
8+
"name": "boost-lockfree",
9+
"platform": "windows"
10+
},
11+
{
12+
"name": "boost-regex",
13+
"platform": "windows"
14+
},
15+
{
16+
"name": "poco",
17+
"platform": "windows"
18+
},
19+
"sqlite3",
20+
"rapidxml"
21+
]
22+
}

ports/abseil/CONTROL

-10
This file was deleted.

ports/abseil/vcpkg.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "abseil",
3+
"version-string": "2020-03-03",
4+
"port-version": 7,
5+
"homepage": "https://github.com/abseil/abseil-cpp",
6+
"description": [
7+
"an open-source collection designed to augment the C++ standard library.",
8+
"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.",
9+
"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.",
10+
"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."
11+
],
12+
"features": [
13+
{
14+
"name": "cxx17",
15+
"description": "Enable compiler C++17."
16+
}
17+
]
18+
}

ports/argparse/CONTROL

-4
This file was deleted.

ports/argparse/vcpkg.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "argparse",
3+
"version-string": "2.1",
4+
"description": "Argument parser for modern C++",
5+
"license": "MIT",
6+
"homepage": "https://github.com/p-ranav/argparse"
7+
}

ports/avisynthplus/CONTROL

-5
This file was deleted.

ports/avisynthplus/vcpkg.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "avisynthplus",
3+
"version-string": "3.6.0",
4+
"homepage": "http://avs-plus.net/",
5+
"description": "An improved version of the AviSynth frameserver, with improved features and developer friendliness",
6+
"supports": "!(uwp | arm | static)"
7+
}

ports/cmocka/CONTROL

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Source: cmocka
2-
Version: 1.1.5-1
2+
Version: 1.1.5
3+
Port-Version: 2
34
Description: An elegant unit testing framework for C with support for mock objects

ports/cmocka/vcpkg-cmake-wrapper.cmake

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ _find_package(${ARGS})
33
get_filename_component(_cmocka_lib_name ${CMOCKA_LIBRARY} NAME)
44

55
set(CMOCKA_LIBRARY
6-
debug ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/lib/${_cmocka_lib_name}
7-
optimized ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/${_cmocka_lib_name}
6+
debug ${CURRENT_INSTALLED_DIR}/debug/lib/${_cmocka_lib_name}
7+
optimized ${CURRENT_INSTALLED_DIR}/lib/${_cmocka_lib_name}
88
)
99

1010
set(CMOCKA_LIBRARIES ${CMOCKA_LIBRARY})

ports/libarchive/CONTROL

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Source: libarchive
2-
Version: 3.4.1-3
2+
Version: 3.4.1
3+
Port-Version: 4
34
Homepage: https://github.com/libarchive/libarchive
45
Description: Library for reading and writing streaming archives
56
Build-Depends: zlib

0 commit comments

Comments
 (0)