]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/tools/vcpkg/docs/maintainers/maintainer-guide.md
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / tools / vcpkg / docs / maintainers / maintainer-guide.md
1 # Maintainer Guidelines and Policies
2
3 This document lists a set of policies that you should apply when adding or updating a port recipe.
4 It is intended to serve the role of
5 [Debian's Policy Manual](https://www.debian.org/doc/debian-policy/),
6 [Homebrew's Maintainer Guidelines](https://docs.brew.sh/Maintainer-Guidelines), and
7 [Homebrew's Formula Cookbook](https://docs.brew.sh/Formula-Cookbook).
8
9 ## PR Structure
10
11 ### Make separate Pull Requests per port
12
13 Whenever possible, separate changes into multiple PRs.
14 This makes them significantly easier to review and prevents issues with one set of changes from holding up every other change.
15
16 ### Avoid trivial changes in untouched files
17
18 For example, avoid reformatting or renaming variables in portfiles that otherwise have no reason to be modified for the issue at hand.
19 However, if you need to modify the file for the primary purpose of the PR (updating the library),
20 then obviously beneficial changes like fixing typos are appreciated!
21
22 ### Check names against other repositories
23
24 A good service to check many at once is [Repology](https://repology.org/).
25 If the library you are adding could be confused with another one,
26 consider renaming to make it clear.
27
28 ### Use GitHub Draft PRs
29
30 GitHub Draft PRs are a great way to get CI or human feedback on work that isn't yet ready to merge.
31 Most new PRs should be opened as drafts and converted to normal PRs once the CI passes.
32
33 More information about GitHub Draft PRs:
34 https://github.blog/2019-02-14-introducing-draft-pull-requests/
35
36 ## Portfiles
37
38 ### Avoid deprecated helper functions
39
40 At this time, the following helpers are deprecated:
41
42 1. `vcpkg_extract_source_archive()` should be replaced by [`vcpkg_extract_source_archive_ex()`](vcpkg_extract_source_archive_ex.md)
43 2. `vcpkg_apply_patches()` should be replaced by the `PATCHES` arguments to the "extract" helpers (e.g. [`vcpkg_from_github()`](vcpkg_from_github.md))
44 3. `vcpkg_build_msbuild()` should be replaced by [`vcpkg_install_msbuild()`](vcpkg_install_msbuild.md)
45 4. `vcpkg_copy_tool_dependencies()` should be replaced by [`vcpkg_copy_tools()`](vcpkg_copy_tools.md)
46
47 ### Avoid excessive comments in portfiles
48
49 Ideally, portfiles should be short, simple, and as declarative as possible.
50 Remove any boiler plate comments introduced by the `create` command before submitting a PR.
51
52 ## Features
53
54 ### Do not use features to implement alternatives
55
56 Features must be treated as additive functionality. If port[featureA] installs and port[featureB] installs, then port[featureA,featureB] must install. Moreover, if a second port depends on [featureA] and a third port depends on [featureB], installing both the second and third ports should have their dependencies satisfied.
57
58 Libraries in this situation must choose one of the available options as expressed in vcpkg, and users who want a different setting must use overlay ports at this time.
59
60 Existing examples we would not accept today retained for backwards compatibility:
61 * `libgit2`, `libzip`, `open62541` all have features for selecting a TLS or crypto backend. Note that `curl` has different crypto backend options but allows selecting between them at runtime, meaning the above tenet is maintained.
62 * `darknet` has `opencv2`, `opencv3`, features to control which version of opencv to use for its dependencies.
63
64 ### A feature may engage preview or beta functionality
65
66 Notwithstanding the above, if there is a preview branch or similar where the preview functionality has a high probability of not disrupting the non-preview functionality (for example, no API removals), a feature is acceptable to model this setting.
67
68 Examples:
69 * The Azure SDKs (of the form `azure-Xxx`) have a `public-preview` feature.
70 * `imgui` has an `experimental-docking` feature which engages their preview docking branch which uses a merge commit attached to each of their public numbered releases.
71
72 ### Default features should enable behaviors, not APIs
73
74 If a consumer is depending directly upon a library, they can list out any desired features easily (`library[feature1,feature2]`). However, if a consumer _does not know_ they are using a library, they cannot list out those features. If that hidden library is like `libarchive` where features are adding additional compression algorithms (and thus behaviors) to an existing generic interface, default features offer a way to ensure a reasonably functional transitive library is built even if the final consumer doesn't name it directly.
75
76 If the feature adds additional APIs (or executables, or library binaries) and doesn't modify the behavior of existing APIs, it should be left off by default. This is because any consumer which might want to use those APIs can easily require it via their direct reference.
77
78 If in doubt, do not mark a feature as default.
79
80 ### Do not use features to control alternatives in published interfaces
81
82 If a consumer of a port depends on only the core functionality of that port, with high probability they must not be broken by turning on the feature. This is even more important when the alternative is not directly controlled by the consumer, but by compiler settings like `/std:c++17` / `-std=c++17`.
83
84 Existing examples we would not accept today retained for backwards compatibility:
85 * `redis-plus-plus[cxx17]` controls a polyfill but does not bake the setting into the installed tree.
86 * `ace[wchar]` changes all APIs to accept `const wchar_t*` rather than `const char*`.
87
88 ### A feature may replace polyfills with aliases provided that replacement is baked into the installed tree
89
90 Notwithstanding the above, ports may remove polyfills with a feature, as long as:
91 1. Turning on the feature changes the polyfills to aliases of the polyfilled entity
92 2. The state of the polyfill is baked into the installed headers, such that ABI mismatch "impossible" runtime errors are unlikely
93 3. It is possible for a consumer of the port to write code which works in both modes, for example by using a typedef which is either polyfilled or not
94
95 Example:
96 * `abseil[cxx17]` changes `absl::string_view` to a replacement or `std::string_view`; the patch
97 https://github.com/microsoft/vcpkg/blob/981e65ce0ac1f6c86e5a5ded7824db8780173c76/ports/abseil/fix-cxx-standard.patch implements the baking requirement
98
99 ### Recommended solutions
100
101 If it's critical to expose the underlying alternatives, we recommend providing messages at build time to instruct the user on how to copy the port into a private overlay:
102 ```cmake
103 set(USING_DOG 0)
104 message(STATUS "This version of LibContosoFrobnicate uses the Kittens backend. To use the Dog backend instead, create an overlay port of this with USING_DOG set to 1 and the `kittens` dependency replaced with `dog`.")
105 message(STATUS "This recipe is at ${CMAKE_CURRENT_LIST_DIR}")
106 message(STATUS "See the overlay ports documentation at https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md")
107 ```
108
109 ## Build Techniques
110
111 ### Do not use vendored dependencies
112
113 Do not use embedded copies of libraries.
114 All dependencies should be split out and packaged separately so they can be updated and maintained.
115
116 ### Prefer using CMake
117
118 When multiple buildsystems are available, prefer using CMake.
119 Additionally, when appropriate, it can be easier and more maintainable to rewrite alternative buildsystems into CMake using `file(GLOB)` directives.
120
121 Examples: [abseil](../../ports/abseil/portfile.cmake)
122
123 ### Choose either static or shared binaries
124
125 By default, `vcpkg_configure_cmake()` will pass in the appropriate setting for `BUILD_SHARED_LIBS`,
126 however for libraries that don't respect that variable, you can switch on `VCPKG_LIBRARY_LINKAGE`:
127
128 ```cmake
129 string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" KEYSTONE_BUILD_STATIC)
130 string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" KEYSTONE_BUILD_SHARED)
131
132 vcpkg_configure_cmake(
133 SOURCE_PATH ${SOURCE_PATH}
134 PREFER_NINJA
135 OPTIONS
136 -DKEYSTONE_BUILD_STATIC=${KEYSTONE_BUILD_STATIC}
137 -DKEYSTONE_BUILD_SHARED=${KEYSTONE_BUILD_SHARED}
138 )
139 ```
140
141 ### When defining features, explicitly control dependencies
142
143 When defining a feature that captures an optional dependency,
144 ensure that the dependency will not be used accidentally when the feature is not explicitly enabled.
145
146 ```cmake
147 if ("zlib" IN_LIST FEATURES)
148 set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
149 else()
150 set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
151 endif()
152
153 vcpkg_configure_cmake(
154 SOURCE_PATH ${SOURCE_PATH}
155 PREFER_NINJA
156 OPTIONS
157 -CMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
158 )
159 ```
160
161 The snippet below using `vcpkg_check_features()` is equivalent, [see the documentation](vcpkg_check_features.md).
162
163 ```cmake
164 vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
165 INVERTED_FEATURES
166 "zlib" CMAKE_DISABLE_FIND_PACKAGE_ZLIB
167 )
168
169 vcpkg_configure_cmake(
170 SOURCE_PATH ${SOURCE_PATH}
171 PREFER_NINJA
172 OPTIONS
173 ${FEATURE_OPTIONS}
174 )
175 ```
176
177 Note that `ZLIB` in the above is case-sensitive. See the [cmake documentation](https://cmake.org/cmake/help/v3.15/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.html) for more details.
178
179 ### Place conflicting libs in a `manual-link` directory
180
181 A lib is considered conflicting if it does any of the following:
182 + Define `main`
183 + Define malloc
184 + Define symbols that are also declared in other libraries
185
186 Conflicting libs are typically by design and not considered a defect. Because some build systems link against everything in the lib directory, these should be moved into a subdirectory named `manual-link`.
187
188 ## Manifests and CONTROL files
189
190 When adding a new port, use the new manifest syntax for defining a port;
191 you may also change over to manifests when modifying an existing port.
192 You may do so easily by running the `vcpkg format-manifest` command, which will convert existing CONTROL
193 files into manifest files. Do not convert CONTROL files that have not been modified.
194
195 ## Versioning
196
197 ### Follow common conventions for the `"version"` field
198
199 See our [versioning documentation](../users/versioning.md#version-schemes) for a full explanation of our conventions.
200
201 ### Update the `"port-version"` field in the manifest file of any modified ports
202
203 Vcpkg uses this field to determine whether a given port is out-of-date and should be changed whenever the port's behavior changes.
204
205 Our convention is to use the `"port-version"` field for changes to the port that don't change the upstream version, and to reset the `"port-version"` back to zero when an update to the upstream version is made.
206
207 For Example:
208
209 - Zlib's package version is currently `1.2.1`, with no explicit `"port-version"` (equivalent to a `"port-version"` of `0`).
210 - You've discovered that the wrong copyright file has been deployed, and fixed that in the portfile.
211 - You should update the `"port-version"` field in the manifest file to `1`.
212
213 See our [manifest files document](manifest-files.md#port-version) for a full explanation of our conventions.
214
215 ### Update the version files in `versions/` of any modified ports
216
217 Vcpkg uses a set of metadata files to power its versioning feature.
218 These files are located in the following locations:
219 * `${VCPKG_ROOT}/versions/baseline.json`, (this file is common to all ports) and
220 * `${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json` (one per port).
221
222 For example, for `zlib` the relevant files are:
223 * `${VCPKG_ROOT}/versions/baseline.json`
224 * `${VCPKG_ROOT}/versions/z-/zlib.json`
225
226 We expect that each time you update a port, you also update its version files.
227
228 **The recommended method to update these files is to run the `x-add-version` command, e.g.:**
229
230 ```
231 vcpkg x-add-version zlib
232 ```
233
234 If you're updating multiple ports at the same time, instead you can run:
235
236 ```
237 vcpkg x-add-version --all
238 ```
239
240 To update the files for all modified ports at once.
241
242 _NOTE: These commands require you to have committed your changes to the ports before running them. The reason is that the Git SHA of the port directory is required in these version files. But don't worry, the `x-add-version` command will warn you if you have local changes that haven't been committed._
243
244 See our [versioning specification](../specifications/versioning.md) and [registries specification](../specifications/registries-2.md) to learn how vcpkg interacts with these files.
245
246 ## Patching
247
248 ### Prefer options over patching
249
250 It is preferable to set options in a call to `vcpkg_configure_xyz()` over patching the settings directly.
251
252 Common options that allow avoiding patching:
253 1. [MSBUILD] `<PropertyGroup>` settings inside the project file can be overridden via `/p:` parameters
254 2. [CMAKE] Calls to `find_package(XYz)` in CMake scripts can be disabled via [`-DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON`](https://cmake.org/cmake/help/v3.15/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.html)
255 3. [CMAKE] Cache variables (declared as `set(VAR "value" CACHE STRING "Documentation")` or `option(VAR "Documentation" "Default Value")`) can be overridden by just passing them in on the command line as `-DVAR:STRING=Foo`. One notable exception is if the `FORCE` parameter is passed to `set()`. See also the [CMake `set` documentation](https://cmake.org/cmake/help/v3.15/command/set.html)
256
257 ### Prefer patching over overriding `VCPKG_<VARIABLE>` values
258
259 Some variables prefixed with `VCPKG_<VARIABLE>` have an equivalent `CMAKE_<VARIABLE>`.
260 However, not all of them are passed to the internal package build [(see implementation: Windows toolchain)](../../scripts/toolchains/windows.cmake).
261
262 Consider the following example:
263
264 ```cmake
265 set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
266 set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")
267 ```
268
269 Using `vcpkg`'s built-in toolchains this works, because the value of `VCPKG_<LANG>_FLAGS` is forwarded to the appropriate `CMAKE_LANG_FLAGS` variable. But, a custom toolchain that is not aware of `vcpkg`'s variables will not forward them.
270
271 Because of this, it is preferable to patch the buildsystem directly when setting `CMAKE_<LANG>_FLAGS`.
272
273 ### Minimize patches
274
275 When making changes to a library, strive to minimize the final diff. This means you should _not_ reformat the upstream source code when making changes that affect a region. Also, when disabling a conditional, it is better to add a `AND FALSE` or `&& 0` to the condition than to delete every line of the conditional.
276
277 This helps to keep the size of the vcpkg repository down as well as improves the likelihood that the patch will apply to future code versions.
278
279 ### Do not implement features in patches
280
281 The purpose of patching in vcpkg is to enable compatibility with compilers, libraries, and platforms. It is not to implement new features in lieu of following proper Open Source procedure (submitting an Issue/PR/etc).
282
283 ## Do not build tests/docs/examples by default
284
285 When submitting a new port, check for any options like `BUILD_TESTS` or `WITH_TESTS` or `POCO_ENABLE_SAMPLES` and ensure the additional binaries are disabled. This minimizes build times and dependencies for the average user.
286
287 Optionally, you can add a `test` feature which enables building the tests, however this should not be in the `Default-Features` list.
288
289 ## Enable existing users of the library to switch to vcpkg
290
291 ### Do not add `CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS`
292
293 Unless the author of the library is already using it, we should not use this CMake functionality because it interacts poorly with C++ templates and breaks certain compiler features. Libraries that don't provide a .def file and do not use __declspec() declarations simply do not support shared builds for Windows and should be marked as such with `vcpkg_check_linkage(ONLY_STATIC_LIBRARY)`.
294
295 ### Do not rename binaries outside the names given by upstream
296
297 This means that if the upstream library has different names in release and debug (libx versus libxd), then the debug library should not be renamed to `libx`. Vice versa, if the upstream library has the same name in release and debug, we should not introduce a new name.
298
299 Important caveat:
300 - Static and shared variants often should be renamed to a common scheme. This enables consumers to use a common name and be ignorant of the downstream linkage. This is safe because we only make one at a time available.
301
302 Note that if a library generates CMake integration files (`foo-config.cmake`), renaming must be done through patching the CMake build itself instead of simply calling `file(RENAME)` on the output archives/LIBs.
303
304 Finally, DLL files on Windows should never be renamed post-build because it breaks the generated LIBs.
305
306 ## Code format
307
308 ### Vcpkg internal code
309
310 We require the C++ code inside vcpkg to follow the clang-format, if you change them. Please perform the following steps after modification:
311
312 - Use Visual Studio:
313 1. Configure your [clang-format tools](https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/).
314 2. Open the modified file.
315 3. Use shortcut keys Ctrl+K, Ctrl+D to format the current file.
316
317 - Use tools:
318 1. Install [llvm clang-format](https://releases.llvm.org/download.html#10.0.0)
319 2. Run command:
320 ```cmd
321 > LLVM_PATH/bin/clang-format.exe -style=file -i changed_file.cpp
322 ```
323
324 ### Manifests
325
326 We require that the manifest file be formatted. Use the following command to format all manifest files:
327
328 ```cmd
329 > vcpkg format-manifest --all
330 ```
331
332 ## Useful implementation notes
333
334 ### Portfiles are run in Script Mode
335
336 While `portfile.cmake`'s and `CMakeLists.txt`'s share a common syntax and core CMake language constructs, portfiles run in "Script Mode", whereas `CMakeLists.txt` files run in "Build Mode" (unofficial term). The most important difference between these two modes is that "Script Mode" does not have a concept of "Target" -- any behaviors that depend on the "target" machine (`CMAKE_CXX_COMPILER`, `CMAKE_EXECUTABLE_SUFFIX`, `CMAKE_SYSTEM_NAME`, etc) will not be correct.
337
338 Portfiles have direct access to variables set in the triplet file, but `CMakeLists.txt`s do not (though there is often a translation that happens -- `VCPKG_LIBRARY_LINKAGE` versus `BUILD_SHARED_LIBS`).
339
340 Portfiles and CMake builds invoked by portfiles are run in different processes. Conceptually:
341
342 ```no-highlight
343 +----------------------------+ +------------------------------------+
344 | CMake.exe | | CMake.exe |
345 +----------------------------+ +------------------------------------+
346 | Triplet file | ====> | Toolchain file |
347 | (x64-windows.cmake) | | (scripts/buildsystems/vcpkg.cmake) |
348 +----------------------------+ +------------------------------------+
349 | Portfile | ====> | CMakeLists.txt |
350 | (ports/foo/portfile.cmake) | | (buildtrees/../CMakeLists.txt) |
351 +----------------------------+ +------------------------------------+
352 ```
353
354 To determine the host in a portfile, the standard CMake variables are fine (`CMAKE_HOST_WIN32`).
355
356 To determine the target in a portfile, the vcpkg triplet variables should be used (`VCPKG_CMAKE_SYSTEM_NAME`).
357
358 See also our [triplet documentation](../users/triplets.md) for a full enumeration of possible settings.