diff options
| author | nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> | 2021-07-14 14:45:18 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-14 12:45:18 -0700 |
| commit | d369df7ecf194005eaca46f07368779cd486badd (patch) | |
| tree | 419f9861b796a7dc6e53646df13642c6c71108f2 /docs/maintainers/cmake-guidelines.md | |
| parent | 932df5b8ede16b73fc5508445140d5b360ea0c68 (diff) | |
| download | vcpkg-d369df7ecf194005eaca46f07368779cd486badd.tar.gz vcpkg-d369df7ecf194005eaca46f07368779cd486badd.zip | |
[rollup:2021-07-06] Rollup PR (#18838)
* [rollup:2021-07-06 1/8] PR #18272 (@strega-nil)
[scripts-audit] vcpkg_from_*
* [rollup:2021-07-06 2/8] PR #18319 (@strega-nil)
[scripts-audit] add guidelines for cmake
* [rollup 2021-07-06 3/8] PR #18410 (@mheyman)
[vcpkg-cmake-config] documentation fix
* [rollup:2021-07-06 4/8] PR #18488 (@strega-nil)
[scripts-audit] vcpkg_execute_*
* [rollup:2021-07-06 5/8] PR #18517 (@strega-nil)
[scripts-audit] vcpkg_extract_source_archive
* [rollup:2021-07-06 6/8] PR #18674 (@NancyLi1013)
[vcpkg doc] Update examples
* [rollup:2021-07-06 7/8] PR #18695 (@JackBoosY)
[vcpkg] Update the minimum version of vcpkg
* [rollup:2021-07-06 8/8] PR #18758 (@ras0219-msft)
[vcpkg_from_git] Fix error if downloads folder does not exist
* build docs!
* fix bond:*-windows
* fix nmap
Co-authored-by: nicole mazzuca <mazzucan@outlook.com>
Co-authored-by: Michael Heyman <Michael.Heyman@jhuapl.edu>
Co-authored-by: NancyLi1013 <lirui09@beyondsoft.com>
Co-authored-by: JackBoosY <yuzaiyang@beyondsoft.com>
Co-authored-by: Robert Schumacher <ras0219@outlook.com>
Diffstat (limited to 'docs/maintainers/cmake-guidelines.md')
| -rw-r--r-- | docs/maintainers/cmake-guidelines.md | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/docs/maintainers/cmake-guidelines.md b/docs/maintainers/cmake-guidelines.md new file mode 100644 index 000000000..77cdf7372 --- /dev/null +++ b/docs/maintainers/cmake-guidelines.md @@ -0,0 +1,127 @@ +# CMake Guidelines
+
+We expect that all CMake scripts that are either:
+
+- In the `scripts/` directory, or
+- In a `vcpkg-*` port
+
+should follow the guidelines laid out in this document.
+Existing scripts may not follow these guidelines yet;
+it is expected that we will continue to update old scripts
+to fall in line with these guidelines.
+
+These guidelines are intended to create stability in our scripts.
+We hope that they will make both forwards and backwards compatibility easier.
+
+## The Guidelines
+
+- Except for out-parameters, we always use `cmake_parse_arguments()`
+ rather than function parameters or referring to `${ARG<N>}`.
+ - This doesn't necessarily need to be followed for "script-local helper functions"
+ - In this case, positional parameters should be put in the function
+ declaration (rather than using `${ARG<N>}`),
+ and should be named according to local rules (i.e. `snake_case`).
+ - Exception: positional parameters that are optional should be
+ given a name via `set(argument_name "${ARG<N>}")`, after checking `ARGC`.
+ - Out-parameters should be the first parameter to a function. Example:
+ ```cmake
+ function(format out_var)
+ cmake_parse_arguments(PARSE_ARGV 1 "arg" ...)
+ # ... set(buffer "output")
+ set("${out_var}" "${buffer}" PARENT_SCOPE)
+ endfunction()
+ ```
+- There are no unparsed or unused arguments.
+ Always check for `ARGN` or `arg_UNPARSED_ARGUMENTS`.
+ `FATAL_ERROR` when possible, `WARNING` if necessary for backwards compatibility.
+- All `cmake_parse_arguments` must use `PARSE_ARGV`.
+- All `foreach` loops must use `IN LISTS` and `IN ITEMS`.
+- The variables `${ARGV}` and `${ARGN}` are unreferenced,
+ except in helpful messages to the user.
+ - (i.e., `message(FATAL_ERROR "blah was passed extra arguments: ${ARGN}")`)
+- We always use functions, not macros or top level code.
+ - Exception: "script-local helper macros". It is sometimes helpful to define a small macro.
+ This should be done sparingly, and functions should be preferred.
+ - Exception: `vcpkg.cmake`'s `find_package`.
+- Scripts in the scripts tree should not be expected to need observable changes
+ as part of normal operation.
+ - Example violation: `vcpkg_acquire_msys()` has hard-coded packages and versions that need updating over time due to the MSYS project dropping old packages.
+ - Example exception: `vcpkg_from_sourceforge()` has a list of mirrors which needs maintenance but does not have an observable behavior impact on the callers.
+- All variable expansions are in quotes `""`,
+ except those which are intended to be passed as multiple arguments.
+ - Example:
+ ```cmake
+ set(working_directory "")
+ if(DEFINED arg_WORKING_DIRECTORY)
+ set(working_directory "WORKING_DIRECTORY" "${arg_WORKING_DIRECTORY}")
+ endif()
+ # calls do_the_thing() if NOT DEFINED arg_WORKING_DIRECTORY,
+ # else calls do_the_thing(WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}")
+ do_the_thing(${working_directory})
+ ```
+- There are no "pointer" or "in-out" parameters
+ (where a user passes a variable name rather than the contents),
+ except for simple out-parameters.
+- Variables are not assumed to be empty.
+ If the variable is intended to be used locally,
+ it must be explicitly initialized to empty with `set(foo "")`.
+- All variables expected to be inherited from the parent scope across an API boundary (i.e. not a file-local function) should be documented. Note that all variables mentioned in triplets.md are considered documented.
+- Out parameters are only set in `PARENT_SCOPE` and are never read.
+ See also the helper `z_vcpkg_forward_output_variable()` to forward out parameters through a function scope.
+- `CACHE` variables are used only for global variables which are shared internally among strongly coupled
+ functions and for internal state within a single function to avoid duplicating work.
+ These should be used extremely sparingly and should use the `Z_VCPKG_` prefix to avoid
+ colliding with any local variables that would be defined by any other code.
+ - Examples:
+ - `vcpkg_cmake_configure`'s `Z_VCPKG_CMAKE_GENERATOR`
+ - `z_vcpkg_get_cmake_vars`'s `Z_VCPKG_GET_CMAKE_VARS_FILE`
+- `include()`s are only allowed in `ports.cmake` or `vcpkg-port-config.cmake`.
+- `foreach(RANGE)`'s arguments _must always be_ natural numbers,
+ and `<start>` _must always be_ less than or equal to `<stop>`.
+ - This must be checked by something like:
+ ```cmake
+ if(start LESS_EQUAL end)
+ foreach(RANGE start end)
+ ...
+ endforeach()
+ endif()
+ ```
+- All port-based scripts must use `include_guard(GLOBAL)`
+ to avoid being included multiple times.
+- `set(var)` should not be used. Use `unset(var)` to unset a variable,
+ and `set(var "")` to set it to the empty value. _Note: this works for use as a list and as a string_
+
+### CMake Versions to Require
+
+- All CMake scripts, except for `vcpkg.cmake`,
+ may assume the version of CMake that is present in the
+ `cmake_minimum_required` of `ports.cmake`.
+ - This `cmake_minimum_required` should be bumped every time a new version
+ of CMake is added to `vcpkgTools.xml`, as should the
+ `cmake_minimum_required` in all of the helper `CMakeLists.txt` files.
+- `vcpkg.cmake` must assume a version of CMake back to 3.1 in general
+ - Specific functions and options may assume a greater CMake version;
+ if they do, make sure to comment that function or option
+ with the required CMake version.
+
+
+### Changing Existing Functions
+
+- Never remove arguments in non-internal functions;
+ if they should no longer do anything, just take them as normal and warn on use.
+- Never add a new mandatory argument.
+
+### Naming Variables
+
+- `cmake_parse_arguments`: set prefix to `"arg"`
+- Local variables are named with `snake_case`
+- Internal global variable names are prefixed with `Z_VCPKG_`.
+- External experimental global variable names are prefixed with `X_VCPKG_`.
+
+- Internal functions are prefixed with `z_vcpkg_`
+ - Functions which are internal to a single function (i.e., helper functions)
+ are named `[z_]<func>_<name>`, where `<func>` is the name of the function they are
+ a helper to, and `<name>` is what the helper function does.
+ - `z_` should be added to the front if `<func>` doesn't have a `z_`,
+ but don't name a helper function `z_z_foo_bar`.
+- Public global variables are named `VCPKG_`.
|
