From d369df7ecf194005eaca46f07368779cd486badd Mon Sep 17 00:00:00 2001 From: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> Date: Wed, 14 Jul 2021 14:45:18 -0500 Subject: [PATCH] [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 Co-authored-by: Michael Heyman Co-authored-by: NancyLi1013 Co-authored-by: JackBoosY Co-authored-by: Robert Schumacher --- docs/README.md | 1 + docs/maintainers/cmake-guidelines.md | 127 +++++++++ .../z_vcpkg_forward_output_variable.md | 38 +++ docs/maintainers/portfile-functions.md | 1 + .../vcpkg_cmake_config_fixup.md | 2 +- docs/maintainers/vcpkg_clean_msbuild.md | 2 +- docs/maintainers/vcpkg_download_distfile.md | 6 + .../vcpkg_execute_in_download_mode.md | 21 +- .../vcpkg_execute_required_process_repeat.md | 3 +- .../vcpkg_extract_source_archive.md | 71 ++++- .../vcpkg_extract_source_archive_ex.md | 54 +--- docs/maintainers/vcpkg_from_bitbucket.md | 1 - docs/maintainers/vcpkg_from_git.md | 11 +- docs/maintainers/vcpkg_from_sourceforge.md | 7 +- docs/maintainers/vcpkg_install_msbuild.md | 4 +- docs/regenerate.ps1 | 3 +- ports/avisynthplus/portfile.cmake | 4 +- ports/avisynthplus/vcpkg.json | 1 + ports/bond/CONTROL | 9 - ports/bond/portfile.cmake | 10 +- ports/bond/vcpkg.json | 22 ++ ports/nmap/CONTROL | 4 - ports/nmap/portfile.cmake | 33 +-- ports/nmap/vcpkg.json | 25 ++ ports/opencv3/portfile.cmake | 4 +- ports/opencv3/vcpkg.json | 1 + ports/qcustomplot/CONTROL | 4 - ports/qcustomplot/portfile.cmake | 4 +- ports/qcustomplot/vcpkg.json | 12 + ports/qt5-mqtt/CONTROL | 4 - ports/qt5-mqtt/portfile.cmake | 9 +- ports/qt5-mqtt/vcpkg.json | 12 + ports/vcpkg-cmake-config/vcpkg.json | 3 +- .../vcpkg_cmake_config_fixup.cmake | 2 +- scripts/buildsystems/vcpkg.cmake | 4 +- scripts/cmake/execute_process.cmake | 3 + scripts/cmake/vcpkg_clean_msbuild.cmake | 2 +- scripts/cmake/vcpkg_download_distfile.cmake | 15 +- .../cmake/vcpkg_execute_build_process.cmake | 191 +++++++------- .../vcpkg_execute_in_download_mode.cmake | 82 +++--- .../vcpkg_execute_required_process.cmake | 121 +++++---- ...cpkg_execute_required_process_repeat.cmake | 85 ++++-- .../cmake/vcpkg_extract_source_archive.cmake | 242 ++++++++++++++++-- .../vcpkg_extract_source_archive_ex.cmake | 156 ++--------- .../cmake/vcpkg_find_acquire_program.cmake | 4 + scripts/cmake/vcpkg_from_bitbucket.cmake | 182 +++++-------- scripts/cmake/vcpkg_from_git.cmake | 192 +++++++------- scripts/cmake/vcpkg_from_github.cmake | 204 ++++++--------- scripts/cmake/vcpkg_from_gitlab.cmake | 186 +++++++------- scripts/cmake/vcpkg_from_sourceforge.cmake | 118 ++++----- scripts/cmake/vcpkg_install_msbuild.cmake | 4 +- .../z_vcpkg_forward_output_variable.cmake | 48 ++++ scripts/detect_compiler/CMakeLists.txt | 2 +- scripts/get_cmake_vars/CMakeLists.txt | 2 +- scripts/ports.cmake | 5 +- scripts/vcpkgTools.xml | 7 - versions/a-/avisynthplus.json | 5 + versions/b-/bond.json | 5 + versions/baseline.json | 18 +- versions/n-/nmap.json | 5 + versions/o-/opencv3.json | 5 + versions/q-/qcustomplot.json | 5 + versions/q-/qt5-mqtt.json | 5 + versions/v-/vcpkg-cmake-config.json | 5 + 64 files changed, 1393 insertions(+), 1030 deletions(-) create mode 100644 docs/maintainers/cmake-guidelines.md create mode 100644 docs/maintainers/internal/z_vcpkg_forward_output_variable.md delete mode 100644 ports/bond/CONTROL create mode 100644 ports/bond/vcpkg.json delete mode 100644 ports/nmap/CONTROL create mode 100644 ports/nmap/vcpkg.json delete mode 100644 ports/qcustomplot/CONTROL create mode 100644 ports/qcustomplot/vcpkg.json delete mode 100644 ports/qt5-mqtt/CONTROL create mode 100644 ports/qt5-mqtt/vcpkg.json create mode 100644 scripts/cmake/z_vcpkg_forward_output_variable.cmake diff --git a/docs/README.md b/docs/README.md index 04d9557112125b..7ef5c0d0659269 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,6 +33,7 @@ Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS. This too - [Common CMake definitions](maintainers/vcpkg_common_definitions.md) - [Maintainer Guidelines](maintainers/maintainer-guide.md) - [Creating Registries](maintainers/registries.md) +- [CMake Guidelines](maintainers/cmake-guidelines.md) ### [Vcpkg-Tool](https://github.com/microsoft/vcpkg-tool) Maintainer Help diff --git a/docs/maintainers/cmake-guidelines.md b/docs/maintainers/cmake-guidelines.md new file mode 100644 index 00000000000000..77cdf737204148 --- /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}`. + - 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}`), + 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}")`, 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 `` _must always be_ less than or equal to ``. + - 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_]_`, where `` is the name of the function they are + a helper to, and `` is what the helper function does. + - `z_` should be added to the front if `` doesn't have a `z_`, + but don't name a helper function `z_z_foo_bar`. +- Public global variables are named `VCPKG_`. diff --git a/docs/maintainers/internal/z_vcpkg_forward_output_variable.md b/docs/maintainers/internal/z_vcpkg_forward_output_variable.md new file mode 100644 index 00000000000000..10c5855df6dba0 --- /dev/null +++ b/docs/maintainers/internal/z_vcpkg_forward_output_variable.md @@ -0,0 +1,38 @@ +# z_vcpkg_forward_output_variable + +The latest version of this document lives in the [vcpkg repo](https://github.com/Microsoft/vcpkg/blob/master/docs/). + +This macro helps with forwarding values from inner function calls, +through a local function scope, into pointer out parameters. + +```cmake +z_vcpkg_forward_output_variable(ptr_to_parent_var var_to_forward) +``` + +is equivalent to + +```cmake +if(DEFINED ptr_to_parent_var) + if(DEFINED value_var) + set("${ptr_to_parent_var}" "${value_var}" PARENT_SCOPE) + else() + unset("${ptr_to_parent_var}" PARENT_SCOPE) + endif() +endif() +``` + +Take note that the first argument should be a local variable that has a value of the parent variable name. +Most commonly, this local is the result of a pointer-out parameter to a function. +If the variable in the first parameter is not defined, this function does nothing, +simplifying functions with optional out parameters. +Most commonly, this should be used in cases like: + +```cmake +function(my_function out_var) + file(SHA512 "somefile.txt" local_var) + z_vcpkg_forward_output_variable(out_var local_var) +endfunction() +``` + +## Source +[scripts/cmake/z\_vcpkg\_forward\_output\_variable.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/z_vcpkg_forward_output_variable.cmake) diff --git a/docs/maintainers/portfile-functions.md b/docs/maintainers/portfile-functions.md index 0b8e7f3b50dbdb..d6acc6471db91c 100644 --- a/docs/maintainers/portfile-functions.md +++ b/docs/maintainers/portfile-functions.md @@ -58,6 +58,7 @@ - [vcpkg\_internal\_get\_cmake\_vars](internal/vcpkg_internal_get_cmake_vars.md) - [z\_vcpkg\_apply\_patches](internal/z_vcpkg_apply_patches.md) +- [z\_vcpkg\_forward\_output\_variable](internal/z_vcpkg_forward_output_variable.md) - [z\_vcpkg\_function\_arguments](internal/z_vcpkg_function_arguments.md) - [z\_vcpkg\_prettify\_command\_line](internal/z_vcpkg_prettify_command_line.md) diff --git a/docs/maintainers/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.md b/docs/maintainers/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.md index 33509d1174ef8a..e4b486798ca388 100644 --- a/docs/maintainers/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.md +++ b/docs/maintainers/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.md @@ -10,7 +10,7 @@ Additionally corrects common issues with targets, such as absolute paths and inc vcpkg_cmake_config_fixup( [PACKAGE_NAME ] [CONFIG_PATH ] - [DO_NOT_DELETE_CONFIG_PATH_PARENT] + [DO_NOT_DELETE_PARENT_CONFIG_PATH] [NO_PREFIX_CORRECTION] ) ``` diff --git a/docs/maintainers/vcpkg_clean_msbuild.md b/docs/maintainers/vcpkg_clean_msbuild.md index 00e5358682bcd1..3474076b53ac31 100644 --- a/docs/maintainers/vcpkg_clean_msbuild.md +++ b/docs/maintainers/vcpkg_clean_msbuild.md @@ -11,7 +11,7 @@ vcpkg_clean_msbuild() ## Examples -* [xalan-c](https://github.com/Microsoft/vcpkg/blob/master/ports/xalan-c/portfile.cmake) +* [python3](https://github.com/Microsoft/vcpkg/blob/master/ports/python3/portfile.cmake) ## Source [scripts/cmake/vcpkg\_clean\_msbuild.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_clean_msbuild.cmake) diff --git a/docs/maintainers/vcpkg_download_distfile.md b/docs/maintainers/vcpkg_download_distfile.md index 9b1bda73738566..62fde14553073b 100644 --- a/docs/maintainers/vcpkg_download_distfile.md +++ b/docs/maintainers/vcpkg_download_distfile.md @@ -13,6 +13,7 @@ vcpkg_download_distfile( URLS ... FILENAME SHA512 <5981de...> + [ALWAYS_REDOWNLOAD] ) ``` ## Parameters @@ -38,6 +39,11 @@ Skip SHA512 hash check for file. This switch is only valid when building with the `--head` command line flag. +### ALWAYS_REDOWNLOAD +Avoid caching; this is a REST call or otherwise unstable. + +Requires `SKIP_SHA512`. + ### HEADERS A list of headers to append to the download request. This can be used for authentication during a download. diff --git a/docs/maintainers/vcpkg_execute_in_download_mode.md b/docs/maintainers/vcpkg_execute_in_download_mode.md index c4931714cca6a2..a9fb5bffb806c8 100644 --- a/docs/maintainers/vcpkg_execute_in_download_mode.md +++ b/docs/maintainers/vcpkg_execute_in_download_mode.md @@ -7,28 +7,13 @@ Execute a process even in download mode. ## Usage ```cmake vcpkg_execute_in_download_mode( - COMMAND [] - [WORKING_DIRECTORY ] - [TIMEOUT ] - [RESULT_VARIABLE ] - [OUTPUT_VARIABLE ] - [ERROR_VARIABLE ] - [INPUT_FILE ] - [OUTPUT_FILE ] - [ERROR_FILE ] - [OUTPUT_QUIET] - [ERROR_QUIET] - [OUTPUT_STRIP_TRAILING_WHITESPACE] - [ERROR_STRIP_TRAILING_WHITESPACE] - [ENCODING ] + ... ) ``` -The signature of this function is identical to `execute_process()` except that -it only accepts one COMMAND argument, i.e., does not support chaining multiple -commands with pipes. +The signature of this function is identical to `execute_process()`. -See [`execute_process()`] for a detailed description of the parameters. +See [`execute_process()`] for more details. [`execute_process()`]: https://cmake.org/cmake/help/latest/command/execute_process.html diff --git a/docs/maintainers/vcpkg_execute_required_process_repeat.md b/docs/maintainers/vcpkg_execute_required_process_repeat.md index e6c9d0def13090..22dcfc4afbe827 100644 --- a/docs/maintainers/vcpkg_execute_required_process_repeat.md +++ b/docs/maintainers/vcpkg_execute_required_process_repeat.md @@ -7,10 +7,11 @@ Execute a process until the command succeeds, or until the COUNT is reached. ## Usage ```cmake vcpkg_execute_required_process_repeat( - COUNT COMMAND [] + COUNT WORKING_DIRECTORY LOGNAME + [ALLOW_IN_DOWNLOAD_MODE] ) ``` diff --git a/docs/maintainers/vcpkg_extract_source_archive.md b/docs/maintainers/vcpkg_extract_source_archive.md index 5e17d2d8d01c17..1d807edc8eb706 100644 --- a/docs/maintainers/vcpkg_extract_source_archive.md +++ b/docs/maintainers/vcpkg_extract_source_archive.md @@ -2,27 +2,74 @@ The latest version of this document lives in the [vcpkg repo](https://github.com/Microsoft/vcpkg/blob/master/docs/maintainers/vcpkg_extract_source_archive.md). -Extract an archive into the source directory. Deprecated in favor of [`vcpkg_extract_source_archive_ex`](vcpkg_extract_source_archive_ex.md). +Extract an archive into the source directory. ## Usage +There are two "overloads" of this function. The first is deprecated: + ```cmake -vcpkg_extract_source_archive( - <${ARCHIVE}> [<${TARGET_DIRECTORY}>] +vcpkg_extract_source_archive(<${ARCHIVE}> [<${TARGET_DIRECTORY}>]) +``` + +This overload should not be used. + +The latter is suggested to use for all future `vcpkg_extract_source_archive`s. + +```cmake +vcpkg_extract_source_archive( + ARCHIVE + [NO_REMOVE_ONE_LEVEL] + [PATCHES ...] + [SOURCE_BASE ] + [BASE_DIRECTORY | WORKING_DIRECTORY ] ) ``` -## Parameters -### ARCHIVE -The full path to the archive to be extracted. -This is usually obtained from calling [`vcpkg_download_distfile`](vcpkg_download_distfile.md). +`vcpkg_extract_source_archive` takes an archive and extracts it. +It replaces existing uses of `vcpkg_extract_source_archive_ex`. +The simplest use of it is: + +```cmake +vcpkg_download_distfile(archive ...) +vcpkg_extract_source_archive(source_path ARCHIVE "${archive}") +``` + +The general expectation is that an archives are laid out with a base directory, +and all the actual files underneath that directory; in other words, if you +extract the archive, you'll get something that looks like: + +``` +zlib-1.2.11/ + doc/ + ... + examples/ + ... + ChangeLog + CMakeLists.txt + README + zlib.h + ... +``` -### TARGET_DIRECTORY -If specified, the archive will be extracted into the target directory instead of `${CURRENT_BUILDTREES_DIR}/src/`. +`vcpkg_extract_source_archive` automatically removes this directory, +and gives you the items under it directly. However, this only works +when there is exactly one item in the top level of an archive. +Otherwise, you'll have to pass the `NO_REMOVE_ONE_LEVEL` argument to +prevent `vcpkg_extract_source_archive` from performing this transformation. -This can be used to mimic git submodules, by extracting into a subdirectory of another archive. +If the source needs to be patched in some way, the `PATCHES` argument +allows one to do this, just like other `vcpkg_from_*` functions. -## Notes -This command will also create a tracking file named .extracted in the TARGET_DIRECTORY. This file, when present, will suppress the extraction of the archive. +`vcpkg_extract_source_archive` extracts the files to +`${CURRENT_BUILDTREES_DIR}//-.clean`. +When in editable mode, no `.clean` is appended, +to allow for a user to modify the sources. +`base-directory` defaults to `src`, +and `source-base` defaults to the stem of ``. +You can change these via the `BASE_DIRECTORY` and `SOURCE_BASE` arguments +respectively. +If you need to extract to a location that is not based in `CURRENT_BUILDTREES_DIR`, +you can use the `WORKING_DIRECTORY` argument to do the same. ## Examples diff --git a/docs/maintainers/vcpkg_extract_source_archive_ex.md b/docs/maintainers/vcpkg_extract_source_archive_ex.md index 0692846f7627b4..72b45d87cf6a8c 100644 --- a/docs/maintainers/vcpkg_extract_source_archive_ex.md +++ b/docs/maintainers/vcpkg_extract_source_archive_ex.md @@ -2,57 +2,25 @@ The latest version of this document lives in the [vcpkg repo](https://github.com/Microsoft/vcpkg/blob/master/docs/maintainers/vcpkg_extract_source_archive_ex.md). -Extract an archive into the source directory. Replaces [`vcpkg_extract_source_archive`](vcpkg_extract_source_archive.md). +Extract an archive into the source directory. +Originally replaced [`vcpkg_extract_source_archive()`], +but new ports should instead use the second overload of +[`vcpkg_extract_source_archive()`]. ## Usage ```cmake vcpkg_extract_source_archive_ex( - SKIP_PATCH_CHECK - OUT_SOURCE_PATH - ARCHIVE <${ARCHIVE}> - [REF <1.0.0>] - [NO_REMOVE_ONE_LEVEL] - [WORKING_DIRECTORY <${CURRENT_BUILDTREES_DIR}/src>] - [PATCHES ...] + [OUT_SOURCE_PATH ] + ... ) ``` -## Parameters -### SKIP_PATCH_CHECK -If this option is set the failure to apply a patch is ignored. -### OUT_SOURCE_PATH -Specifies the out-variable that will contain the extracted location. +See the documentation for [`vcpkg_extract_source_archive()`] for other parameters. +Additionally, `vcpkg_extract_source_archive_ex()` adds the `REF` and `WORKING_DIRECTORY` +parameters, which are wrappers around `SOURCE_BASE` and `BASE_DIRECTORY` +respectively. -This should be set to `SOURCE_PATH` by convention. - -### ARCHIVE -The full path to the archive to be extracted. - -This is usually obtained from calling [`vcpkg_download_distfile`](vcpkg_download_distfile.md). - -### REF -A friendly name that will be used instead of the filename of the archive. If more than 10 characters it will be truncated. - -By convention, this is set to the version number or tag fetched - -### WORKING_DIRECTORY -If specified, the archive will be extracted into the working directory instead of `${CURRENT_BUILDTREES_DIR}/src/`. - -Note that the archive will still be extracted into a subfolder underneath that directory (`${WORKING_DIRECTORY}/${REF}-${HASH}/`). - -### PATCHES -A list of patches to be applied to the extracted sources. - -Relative paths are based on the port directory. - -### NO_REMOVE_ONE_LEVEL -Specifies that the default removal of the top level folder should not occur. - -## Examples - -* [bzip2](https://github.com/Microsoft/vcpkg/blob/master/ports/bzip2/portfile.cmake) -* [sqlite3](https://github.com/Microsoft/vcpkg/blob/master/ports/sqlite3/portfile.cmake) -* [cairo](https://github.com/Microsoft/vcpkg/blob/master/ports/cairo/portfile.cmake) +[`vcpkg_extract_source_archive()`]: vcpkg_extract_source_archive.md ## Source [scripts/cmake/vcpkg\_extract\_source\_archive\_ex.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_extract_source_archive_ex.cmake) diff --git a/docs/maintainers/vcpkg_from_bitbucket.md b/docs/maintainers/vcpkg_from_bitbucket.md index dd32fde023df0e..c37e9e74b3254c 100644 --- a/docs/maintainers/vcpkg_from_bitbucket.md +++ b/docs/maintainers/vcpkg_from_bitbucket.md @@ -3,7 +3,6 @@ The latest version of this document lives in the [vcpkg repo](https://github.com/Microsoft/vcpkg/blob/master/docs/maintainers/vcpkg_from_bitbucket.md). Download and extract a project from Bitbucket. -Enables support for installing HEAD `vcpkg.exe install --head `. ## Usage: ```cmake diff --git a/docs/maintainers/vcpkg_from_git.md b/docs/maintainers/vcpkg_from_git.md index ce6daa5e7c240b..85bb3f90929bb5 100644 --- a/docs/maintainers/vcpkg_from_git.md +++ b/docs/maintainers/vcpkg_from_git.md @@ -10,7 +10,7 @@ vcpkg_from_git( OUT_SOURCE_PATH URL REF <59f7335e4d...> - [TAG ] + [HEAD_REF ] [PATCHES ...] ) ``` @@ -27,17 +27,16 @@ The url of the git repository. ### REF The git sha of the commit to download. -### TAG -An optional git tag to be verified against the `REF`. If the remote repository's tag does not match the specified `REF`, the build will fail. +### HEAD_REF +The git branch to use when the package is requested to be built from the latest sources. + +Example: `main`, `develop`, `HEAD` ### PATCHES A list of patches to be applied to the extracted sources. Relative paths are based on the port directory. -### X_OUT_REF (internal only) -This parameter is used for automatic REF updates for certain ports in the central vcpkg catalog. It should not be used by any ports outside the central catalog and within the central catalog it should not be used on any user path. This parameter may change behavior incompatibly or be removed at any time. - ## Notes: `OUT_SOURCE_PATH`, `REF`, and `URL` must be specified. diff --git a/docs/maintainers/vcpkg_from_sourceforge.md b/docs/maintainers/vcpkg_from_sourceforge.md index 7ce256b2ef3f99..3c1574facd174c 100644 --- a/docs/maintainers/vcpkg_from_sourceforge.md +++ b/docs/maintainers/vcpkg_from_sourceforge.md @@ -4,6 +4,10 @@ The latest version of this document lives in the [vcpkg repo](https://github.com Download and extract a project from sourceforge. +This function automatically checks a set of sourceforge mirrors. +Additional mirrors can be injected through the `VCPKG_SOURCEFORGE_EXTRA_MIRRORS` +list variable in the triplet. + ## Usage: ```cmake vcpkg_from_sourceforge( @@ -54,9 +58,6 @@ A list of patches to be applied to the extracted sources. Relative paths are based on the port directory. -### DISABLE_SSL -Disable ssl when downloading source. - ### NO_REMOVE_ONE_LEVEL Specifies that the default removal of the top level folder should not occur. diff --git a/docs/maintainers/vcpkg_install_msbuild.md b/docs/maintainers/vcpkg_install_msbuild.md index 151a42410f5b07..8d0a31051aeff5 100644 --- a/docs/maintainers/vcpkg_install_msbuild.md +++ b/docs/maintainers/vcpkg_install_msbuild.md @@ -88,8 +88,8 @@ Additional options passed to msbuild for Debug builds. These are in addition to ## Examples -* [xalan-c](https://github.com/Microsoft/vcpkg/blob/master/ports/xalan-c/portfile.cmake) -* [libimobiledevice](https://github.com/Microsoft/vcpkg/blob/master/ports/libimobiledevice/portfile.cmake) +* [libirecovery](https://github.com/Microsoft/vcpkg/blob/master/ports/libirecovery/portfile.cmake) +* [libfabric](https://github.com/Microsoft/vcpkg/blob/master/ports/libfabric/portfile.cmake) ## Source [scripts/cmake/vcpkg\_install\_msbuild.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_install_msbuild.cmake) diff --git a/docs/regenerate.ps1 b/docs/regenerate.ps1 index df78e2fca3a5c6..7844055efedfcf 100755 --- a/docs/regenerate.ps1 +++ b/docs/regenerate.ps1 @@ -212,7 +212,7 @@ function ParseCmakeDocComment $Docs.HasError = $True } - if ($contents.Length -ne 0) + if (-not [String]::IsNullOrEmpty($contents)) { $Docs.ActualDocumentation = $contents } @@ -311,6 +311,7 @@ function GetDeprecationMessage Param( [CMakeDocumentation]$Doc ) + $message = '' if ($Doc.IsDeprecated) { $message = " (deprecated" diff --git a/ports/avisynthplus/portfile.cmake b/ports/avisynthplus/portfile.cmake index 8bbc5eace1f708..af6641c3f97246 100644 --- a/ports/avisynthplus/portfile.cmake +++ b/ports/avisynthplus/portfile.cmake @@ -15,8 +15,8 @@ vcpkg_download_distfile(GHC_ARCHIVE ) file(REMOVE_RECURSE ${SOURCE_PATH}/filesystem) -vcpkg_extract_source_archive(${GHC_ARCHIVE} ${SOURCE_PATH}) -file(RENAME ${SOURCE_PATH}/filesystem-3f1c185ab414e764c694b8171d1c4d8c5c437517 ${SOURCE_PATH}/filesystem) +vcpkg_extract_source_archive(extracted_archive ARCHIVE "${GHC_ARCHIVE}") +file(RENAME "${extracted_archive}" "${SOURCE_PATH}/filesystem") vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} diff --git a/ports/avisynthplus/vcpkg.json b/ports/avisynthplus/vcpkg.json index 58d064b2d00bd9..88e47ac016c0a5 100644 --- a/ports/avisynthplus/vcpkg.json +++ b/ports/avisynthplus/vcpkg.json @@ -1,6 +1,7 @@ { "name": "avisynthplus", "version-semver": "3.7.0", + "port-version": 1, "description": "An improved version of the AviSynth frameserver, with improved features and developer friendliness", "homepage": "http://avs-plus.net/", "supports": "!arm & !uwp" diff --git a/ports/bond/CONTROL b/ports/bond/CONTROL deleted file mode 100644 index 64673d992b2364..00000000000000 --- a/ports/bond/CONTROL +++ /dev/null @@ -1,9 +0,0 @@ -Source: bond -Version: 9.0.3 -Description: Bond is a cross-platform framework for working with schematized data. It supports cross-language de/serialization and powerful generic mechanisms for efficiently manipulating data. Bond is broadly used at Microsoft in high scale services. -Homepage: https://github.com/Microsoft/bond -Build-Depends: rapidjson, boost-config, boost-utility, boost-assign, boost-locale - -Feature: bond-over-grpc -Description: Bond-over-gRPC provides code generation from Bond IDL service definitions to send Bond objects via gRPC. -Build-Depends: grpc diff --git a/ports/bond/portfile.cmake b/ports/bond/portfile.cmake index f4b9cdd9498e6b..6a56a4534e92be 100644 --- a/ports/bond/portfile.cmake +++ b/ports/bond/portfile.cmake @@ -21,13 +21,13 @@ if (VCPKG_TARGET_IS_WINDOWS) # Clear the generator to prevent it from updating file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/tools/) # Extract the precompiled gbc - vcpkg_extract_source_archive(${GBC_ARCHIVE} ${CURRENT_BUILDTREES_DIR}/tools/) - set(FETCHED_GBC_PATH ${CURRENT_BUILDTREES_DIR}/tools/gbc-${BOND_VER}-amd64.exe) + vcpkg_extract_source_archive(extracted_tool_dir ARCHIVE "${GBC_ARCHIVE}" NO_REMOVE_ONE_LEVEL) + file(RENAME "${extracted_tool_dir}" "${CURRENT_BUILDTREES_DIR}/tools") - if (NOT EXISTS "${FETCHED_GBC_PATH}") - message(FATAL_ERROR "Fetching GBC failed. Expected '${FETCHED_GBC_PATH}' to exists, but it doesn't.") + set(FETCHED_GBC_PATH "${CURRENT_BUILDTREES_DIR}/tools/gbc-${BOND_VER}-amd64.exe") + if(NOT EXISTS "${FETCHED_GBC_PATH}") + message(FATAL_ERROR "Fetching GBC failed. Expected '${FETCHED_GBC_PATH}' to exist, but it doesn't.") endif() - else() # According to the readme on https://github.com/microsoft/bond/ # The build needs a version of the Haskel Tool stack that is newer than some distros ship with. diff --git a/ports/bond/vcpkg.json b/ports/bond/vcpkg.json new file mode 100644 index 00000000000000..524cc9d0f5b7da --- /dev/null +++ b/ports/bond/vcpkg.json @@ -0,0 +1,22 @@ +{ + "name": "bond", + "version-string": "9.0.3", + "port-version": 1, + "description": "Bond is a cross-platform framework for working with schematized data. It supports cross-language de/serialization and powerful generic mechanisms for efficiently manipulating data. Bond is broadly used at Microsoft in high scale services.", + "homepage": "https://github.com/Microsoft/bond", + "dependencies": [ + "boost-assign", + "boost-config", + "boost-locale", + "boost-utility", + "rapidjson" + ], + "features": { + "bond-over-grpc": { + "description": "Bond-over-gRPC provides code generation from Bond IDL service definitions to send Bond objects via gRPC.", + "dependencies": [ + "grpc" + ] + } + } +} diff --git a/ports/nmap/CONTROL b/ports/nmap/CONTROL deleted file mode 100644 index a703b496fa35a3..00000000000000 --- a/ports/nmap/CONTROL +++ /dev/null @@ -1,4 +0,0 @@ -Source: nmap -Version: 7.70-4 -Build-Depends: winpcap (windows), libpcap (!windows), lua, openssl, python2 (windows), libssh2, zlib, pcre -Description: A library for scanning network ports. diff --git a/ports/nmap/portfile.cmake b/ports/nmap/portfile.cmake index 829153310bdbf2..c0252af8dac02e 100644 --- a/ports/nmap/portfile.cmake +++ b/ports/nmap/portfile.cmake @@ -58,59 +58,60 @@ if(VCPKG_TARGET_IS_WINDOWS) endif() else() set(ENV{LDFLAGS} "$ENV{LDFLAGS} -pthread") - foreach(BUILD_TYPE rel dbg) - file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${BUILD_TYPE}) - file(MAKE_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${BUILD_TYPE}) - # Since nmap makefile has strong relationshop with codes, copy codes to obj path - vcpkg_extract_source_archive(${ARCHIVE} ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${BUILD_TYPE}) - - endforeach() set(OPTIONS --without-nmap-update --with-openssl=${CURRENT_INSTALLED_DIR} --with-libssh2=${CURRENT_INSTALLED_DIR} --with-libz=${CURRENT_INSTALLED_DIR} --with-libpcre=${CURRENT_INSTALLED_DIR}) message(STATUS "Building Options: ${OPTIONS}") if (NOT VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL Release) + # Since nmap makefile has strong relationshop with codes, copy codes to obj path message(STATUS "Configuring ${TARGET_TRIPLET}-rel") - set(SOURCE_PATH_RELEASE ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/nmap-7.70) + vcpkg_extract_source_archive(source_path_release + ARCHIVE "${ARCHIVE}" + WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel" + ) vcpkg_execute_required_process( COMMAND "./configure" ${OPTIONS} - WORKING_DIRECTORY ${SOURCE_PATH_RELEASE} + WORKING_DIRECTORY "${source_path_release}" LOGNAME config-${TARGET_TRIPLET}-rel ) message(STATUS "Building ${TARGET_TRIPLET}-rel") vcpkg_execute_required_process( COMMAND make - WORKING_DIRECTORY ${SOURCE_PATH_RELEASE} + WORKING_DIRECTORY "${source_path_release}" LOGNAME build-${TARGET_TRIPLET}-rel ) message(STATUS "Installing ${TARGET_TRIPLET}-rel") - file(INSTALL ${SOURCE_PATH_RELEASE}/nmap DESTINATION ${CURRENT_PACKAGES_DIR}/tools) + file(INSTALL ${source_path_release}/nmap DESTINATION ${CURRENT_PACKAGES_DIR}/tools) endif() if (NOT VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL Debug) + # Since nmap makefile has strong relationshop with codes, copy codes to obj path message(STATUS "Configuring ${TARGET_TRIPLET}-dbg") - set(SOURCE_PATH_DEBUG ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg/nmap-7.70) + vcpkg_extract_source_archive(source_path_debug + ARCHIVE "${ARCHIVE}" + WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel" + ) vcpkg_execute_required_process( COMMAND "./configure" ${OPTIONS} - WORKING_DIRECTORY ${SOURCE_PATH_DEBUG} + WORKING_DIRECTORY ${source_path_debug} LOGNAME config-${TARGET_TRIPLET}-dbg ) message(STATUS "Building ${TARGET_TRIPLET}-dbg") vcpkg_execute_required_process( COMMAND make - WORKING_DIRECTORY ${SOURCE_PATH_DEBUG} + WORKING_DIRECTORY ${source_path_debug} LOGNAME build-${TARGET_TRIPLET}-dbg ) message(STATUS "Installing ${TARGET_TRIPLET}-dbg") - file(INSTALL ${SOURCE_PATH_RELEASE}/nmap DESTINATION ${CURRENT_PACKAGES_DIR}/debug/tools) + file(INSTALL ${source_path_release}/nmap DESTINATION ${CURRENT_PACKAGES_DIR}/debug/tools) endif() - set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/nmap-7.70) + set(SOURCE_PATH "${source_path_release}") endif() vcpkg_copy_pdbs() diff --git a/ports/nmap/vcpkg.json b/ports/nmap/vcpkg.json new file mode 100644 index 00000000000000..6aba23611c541d --- /dev/null +++ b/ports/nmap/vcpkg.json @@ -0,0 +1,25 @@ +{ + "name": "nmap", + "version": "7.70", + "port-version": 5, + "description": "A library for scanning network ports.", + "dependencies": [ + { + "name": "libpcap", + "platform": "!windows" + }, + "libssh2", + "lua", + "openssl", + "pcre", + { + "name": "python2", + "platform": "windows" + }, + { + "name": "winpcap", + "platform": "windows" + }, + "zlib" + ] +} diff --git a/ports/opencv3/portfile.cmake b/ports/opencv3/portfile.cmake index 4d93c4f1a14f9e..5e298acbc1f200 100644 --- a/ports/opencv3/portfile.cmake +++ b/ports/opencv3/portfile.cmake @@ -135,9 +135,9 @@ if("contrib" IN_LIST FEATURES) FILENAME "opencv_3rdparty-${COMMIT}.zip" SHA512 ${HASH} ) - vcpkg_extract_source_archive(${OCV_DOWNLOAD}) + vcpkg_extract_source_archive(extracted_ocv ARCHIVE "${OCV_DOWNLOAD}") file(MAKE_DIRECTORY "${DOWNLOADS}/opencv-cache/${ID}") - file(GLOB XFEATURES2D_I ${CURRENT_BUILDTREES_DIR}/src/opencv_3rdparty-${COMMIT}/*) + file(GLOB XFEATURES2D_I "${extracted_ocv}/*") foreach(FILE ${XFEATURES2D_I}) file(COPY ${FILE} DESTINATION "${DOWNLOADS}/opencv-cache/${ID}") get_filename_component(XFEATURES2D_I_NAME "${FILE}" NAME) diff --git a/ports/opencv3/vcpkg.json b/ports/opencv3/vcpkg.json index cf7bb123405c99..50d927750ac693 100644 --- a/ports/opencv3/vcpkg.json +++ b/ports/opencv3/vcpkg.json @@ -1,6 +1,7 @@ { "name": "opencv3", "version": "3.4.14", + "port-version": 1, "description": "computer vision library", "homepage": "https://github.com/opencv/opencv", "dependencies": [ diff --git a/ports/qcustomplot/CONTROL b/ports/qcustomplot/CONTROL deleted file mode 100644 index ec7dac08fc670c..00000000000000 --- a/ports/qcustomplot/CONTROL +++ /dev/null @@ -1,4 +0,0 @@ -Source: qcustomplot -Version: 2.0.1-4 -Description: QCustomPlot is a Qt C++ widget for plotting and data visualization. -Build-Depends: qt5-base[core] diff --git a/ports/qcustomplot/portfile.cmake b/ports/qcustomplot/portfile.cmake index b180d8bd7ab5d7..026f62fb381356 100644 --- a/ports/qcustomplot/portfile.cmake +++ b/ports/qcustomplot/portfile.cmake @@ -16,7 +16,9 @@ vcpkg_download_distfile(ARCHIVE FILENAME "QCustomPlot-sharedlib-${QCP_VERSION}.tar.gz" SHA512 ce90540fca7226eac37746327e1939a9c7af38fc2595f385ed04d6d1f49560da08fb5fae15d1b9d22b6ba578583f70de8f89ef26796770d41bf599c1b15c535d ) -vcpkg_extract_source_archive(${ARCHIVE} ${SOURCE_PATH}) +vcpkg_extract_source_archive(SharedLib_SOURCE_PATH ARCHIVE "${ARCHIVE}") +file(RENAME "${SharedLib_SOURCE_PATH}" "${SOURCE_PATH}/qcustomplot-sharedlib") + vcpkg_configure_qmake(SOURCE_PATH ${SOURCE_PATH}/qcustomplot-sharedlib/sharedlib-compilation/sharedlib-compilation.pro diff --git a/ports/qcustomplot/vcpkg.json b/ports/qcustomplot/vcpkg.json new file mode 100644 index 00000000000000..6d2c2c66533708 --- /dev/null +++ b/ports/qcustomplot/vcpkg.json @@ -0,0 +1,12 @@ +{ + "name": "qcustomplot", + "version": "2.0.1", + "port-version": 5, + "description": "QCustomPlot is a Qt C++ widget for plotting and data visualization.", + "dependencies": [ + { + "name": "qt5-base", + "default-features": false + } + ] +} diff --git a/ports/qt5-mqtt/CONTROL b/ports/qt5-mqtt/CONTROL deleted file mode 100644 index eeb831a9f81366..00000000000000 --- a/ports/qt5-mqtt/CONTROL +++ /dev/null @@ -1,4 +0,0 @@ -Source: qt5-mqtt -Version: 5.15.2 -Description: Qt5 MQTT module. -Build-Depends: qt5-base[core] diff --git a/ports/qt5-mqtt/portfile.cmake b/ports/qt5-mqtt/portfile.cmake index 77ef1144b18865..ca6e25d0d4d746 100644 --- a/ports/qt5-mqtt/portfile.cmake +++ b/ports/qt5-mqtt/portfile.cmake @@ -1,20 +1,19 @@ include(${CURRENT_INSTALLED_DIR}/share/qt5/qt_port_functions.cmake) #qt_submodule_installation() No binary package for this port. if(QT_UPDATE_VERSION) - set(UPDATE_PORT_GIT_OPTIONS X_OUT_REF NEW_REF) # TO get an SHA512 error if the variable is set. + set(VCPKG_USE_HEAD_VERSION ON) endif() vcpkg_from_git( OUT_SOURCE_PATH SOURCE_PATH URL git://code.qt.io/qt/qtmqtt.git - TAG v${QT_MAJOR_MINOR_VER}.${QT_PATCH_VER} REF ${QT_HASH_${PORT}} - ${UPDATE_PORT_GIT_OPTIONS} + HEAD_REF "v${QT_MAJOR_MINOR_VER}.${QT_PATCH_VER}" PATCHES ${_qis_PATCHES} ) -if(NEW_REF) - message(STATUS "New qtmqtt ref: ${NEW_REF}") +if(QT_UPDATE_VERSION) + message(STATUS "New qtmqtt ref: ${VCPKG_HEAD_VERSION}") endif() # qt module builds from a git repository require a .git entry to invoke syncqt diff --git a/ports/qt5-mqtt/vcpkg.json b/ports/qt5-mqtt/vcpkg.json new file mode 100644 index 00000000000000..c4dac430ad181d --- /dev/null +++ b/ports/qt5-mqtt/vcpkg.json @@ -0,0 +1,12 @@ +{ + "name": "qt5-mqtt", + "version": "5.15.2", + "port-version": 1, + "description": "Qt5 MQTT module.", + "dependencies": [ + { + "name": "qt5-base", + "default-features": false + } + ] +} diff --git a/ports/vcpkg-cmake-config/vcpkg.json b/ports/vcpkg-cmake-config/vcpkg.json index fde8492dc57d48..49faaf4d402b37 100644 --- a/ports/vcpkg-cmake-config/vcpkg.json +++ b/ports/vcpkg-cmake-config/vcpkg.json @@ -1,4 +1,5 @@ { "name": "vcpkg-cmake-config", - "version-date": "2021-05-22" + "version-date": "2021-05-22", + "port-version": 1 } diff --git a/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.cmake b/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.cmake index 03a6c1d0982351..a145d324a91d8c 100644 --- a/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.cmake +++ b/ports/vcpkg-cmake-config/vcpkg_cmake_config_fixup.cmake @@ -9,7 +9,7 @@ Additionally corrects common issues with targets, such as absolute paths and inc vcpkg_cmake_config_fixup( [PACKAGE_NAME ] [CONFIG_PATH ] - [DO_NOT_DELETE_CONFIG_PATH_PARENT] + [DO_NOT_DELETE_PARENT_CONFIG_PATH] [NO_PREFIX_CORRECTION] ) ``` diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake index a25f0f716c1d7b..8ab2878524e204 100644 --- a/scripts/buildsystems/vcpkg.cmake +++ b/scripts/buildsystems/vcpkg.cmake @@ -46,7 +46,9 @@ mark_as_advanced(VCPKG_VERBOSE) option(VCPKG_APPLOCAL_DEPS "Automatically copy dependencies into the output directory for executables." ON) option(X_VCPKG_APPLOCAL_DEPS_SERIALIZED "(experimental) Add USES_TERMINAL to VCPKG_APPLOCAL_DEPS to force serialization." OFF) -option(X_VCPKG_APPLOCAL_DEPS_INSTALL "(experimental) Automatically copy dependencies into the install target directory for executables." OFF) + +# requires CMake 3.14 +option(X_VCPKG_APPLOCAL_DEPS_INSTALL "(experimental) Automatically copy dependencies into the install target directory for executables. Requires CMake 3.14." OFF) option(VCPKG_PREFER_SYSTEM_LIBS "Appends the vcpkg paths to CMAKE_PREFIX_PATH, CMAKE_LIBRARY_PATH and CMAKE_FIND_ROOT_PATH so that vcpkg libraries/packages are found after toolchain/system libraries/packages." OFF) # Manifest options and settings diff --git a/scripts/cmake/execute_process.cmake b/scripts/cmake/execute_process.cmake index 206bd95b1219da..be45604d6b4c46 100644 --- a/scripts/cmake/execute_process.cmake +++ b/scripts/cmake/execute_process.cmake @@ -14,5 +14,8 @@ if (NOT DEFINED Z_VCPKG_OVERRIDEN_EXECUTE_PROCESS) function(execute_process) message(FATAL_ERROR "This command cannot be executed in Download Mode.\nHalting portfile execution.\n") endfunction() + set(Z_VCPKG_EXECUTE_PROCESS_NAME "_execute_process") + else() + set(Z_VCPKG_EXECUTE_PROCESS_NAME "execute_process") endif() endif() diff --git a/scripts/cmake/vcpkg_clean_msbuild.cmake b/scripts/cmake/vcpkg_clean_msbuild.cmake index 5a2432c33c559a..068208fb8b6345 100644 --- a/scripts/cmake/vcpkg_clean_msbuild.cmake +++ b/scripts/cmake/vcpkg_clean_msbuild.cmake @@ -10,7 +10,7 @@ vcpkg_clean_msbuild() ## Examples -* [xalan-c](https://github.com/Microsoft/vcpkg/blob/master/ports/xalan-c/portfile.cmake) +* [python3](https://github.com/Microsoft/vcpkg/blob/master/ports/python3/portfile.cmake) #]===] function(vcpkg_clean_msbuild) diff --git a/scripts/cmake/vcpkg_download_distfile.cmake b/scripts/cmake/vcpkg_download_distfile.cmake index c859c98a017dcd..557024351ee204 100644 --- a/scripts/cmake/vcpkg_download_distfile.cmake +++ b/scripts/cmake/vcpkg_download_distfile.cmake @@ -12,6 +12,7 @@ vcpkg_download_distfile( URLS ... FILENAME SHA512 <5981de...> + [ALWAYS_REDOWNLOAD] ) ``` ## Parameters @@ -37,6 +38,11 @@ Skip SHA512 hash check for file. This switch is only valid when building with the `--head` command line flag. +### ALWAYS_REDOWNLOAD +Avoid caching; this is a REST call or otherwise unstable. + +Requires `SKIP_SHA512`. + ### HEADERS A list of headers to append to the download request. This can be used for authentication during a download. @@ -55,7 +61,7 @@ The helper [`vcpkg_from_github`](vcpkg_from_github.md) should be used for downlo include(vcpkg_execute_in_download_mode) function(vcpkg_download_distfile VAR) - set(options SKIP_SHA512 SILENT_EXIT QUIET) + set(options SKIP_SHA512 SILENT_EXIT QUIET ALWAYS_REDOWNLOAD) set(oneValueArgs FILENAME SHA512) set(multipleValuesArgs URLS HEADERS) # parse parameters such that semicolons in options arguments to COMMAND don't get erased @@ -70,6 +76,9 @@ function(vcpkg_download_distfile VAR) if(vcpkg_download_distfile_SILENT_EXIT) message(WARNING "SILENT_EXIT has been deprecated as an argument to vcpkg_download_distfile -- remove the argument to resolve this warning") endif() + if(vcpkg_download_distfile_ALWAYS_REDOWNLOAD AND NOT vcpkg_download_distfile_SKIP_SHA512) + message(FATAL_ERROR "ALWAYS_REDOWNLOAD option requires SKIP_SHA512 as well") + endif() if(_VCPKG_INTERNAL_NO_HASH_CHECK) set(vcpkg_download_distfile_SKIP_SHA512 1) else() @@ -125,7 +134,9 @@ function(vcpkg_download_distfile VAR) endif() endfunction() - if(EXISTS "${downloaded_file_path}") + # vcpkg_download_distfile_ALWAYS_REDOWNLOAD only triggers when NOT _VCPKG_NO_DOWNLOADS + # this could be de-morgan'd out but it's more clear this way + if(EXISTS "${downloaded_file_path}" AND NOT (vcpkg_download_distfile_ALWAYS_REDOWNLOAD AND NOT _VCPKG_NO_DOWNLOADS)) if(NOT vcpkg_download_distfile_QUIET) message(STATUS "Using ${downloaded_file_path}") endif() diff --git a/scripts/cmake/vcpkg_execute_build_process.cmake b/scripts/cmake/vcpkg_execute_build_process.cmake index 52c03e445e8074..914c07e0d3054a 100644 --- a/scripts/cmake/vcpkg_execute_build_process.cmake +++ b/scripts/cmake/vcpkg_execute_build_process.cmake @@ -34,120 +34,129 @@ conflict when building multiple at once. * [icu](https://github.com/Microsoft/vcpkg/blob/master/ports/icu/portfile.cmake) #]===] +set(Z_VCPKG_EXECUTE_BUILD_PROCESS_RETRY_ERROR_MESSAGES + "LINK : fatal error LNK1102:" + " fatal error C1060: " + # The linker ran out of memory during execution. We will try continuing once more, with parallelism disabled. + "LINK : fatal error LNK1318:" + "LINK : fatal error LNK1104:" + "LINK : fatal error LNK1201:" + # Multiple threads using the same directory at the same time cause conflicts, will try again. + "Cannot create parent directory" + "Cannot write file" + # Multiple threads caused the wrong order of creating folders and creating files in folders + "Can't open" +) +list(JOIN Z_VCPKG_EXECUTE_BUILD_PROCESS_RETRY_ERROR_MESSAGES "|" Z_VCPKG_EXECUTE_BUILD_PROCESS_RETRY_ERROR_MESSAGES) + function(vcpkg_execute_build_process) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _ebp "" "WORKING_DIRECTORY;LOGNAME" "COMMAND;NO_PARALLEL_COMMAND") + cmake_parse_arguments(PARSE_ARGV 0 arg "" "WORKING_DIRECTORY;LOGNAME" "COMMAND;NO_PARALLEL_COMMAND") + + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + foreach(required_arg IN ITEMS WORKING_DIRECTORY COMMAND) + if(NOT DEFINED arg_${required_arg}) + message(FATAL_ERROR "${required_arg} must be specified.") + endif() + endforeach() - set(LOG_OUT "${CURRENT_BUILDTREES_DIR}/${_ebp_LOGNAME}-out.log") - set(LOG_ERR "${CURRENT_BUILDTREES_DIR}/${_ebp_LOGNAME}-err.log") + if(NOT DEFINED arg_LOGNAME) + message(WARNING "LOGNAME should be specified.") + set(arg_LOGNAME "build") + endif() + + set(log_prefix "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}") + set(log_out "${log_prefix}-out.log") + set(log_err "${log_prefix}-err.log") + set(all_logs "${log_out}" "${log_err}") execute_process( - COMMAND ${_ebp_COMMAND} - WORKING_DIRECTORY ${_ebp_WORKING_DIRECTORY} - OUTPUT_FILE ${LOG_OUT} - ERROR_FILE ${LOG_ERR} + COMMAND ${arg_COMMAND} + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" + OUTPUT_FILE "${log_out}" + ERROR_FILE "${log_err}" RESULT_VARIABLE error_code ) - if(error_code) - file(READ ${LOG_OUT} out_contents) - file(READ ${LOG_ERR} err_contents) - - if(out_contents) - list(APPEND LOGS ${LOG_OUT}) - endif() - if(err_contents) - list(APPEND LOGS ${LOG_ERR}) - endif() - - if(out_contents MATCHES "LINK : fatal error LNK1102:" OR out_contents MATCHES " fatal error C1060: " - OR err_contents MATCHES "LINK : fatal error LNK1102:" OR err_contents MATCHES " fatal error C1060: " - OR out_contents MATCHES "LINK : fatal error LNK1318: Unexpected PDB error; ACCESS_DENIED" - OR out_contents MATCHES "LINK : fatal error LNK1104:" - OR out_contents MATCHES "LINK : fatal error LNK1201:" - # The linker ran out of memory during execution. We will try continuing once more, with parallelism disabled. - OR err_contents MATCHES "Cannot create parent directory" OR err_contents MATCHES "Cannot write file" - # Multiple threads using the same directory at the same time cause conflicts, will try again. - OR err_contents MATCHES "Can't open" - # Multiple threads caused the wrong order of creating folders and creating files in folders - ) + if(NOT error_code EQUAL "0") + file(READ "${log_out}" out_contents) + file(READ "${log_err}" err_contents) + set(all_contents "${out_contents}${err_contents}") + if(all_contents MATCHES "${Z_VCPKG_EXECUTE_BUILD_PROCESS_RETRY_ERROR_MESSAGES}") message(STATUS "Restarting Build without parallelism because memory exceeded") - set(LOG_OUT "${CURRENT_BUILDTREES_DIR}/${_ebp_LOGNAME}-out-1.log") - set(LOG_ERR "${CURRENT_BUILDTREES_DIR}/${_ebp_LOGNAME}-err-1.log") + set(log_out "${log_prefix}-out-1.log") + set(log_err "${log_prefix}-err-1.log") + list(APPEND all_logs "${log_out}" "${log_err}") - if(_ebp_NO_PARALLEL_COMMAND) + if(DEFINED arg_NO_PARALLEL_COMMAND) execute_process( - COMMAND ${_ebp_NO_PARALLEL_COMMAND} - WORKING_DIRECTORY ${_ebp_WORKING_DIRECTORY} - OUTPUT_FILE ${LOG_OUT} - ERROR_FILE ${LOG_ERR} + COMMAND ${arg_NO_PARALLEL_COMMAND} + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" + OUTPUT_FILE "${log_out}" + ERROR_FILE "${log_err}" RESULT_VARIABLE error_code ) else() execute_process( - COMMAND ${_ebp_COMMAND} - WORKING_DIRECTORY ${_ebp_WORKING_DIRECTORY} - OUTPUT_FILE ${LOG_OUT} - ERROR_FILE ${LOG_ERR} + COMMAND ${arg_COMMAND} + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" + OUTPUT_FILE "${log_out}" + ERROR_FILE "${log_err}" RESULT_VARIABLE error_code ) endif() - - if(error_code) - file(READ ${LOG_OUT} out_contents) - file(READ ${LOG_ERR} err_contents) - - if(out_contents) - list(APPEND LOGS ${LOG_OUT}) - endif() - if(err_contents) - list(APPEND LOGS ${LOG_ERR}) - endif() - endif() - elseif(out_contents MATCHES "mt : general error c101008d: " OR out_contents MATCHES "mt.exe : general error c101008d: ") + elseif(all_contents MATCHES "mt : general error c101008d: ") # Antivirus workaround - occasionally files are locked and cause mt.exe to fail message(STATUS "mt.exe has failed. This may be the result of anti-virus. Disabling anti-virus on the buildtree folder may improve build speed") - set(ITERATION 0) - while (ITERATION LESS 3 AND (out_contents MATCHES "mt : general error c101008d: " OR out_contents MATCHES "mt.exe : general error c101008d: ")) - MATH(EXPR ITERATION "${ITERATION}+1") - message(STATUS "Restarting Build ${TARGET_TRIPLET}-${SHORT_BUILDTYPE} because of mt.exe file locking issue. Iteration: ${ITERATION}") + foreach(iteration RANGE 1 3) + message(STATUS "Restarting Build ${TARGET_TRIPLET}-${SHORT_BUILDTYPE} because of mt.exe file locking issue. Iteration: ${iteration}") + + set(log_out "${log_prefix}-out-${iteration}.log") + set(log_err "${log_prefix}-err-${iteration}.log") + list(APPEND all_logs "${log_out}" "${log_err}") execute_process( - COMMAND ${_ebp_COMMAND} - OUTPUT_FILE "${LOGPREFIX}-out-${ITERATION}.log" - ERROR_FILE "${LOGPREFIX}-err-${ITERATION}.log" + COMMAND ${arg_COMMAND} + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" + OUTPUT_FILE "${log_out}" + ERROR_FILE "${log_err}" RESULT_VARIABLE error_code - WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-${SHORT_BUILDTYPE}) - - if(error_code) - file(READ "${LOGPREFIX}-out-${ITERATION}.log" out_contents) - file(READ "${LOGPREFIX}-err-${ITERATION}.log" err_contents) - - if(out_contents) - list(APPEND LOGS "${LOGPREFIX}-out-${ITERATION}.log") - endif() - if(err_contents) - list(APPEND LOGS "${LOGPREFIX}-err-${ITERATION}.log") - endif() - else() + ) + + if(error_code EQUAL "0") break() endif() - endwhile() - elseif(out_contents MATCHES "fatal error: ld terminated with signal 9 [Killed]") + + file(READ "${log_out}" out_contents) + file(READ "${log_err}" err_contents) + set(all_contents "${out_contents}${err_contents}") + if(NOT all_contents MATCHES "mt : general error c101008d: ") + break() + endif() + endforeach() + elseif(all_contents MATCHES "fatal error: ld terminated with signal 9 [Killed]") message(WARNING "ld was terminated with signal 9 [killed], please ensure your system has sufficient hard disk space and memory.") endif() + endif() - if(error_code) - set(STRINGIFIED_LOGS) - foreach(LOG ${LOGS}) - file(TO_NATIVE_PATH "${LOG}" NATIVE_LOG) - list(APPEND STRINGIFIED_LOGS " ${NATIVE_LOG}\n") - endforeach() - z_vcpkg_prettify_command_line(_ebp_COMMAND_PRETTY ${_ebp_COMMAND}) - message(FATAL_ERROR - " Command failed: ${_ebp_COMMAND_PRETTY}\n" - " Working Directory: ${_ebp_WORKING_DIRECTORY}\n" - " See logs for more information:\n" - ${STRINGIFIED_LOGS}) - endif(error_code) - endif(error_code) -endfunction(vcpkg_execute_build_process) + if(NOT error_code EQUAL "0") + set(stringified_logs "") + foreach(log IN LISTS all_logs) + if(NOT EXISTS "${log}") + continue() + endif() + file(SIZE "${log}" log_size) + if(NOT log_size EQUAL "0") + file(TO_NATIVE_PATH "${log}" native_log) + string(APPEND stringified_logs " ${native_log}\n") + endif() + endforeach() + z_vcpkg_prettify_command_line(pretty_command ${arg_COMMAND}) + message(FATAL_ERROR + " Command failed: ${pretty_command}\n" + " Working Directory: ${arg_WORKING_DIRECTORY}\n" + " See logs for more information:\n" + "${stringified_logs}" + ) + endif() +endfunction() diff --git a/scripts/cmake/vcpkg_execute_in_download_mode.cmake b/scripts/cmake/vcpkg_execute_in_download_mode.cmake index 8ef77372953de8..bd88f8f5dce9ce 100644 --- a/scripts/cmake/vcpkg_execute_in_download_mode.cmake +++ b/scripts/cmake/vcpkg_execute_in_download_mode.cmake @@ -6,62 +6,60 @@ Execute a process even in download mode. ## Usage ```cmake vcpkg_execute_in_download_mode( - COMMAND [] - [WORKING_DIRECTORY ] - [TIMEOUT ] - [RESULT_VARIABLE ] - [OUTPUT_VARIABLE ] - [ERROR_VARIABLE ] - [INPUT_FILE ] - [OUTPUT_FILE ] - [ERROR_FILE ] - [OUTPUT_QUIET] - [ERROR_QUIET] - [OUTPUT_STRIP_TRAILING_WHITESPACE] - [ERROR_STRIP_TRAILING_WHITESPACE] - [ENCODING ] + ... ) ``` -The signature of this function is identical to `execute_process()` except that -it only accepts one COMMAND argument, i.e., does not support chaining multiple -commands with pipes. +The signature of this function is identical to `execute_process()`. -See [`execute_process()`] for a detailed description of the parameters. +See [`execute_process()`] for more details. [`execute_process()`]: https://cmake.org/cmake/help/latest/command/execute_process.html #]===] function(vcpkg_execute_in_download_mode) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 vcpkg_execute_in_download_mode - "OUTPUT_QUIET;ERROR_QUIET;OUTPUT_STRIP_TRAILING_WHITESPACE;ERROR_STRIP_TRAILING_WHITESPACE" - "WORKING_DIRECTORY;TIMEOUT;RESULT_VARIABLE;RESULTS_VARIABLE;OUTPUT_VARIABLE;ERROR_VARIABLE;INPUT_FILE;OUTPUT_FILE;ERROR_FILE;ENCODING" - "COMMAND") + # this allows us to grab the value of the output variables, but pass through the rest of the arguments + cmake_parse_arguments(PARSE_ARGV 0 arg "" "RESULT_VARIABLE;RESULTS_VARIABLE;OUTPUT_VARIABLE;ERROR_VARIABLE" "") - # collect all other present parameters - set(other_args "") - foreach(arg OUTPUT_QUIET ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) - if(vcpkg_execute_in_download_mode_${arg}) - list(APPEND other_args ${arg}) + set(output_and_error_same OFF) + set(output_variable_param "") + set(error_variable_param "") + set(result_variable_param "") + set(results_variable_param "") + if(DEFINED arg_OUTPUT_VARIABLE AND DEFINED arg_ERROR_VARIABLE AND arg_OUTPUT_VARIABLE STREQUAL arg_ERROR_VARIABLE) + set(output_variable_param OUTPUT_VARIABLE out_err_var) + set(error_variable_param ERROR_VARIABLE out_err_var) + set(output_and_error_same ON) + else() + if(DEFINED arg_OUTPUT_VARIABLE) + set(output_variable_param OUTPUT_VARIABLE out_var) endif() - endforeach() - foreach(arg WORKING_DIRECTORY TIMEOUT RESULT_VARIABLE RESULTS_VARIABLE OUTPUT_VARIABLE ERROR_VARIABLE INPUT_FILE OUTPUT_FILE ERROR_FILE ENCODING) - if(vcpkg_execute_in_download_mode_${arg}) - list(APPEND other_args ${arg} ${vcpkg_execute_in_download_mode_${arg}}) + if(DEFINED arg_ERROR_VARIABLE) + set(error_variable_param ERROR_VARIABLE err_var) endif() - endforeach() + endif() + if(DEFINED arg_RESULT_VARIABLE) + set(result_variable_param RESULT_VARIABLE result_var) + endif() + if(DEFINED arg_RESULTS_VARIABLE) + set(results_variable_param RESULTS_VARIABLE results_var) + endif() + + cmake_language(CALL "${Z_VCPKG_EXECUTE_PROCESS_NAME}" + ${arg_UNPARSED_ARGUMENTS} + ${output_variable_param} + ${error_variable_param} + ${result_variable_param} + ${results_variable_param} + ) - if (DEFINED VCPKG_DOWNLOAD_MODE) - _execute_process(COMMAND ${vcpkg_execute_in_download_mode_COMMAND} ${other_args}) + if(output_and_error_same) + z_vcpkg_forward_output_variable(arg_OUTPUT_VARIABLE out_err_var) else() - execute_process(COMMAND ${vcpkg_execute_in_download_mode_COMMAND} ${other_args}) + z_vcpkg_forward_output_variable(arg_OUTPUT_VARIABLE out_var) + z_vcpkg_forward_output_variable(arg_ERROR_VARIABLE err_var) endif() - # pass output parameters back to caller's scope - foreach(arg RESULT_VARIABLE RESULTS_VARIABLE OUTPUT_VARIABLE ERROR_VARIABLE) - if(vcpkg_execute_in_download_mode_${arg}) - set(${vcpkg_execute_in_download_mode_${arg}} ${${vcpkg_execute_in_download_mode_${arg}}} PARENT_SCOPE) - endif() - endforeach() + z_vcpkg_forward_output_variable(arg_RESULT_VARIABLE result_var) + z_vcpkg_forward_output_variable(arg_RESULTS_VARIABLE results_var) endfunction() diff --git a/scripts/cmake/vcpkg_execute_required_process.cmake b/scripts/cmake/vcpkg_execute_required_process.cmake index c38fd2ed80be94..27024fecfce862 100644 --- a/scripts/cmake/vcpkg_execute_required_process.cmake +++ b/scripts/cmake/vcpkg_execute_required_process.cmake @@ -48,28 +48,27 @@ This should be a unique name for different triplets so that the logs don't confl #]===] function(vcpkg_execute_required_process) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 vcpkg_execute_required_process "ALLOW_IN_DOWNLOAD_MODE" "WORKING_DIRECTORY;LOGNAME;TIMEOUT;OUTPUT_VARIABLE;ERROR_VARIABLE" "COMMAND") - set(LOG_OUT "${CURRENT_BUILDTREES_DIR}/${vcpkg_execute_required_process_LOGNAME}-out.log") - set(LOG_ERR "${CURRENT_BUILDTREES_DIR}/${vcpkg_execute_required_process_LOGNAME}-err.log") + cmake_parse_arguments(PARSE_ARGV 0 arg + "ALLOW_IN_DOWNLOAD_MODE" + "WORKING_DIRECTORY;LOGNAME;TIMEOUT;OUTPUT_VARIABLE;ERROR_VARIABLE" + "COMMAND" + ) - if(vcpkg_execute_required_process_TIMEOUT) - set(TIMEOUT_PARAM "TIMEOUT;${vcpkg_execute_required_process_TIMEOUT}") - else() - set(TIMEOUT_PARAM "") - endif() - if(vcpkg_execute_required_process_OUTPUT_VARIABLE) - set(OUTPUT_VARIABLE_PARAM "OUTPUT_VARIABLE;${vcpkg_execute_required_process_OUTPUT_VARIABLE}") - else() - set(OUTPUT_VARIABLE_PARAM "") + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") endif() - if(vcpkg_execute_required_process_ERROR_VARIABLE) - set(ERROR_VARIABLE_PARAM "ERROR_VARIABLE;${vcpkg_execute_required_process_ERROR_VARIABLE}") - else() - set(ERROR_VARIABLE_PARAM "") + foreach(required_arg IN ITEMS WORKING_DIRECTORY COMMAND) + if(NOT DEFINED arg_${required_arg}) + message(FATAL_ERROR "${required_arg} must be specified.") + endif() + endforeach() + + if(NOT DEFINED arg_LOGNAME) + message(WARNING "LOGNAME should be specified.") + set(arg_LOGNAME "required") endif() - if (DEFINED VCPKG_DOWNLOAD_MODE AND NOT vcpkg_execute_required_process_ALLOW_IN_DOWNLOAD_MODE) + if (VCPKG_DOWNLOAD_MODE AND NOT arg_ALLOW_IN_DOWNLOAD_MODE) message(FATAL_ERROR [[ This command cannot be executed in Download Mode. @@ -77,43 +76,69 @@ Halting portfile execution. ]]) endif() - vcpkg_execute_in_download_mode( - COMMAND ${vcpkg_execute_required_process_COMMAND} - OUTPUT_FILE ${LOG_OUT} - ERROR_FILE ${LOG_ERR} - RESULT_VARIABLE error_code - WORKING_DIRECTORY ${vcpkg_execute_required_process_WORKING_DIRECTORY} - ${TIMEOUT_PARAM} - ${OUTPUT_VARIABLE_PARAM} - ${ERROR_VARIABLE_PARAM}) - if(error_code) - set(LOGS) - file(READ "${LOG_OUT}" out_contents) - file(READ "${LOG_ERR}" err_contents) - if(out_contents) - list(APPEND LOGS "${LOG_OUT}") + set(log_out "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-out.log") + set(log_err "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-err.log") + + set(timeout_param "") + set(output_and_error_same OFF) + set(output_variable_param "") + set(error_variable_param "") + + if(DEFINED arg_TIMEOUT) + set(timeout_param TIMEOUT "${arg_TIMEOUT}") + endif() + if(DEFINED arg_OUTPUT_VARIABLE AND DEFINED arg_ERROR_VARIABLE AND arg_OUTPUT_VARIABLE STREQUAL arg_ERROR_VARIABLE) + set(output_variable_param OUTPUT_VARIABLE out_err_var) + set(error_variable_param ERROR_VARIABLE out_err_var) + set(output_and_error_same ON) + else() + if(DEFINED arg_OUTPUT_VARIABLE) + set(output_variable_param OUTPUT_VARIABLE out_var) endif() - if(err_contents) - list(APPEND LOGS "${LOG_ERR}") + if(DEFINED arg_ERROR_VARIABLE) + set(error_variable_param ERROR_VARIABLE err_var) endif() - set(STRINGIFIED_LOGS) - foreach(LOG ${LOGS}) - file(TO_NATIVE_PATH "${LOG}" NATIVE_LOG) - list(APPEND STRINGIFIED_LOGS " ${NATIVE_LOG}\n") + endif() + + vcpkg_execute_in_download_mode( + COMMAND ${arg_COMMAND} + OUTPUT_FILE "${log_out}" + ERROR_FILE "${log_err}" + RESULT_VARIABLE error_code + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" + ${timeout_param} + ${output_variable_param} + ${error_variable_param} + ) + if(NOT error_code EQUAL 0) + set(stringified_logs "") + foreach(log IN ITEMS "${log_out}" "${log_err}") + if(NOT EXISTS "${log}") + continue() + endif() + file(SIZE "${log}" log_size) + if(NOT log_size EQUAL "0") + file(TO_NATIVE_PATH "${log}" native_log) + string(APPEND stringified_logs " ${native_log}\n") + endif() endforeach() - z_vcpkg_prettify_command_line(vcpkg_execute_required_process_COMMAND_PRETTY ${vcpkg_execute_required_process_COMMAND}) + + z_vcpkg_prettify_command_line(pretty_command ${arg_COMMAND}) message(FATAL_ERROR - " Command failed: ${vcpkg_execute_required_process_COMMAND_PRETTY}\n" - " Working Directory: ${vcpkg_execute_required_process_WORKING_DIRECTORY}\n" + " Command failed: ${pretty_command}\n" + " Working Directory: ${arg_WORKING_DIRECTORY}\n" " Error code: ${error_code}\n" " See logs for more information:\n" - ${STRINGIFIED_LOGS} + "${stringified_logs}" ) endif() + # pass output parameters back to caller's scope - foreach(arg OUTPUT_VARIABLE ERROR_VARIABLE) - if(vcpkg_execute_required_process_${arg}) - set(${vcpkg_execute_required_process_${arg}} ${${vcpkg_execute_required_process_${arg}}} PARENT_SCOPE) - endif() - endforeach() + if(output_and_error_same) + z_vcpkg_forward_output_variable(arg_OUTPUT_VARIABLE out_err_var) + # arg_ERROR_VARIABLE = arg_OUTPUT_VARIABLE, so no need to set it again + else() + z_vcpkg_forward_output_variable(arg_OUTPUT_VARIABLE out_var) + z_vcpkg_forward_output_variable(arg_ERROR_VARIABLE err_var) + endif() endfunction() diff --git a/scripts/cmake/vcpkg_execute_required_process_repeat.cmake b/scripts/cmake/vcpkg_execute_required_process_repeat.cmake index 3e63a998c61fd8..3ad8d05ce9fe1a 100644 --- a/scripts/cmake/vcpkg_execute_required_process_repeat.cmake +++ b/scripts/cmake/vcpkg_execute_required_process_repeat.cmake @@ -6,48 +6,79 @@ Execute a process until the command succeeds, or until the COUNT is reached. ## Usage ```cmake vcpkg_execute_required_process_repeat( - COUNT COMMAND [] + COUNT WORKING_DIRECTORY LOGNAME + [ALLOW_IN_DOWNLOAD_MODE] ) ``` #]===] function(vcpkg_execute_required_process_repeat) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 vcpkg_execute_required_process_repeat "ALLOW_IN_DOWNLOAD_MODE" "COUNT;WORKING_DIRECTORY;LOGNAME" "COMMAND") - #debug_message("vcpkg_execute_required_process_repeat(${vcpkg_execute_required_process_repeat_COMMAND})") - if (DEFINED VCPKG_DOWNLOAD_MODE AND NOT vcpkg_execute_required_process_repeat_ALLOW_IN_DOWNLOAD_MODE) + cmake_parse_arguments(PARSE_ARGV 0 arg + "ALLOW_IN_DOWNLOAD_MODE" + "COUNT;WORKING_DIRECTORY;LOGNAME" + "COMMAND" + ) + + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + foreach(required_arg IN ITEMS COUNT WORKING_DIRECTORY LOGNAME COMMAND) + if(NOT DEFINED arg_${required_arg}) + message(FATAL_ERROR "${required_arg} must be specified.") + endif() + endforeach() + + # also checks for COUNT being an integer + if(NOT arg_COUNT GREATER_EQUAL "1") + message(FATAL_ERROR "COUNT (${arg_COUNT}) must be greater than or equal to 1.") + endif() + + if (DEFINED VCPKG_DOWNLOAD_MODE AND NOT arg_ALLOW_IN_DOWNLOAD_MODE) message(FATAL_ERROR [[ This command cannot be executed in Download Mode. Halting portfile execution. ]]) endif() - set(SUCCESSFUL_EXECUTION FALSE) - foreach(loop_count RANGE ${vcpkg_execute_required_process_repeat_COUNT}) + + set(all_logs "") + foreach(loop_count RANGE 1 ${arg_COUNT}) + set(out_log "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-out-${loop_count}.log") + set(err_log "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-out-${loop_count}.log") + list(APPEND all_logs "${out_log}" "${err_log}") + vcpkg_execute_in_download_mode( - COMMAND ${vcpkg_execute_required_process_repeat_COMMAND} - OUTPUT_FILE ${CURRENT_BUILDTREES_DIR}/${vcpkg_execute_required_process_repeat_LOGNAME}-out-${loop_count}.log - ERROR_FILE ${CURRENT_BUILDTREES_DIR}/${vcpkg_execute_required_process_repeat_LOGNAME}-err-${loop_count}.log + COMMAND ${arg_COMMAND} + OUTPUT_FILE "${out_log}" + ERROR_FILE "${err_log}" RESULT_VARIABLE error_code - WORKING_DIRECTORY ${vcpkg_execute_required_process_repeat_WORKING_DIRECTORY}) - #debug_message("error_code=${error_code}") - file(TO_NATIVE_PATH "${CURRENT_BUILDTREES_DIR}" NATIVE_BUILDTREES_DIR) - if(NOT error_code) - set(SUCCESSFUL_EXECUTION TRUE) - break() - endif() - endforeach(loop_count) - if (NOT SUCCESSFUL_EXECUTION) - z_vcpkg_prettify_command_line(vcpkg_execute_required_process_repeat_COMMAND_PRETTY ${vcpkg_execute_required_process_repeat_COMMAND}) - message(FATAL_ERROR - " Command failed: ${vcpkg_execute_required_process_repeat_COMMAND_PRETTY}\n" - " Working Directory: ${vcpkg_execute_required_process_repeat_WORKING_DIRECTORY}\n" - " See logs for more information:\n" - " ${NATIVE_BUILDTREES_DIR}\\${vcpkg_execute_required_process_repeat_LOGNAME}-out.log\n" - " ${NATIVE_BUILDTREES_DIR}\\${vcpkg_execute_required_process_repeat_LOGNAME}-err.log\n" + WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}" ) - endif() + if(error_code EQUAL "0") + return() + endif() + endforeach() + + set(stringified_logs "") + foreach(log IN LISTS all_logs) + if(NOT EXISTS "${log}") + continue() + endif() + file(SIZE "${log}" log_size) + if(NOT log_size EQUAL "0") + file(TO_NATIVE_PATH "${log}" native_log) + string(APPEND stringified_logs " ${native_log}\n") + endif() + endforeach() + + z_vcpkg_prettify_command_line(pretty_command ${arg_COMMAND}) + message(FATAL_ERROR + " Command failed: ${pretty_command}\n" + " Working Directory: ${arg_WORKING_DIRECTORY}\n" + " See logs for more information:\n" + "${stringifed_logs}" + ) endfunction() diff --git a/scripts/cmake/vcpkg_extract_source_archive.cmake b/scripts/cmake/vcpkg_extract_source_archive.cmake index 631d6da59f9e78..59daac7d914b0a 100644 --- a/scripts/cmake/vcpkg_extract_source_archive.cmake +++ b/scripts/cmake/vcpkg_extract_source_archive.cmake @@ -1,27 +1,74 @@ #[===[.md: # vcpkg_extract_source_archive -Extract an archive into the source directory. Deprecated in favor of [`vcpkg_extract_source_archive_ex`](vcpkg_extract_source_archive_ex.md). +Extract an archive into the source directory. ## Usage +There are two "overloads" of this function. The first is deprecated: + ```cmake -vcpkg_extract_source_archive( - <${ARCHIVE}> [<${TARGET_DIRECTORY}>] +vcpkg_extract_source_archive(<${ARCHIVE}> [<${TARGET_DIRECTORY}>]) +``` + +This overload should not be used. + +The latter is suggested to use for all future `vcpkg_extract_source_archive`s. + +```cmake +vcpkg_extract_source_archive( + ARCHIVE + [NO_REMOVE_ONE_LEVEL] + [PATCHES ...] + [SOURCE_BASE ] + [BASE_DIRECTORY | WORKING_DIRECTORY ] ) ``` -## Parameters -### ARCHIVE -The full path to the archive to be extracted. -This is usually obtained from calling [`vcpkg_download_distfile`](vcpkg_download_distfile.md). +`vcpkg_extract_source_archive` takes an archive and extracts it. +It replaces existing uses of `vcpkg_extract_source_archive_ex`. +The simplest use of it is: + +```cmake +vcpkg_download_distfile(archive ...) +vcpkg_extract_source_archive(source_path ARCHIVE "${archive}") +``` + +The general expectation is that an archives are laid out with a base directory, +and all the actual files underneath that directory; in other words, if you +extract the archive, you'll get something that looks like: + +``` +zlib-1.2.11/ + doc/ + ... + examples/ + ... + ChangeLog + CMakeLists.txt + README + zlib.h + ... +``` -### TARGET_DIRECTORY -If specified, the archive will be extracted into the target directory instead of `${CURRENT_BUILDTREES_DIR}/src/`. +`vcpkg_extract_source_archive` automatically removes this directory, +and gives you the items under it directly. However, this only works +when there is exactly one item in the top level of an archive. +Otherwise, you'll have to pass the `NO_REMOVE_ONE_LEVEL` argument to +prevent `vcpkg_extract_source_archive` from performing this transformation. -This can be used to mimic git submodules, by extracting into a subdirectory of another archive. +If the source needs to be patched in some way, the `PATCHES` argument +allows one to do this, just like other `vcpkg_from_*` functions. -## Notes -This command will also create a tracking file named .extracted in the TARGET_DIRECTORY. This file, when present, will suppress the extraction of the archive. +`vcpkg_extract_source_archive` extracts the files to +`${CURRENT_BUILDTREES_DIR}//-.clean`. +When in editable mode, no `.clean` is appended, +to allow for a user to modify the sources. +`base-directory` defaults to `src`, +and `source-base` defaults to the stem of ``. +You can change these via the `BASE_DIRECTORY` and `SOURCE_BASE` arguments +respectively. +If you need to extract to a location that is not based in `CURRENT_BUILDTREES_DIR`, +you can use the `WORKING_DIRECTORY` argument to do the same. ## Examples @@ -30,25 +77,166 @@ This command will also create a tracking file named .extracted in the * [msgpack](https://github.com/Microsoft/vcpkg/blob/master/ports/msgpack/portfile.cmake) #]===] -include(vcpkg_execute_required_process) +function(z_vcpkg_extract_source_archive_deprecated_mode archive working_directory) + cmake_path(GET archive FILENAME archive_filename) + if(NOT EXISTS "${working_directory}/${archive_filename}.extracted") + message(STATUS "Extracting source ${archive}") + file(MAKE_DIRECTORY "${working_directory}") + vcpkg_execute_required_process( + ALLOW_IN_DOWNLOAD_MODE + COMMAND "${CMAKE_COMMAND}" -E tar xjf "${archive}" + WORKING_DIRECTORY "${working_directory}" + LOGNAME extract + ) + file(TOUCH "${working_directory}/${archive_filename}.extracted") + endif() +endfunction() -function(vcpkg_extract_source_archive ARCHIVE) - if(NOT ARGC EQUAL 2) - set(WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/src") +function(vcpkg_extract_source_archive) + if(ARGC LESS_EQUAL "2") + z_vcpkg_deprecation_message( "Deprecated form of vcpkg_extract_source_archive used: + Please use the `vcpkg_extract_source_archive( ARCHIVE )` form.") + if(ARGC EQUAL "0") + message(FATAL_ERROR "vcpkg_extract_source_archive requires at least one argument.") + endif() + + set(archive "${ARGV0}") + if(ARGC EQUAL "1") + set(working_directory "${CURRENT_BUILDTREES_DIR}/src") + else() + set(working_directory "${ARGV1}") + endif() + + z_vcpkg_extract_source_archive_deprecated_mode("${archive}" "${working_directory}") + return() + endif() + + set(out_source_path "${ARGV0}") + cmake_parse_arguments(PARSE_ARGV 1 "arg" + "NO_REMOVE_ONE_LEVEL;SKIP_PATCH_CHECK;Z_ALLOW_OLD_PARAMETER_NAMES" + "ARCHIVE;SOURCE_BASE;BASE_DIRECTORY;WORKING_DIRECTORY;REF" + "PATCHES" + ) + + if(DEFINED arg_REF) + if(NOT arg_Z_ALLOW_OLD_PARAMETER_NAMES) + message(FATAL_ERROR "Unexpected argument REF") + elseif(DEFINED arg_SOURCE_BASE) + message(FATAL_ERROR "Cannot specify both REF and SOURCE_BASE") + else() + string(REPLACE "/" "-" arg_SOURCE_BASE "${arg_REF}") + endif() + endif() + + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + if(NOT DEFINED arg_ARCHIVE) + message(FATAL_ERROR "ARCHIVE must be specified") + endif() + + if(DEFINED arg_WORKING_DIRECTORY) + if(DEFINED arg_BASE_DIRECTORY) + message(FATAL_ERROR "Cannot specify both BASE_DIRECTORY and WORKING_DIRECTORY") + elseif(NOT IS_ABSOLUTE "${arg_WORKING_DIRECTORY}") + message(FATAL_ERROR "WORKING_DIRECTORY (${arg_WORKING_DIRECTORY}) must be an absolute path") + endif() + set(working_directory "${arg_WORKING_DIRECTORY}") else() - set(WORKING_DIRECTORY ${ARGV1}) + if(NOT DEFINED arg_BASE_DIRECTORY) + set(arg_BASE_DIRECTORY "src") + elseif(IS_ABSOLUTE "${arg_BASE_DIRECTORY}") + message(FATAL_ERROR "BASE_DIRECTORY (${arg_BASE_DIRECTORY}) must be a relative path") + endif() + cmake_path(APPEND CURRENT_BUILDTREES_DIR "${arg_BASE_DIRECTORY}" + OUTPUT_VARIABLE working_directory) endif() - get_filename_component(ARCHIVE_FILENAME "${ARCHIVE}" NAME) - if(NOT EXISTS ${WORKING_DIRECTORY}/${ARCHIVE_FILENAME}.extracted) - message(STATUS "Extracting source ${ARCHIVE}") - file(MAKE_DIRECTORY ${WORKING_DIRECTORY}) - vcpkg_execute_required_process( - ALLOW_IN_DOWNLOAD_MODE - COMMAND ${CMAKE_COMMAND} -E tar xjf ${ARCHIVE} - WORKING_DIRECTORY ${WORKING_DIRECTORY} - LOGNAME extract + if(NOT DEFINED arg_SOURCE_BASE) + cmake_path(GET arg_ARCHIVE STEM arg_SOURCE_BASE) + elseif(arg_SOURCE_BASE MATCHES [[\\|/]]) + message(FATAL_ERROR "SOURCE_BASE (${arg_SOURCE_BASE}) must not contain slashes") + endif() + + # Take the last 10 chars of the base + set(base_max_length 10) + string(LENGTH "${arg_SOURCE_BASE}" source_base_length) + if(source_base_length GREATER base_max_length) + math(EXPR start "${source_base_length} - ${base_max_length}") + string(SUBSTRING "${arg_SOURCE_BASE}" "${start}" -1 arg_SOURCE_BASE) + endif() + + # Hash the archive hash along with the patches. Take the first 10 chars of the hash + file(SHA512 "${arg_ARCHIVE}" patchset_hash) + foreach(patch IN LISTS arg_PATCHES) + cmake_path(ABSOLUTE_PATH patch + BASE_DIRECTORY "${CURRENT_PORT_DIR}" + OUTPUT_VARIABLE absolute_patch ) - file(WRITE ${WORKING_DIRECTORY}/${ARCHIVE_FILENAME}.extracted) + if(NOT EXISTS "${absolute_patch}") + message(FATAL_ERROR "Could not find patch: '${patch}'") + endif() + file(SHA512 "${absolute_patch}" current_hash) + string(APPEND patchset_hash "${current_hash}") + endforeach() + + string(SHA512 patchset_hash "${patchset_hash}") + string(SUBSTRING "${patchset_hash}" 0 10 patchset_hash) + cmake_path(APPEND working_directory "${arg_SOURCE_BASE}-${patchset_hash}" + OUTPUT_VARIABLE source_path + ) + + if(_VCPKG_EDITABLE AND EXISTS "${source_path}") + set("${out_source_path}" "${source_path}" PARENT_SCOPE) + message(STATUS "Using source at ${source_path}") + return() + elseif(NOT _VCPKG_EDITABLE) + cmake_path(APPEND_STRING source_path ".clean") + if(EXISTS "${source_path}") + message(STATUS "Cleaning sources at ${source_path}. Use --editable to skip cleaning for the packages you specify.") + file(REMOVE_RECURSE "${source_path}") + endif() + endif() + + message(STATUS "Extracting source ${arg_ARCHIVE}") + cmake_path(APPEND_STRING source_path ".tmp" OUTPUT_VARIABLE temp_dir) + file(REMOVE_RECURSE "${temp_dir}") + file(MAKE_DIRECTORY "${temp_dir}") + vcpkg_execute_required_process( + ALLOW_IN_DOWNLOAD_MODE + COMMAND "${CMAKE_COMMAND}" -E tar xjf "${arg_ARCHIVE}" + WORKING_DIRECTORY "${temp_dir}" + LOGNAME extract + ) + + if(arg_NO_REMOVE_ONE_LEVEL) + cmake_path(SET temp_source_path "${temp_dir}") + else() + file(GLOB archive_directory "${temp_dir}/*") + # make sure `archive_directory` is only a single file + if(NOT archive_directory MATCHES ";" AND IS_DIRECTORY "${archive_directory}") + cmake_path(SET temp_source_path "${archive_directory}") + else() + message(FATAL_ERROR "Could not unwrap top level directory from archive. Pass NO_REMOVE_ONE_LEVEL to disable this.") + endif() + endif() + + if (arg_Z_SKIP_PATCH_CHECK) + set(quiet_param QUIET) + else() + set(quiet_param "") endif() + + z_vcpkg_apply_patches( + SOURCE_PATH "${temp_source_path}" + PATCHES ${arg_PATCHES} + ${quiet_param} + ) + + file(RENAME "${temp_source_path}" "${source_path}") + file(REMOVE_RECURSE "${temp_dir}") + + set("${out_source_path}" "${source_path}" PARENT_SCOPE) + message(STATUS "Using source at ${source_path}") endfunction() + diff --git a/scripts/cmake/vcpkg_extract_source_archive_ex.cmake b/scripts/cmake/vcpkg_extract_source_archive_ex.cmake index 633b40b1aec571..fb48c799d8d3c7 100644 --- a/scripts/cmake/vcpkg_extract_source_archive_ex.cmake +++ b/scripts/cmake/vcpkg_extract_source_archive_ex.cmake @@ -1,157 +1,35 @@ #[===[.md: # vcpkg_extract_source_archive_ex -Extract an archive into the source directory. Replaces [`vcpkg_extract_source_archive`](vcpkg_extract_source_archive.md). +Extract an archive into the source directory. +Originally replaced [`vcpkg_extract_source_archive()`], +but new ports should instead use the second overload of +[`vcpkg_extract_source_archive()`]. ## Usage ```cmake vcpkg_extract_source_archive_ex( - SKIP_PATCH_CHECK - OUT_SOURCE_PATH - ARCHIVE <${ARCHIVE}> - [REF <1.0.0>] - [NO_REMOVE_ONE_LEVEL] - [WORKING_DIRECTORY <${CURRENT_BUILDTREES_DIR}/src>] - [PATCHES ...] + [OUT_SOURCE_PATH ] + ... ) ``` -## Parameters -### SKIP_PATCH_CHECK -If this option is set the failure to apply a patch is ignored. -### OUT_SOURCE_PATH -Specifies the out-variable that will contain the extracted location. +See the documentation for [`vcpkg_extract_source_archive()`] for other parameters. +Additionally, `vcpkg_extract_source_archive_ex()` adds the `REF` and `WORKING_DIRECTORY` +parameters, which are wrappers around `SOURCE_BASE` and `BASE_DIRECTORY` +respectively. -This should be set to `SOURCE_PATH` by convention. - -### ARCHIVE -The full path to the archive to be extracted. - -This is usually obtained from calling [`vcpkg_download_distfile`](vcpkg_download_distfile.md). - -### REF -A friendly name that will be used instead of the filename of the archive. If more than 10 characters it will be truncated. - -By convention, this is set to the version number or tag fetched - -### WORKING_DIRECTORY -If specified, the archive will be extracted into the working directory instead of `${CURRENT_BUILDTREES_DIR}/src/`. - -Note that the archive will still be extracted into a subfolder underneath that directory (`${WORKING_DIRECTORY}/${REF}-${HASH}/`). - -### PATCHES -A list of patches to be applied to the extracted sources. - -Relative paths are based on the port directory. - -### NO_REMOVE_ONE_LEVEL -Specifies that the default removal of the top level folder should not occur. - -## Examples - -* [bzip2](https://github.com/Microsoft/vcpkg/blob/master/ports/bzip2/portfile.cmake) -* [sqlite3](https://github.com/Microsoft/vcpkg/blob/master/ports/sqlite3/portfile.cmake) -* [cairo](https://github.com/Microsoft/vcpkg/blob/master/ports/cairo/portfile.cmake) +[`vcpkg_extract_source_archive()`]: vcpkg_extract_source_archive.md #]===] -include(vcpkg_extract_source_archive) - function(vcpkg_extract_source_archive_ex) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments( - PARSE_ARGV 0 - _vesae - "NO_REMOVE_ONE_LEVEL;SKIP_PATCH_CHECK" - "OUT_SOURCE_PATH;ARCHIVE;REF;WORKING_DIRECTORY" - "PATCHES" - ) - - if(NOT _vesae_ARCHIVE) - message(FATAL_ERROR "Must specify ARCHIVE parameter to vcpkg_extract_source_archive_ex()") - endif() - - if(NOT DEFINED _vesae_OUT_SOURCE_PATH) - message(FATAL_ERROR "Must specify OUT_SOURCE_PATH parameter to vcpkg_extract_source_archive_ex()") + # OUT_SOURCE_PATH is an out-parameter so we need to parse it + cmake_parse_arguments(PARSE_ARGV 0 "arg" "" "OUT_SOURCE_PATH" "") + if(NOT DEFINED arg_OUT_SOURCE_PATH) + message(FATAL_ERROR "OUT_SOURCE_PATH must be specified") endif() - if(NOT DEFINED _vesae_WORKING_DIRECTORY) - set(_vesae_WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/src) - endif() - - if(NOT DEFINED _vesae_REF) - get_filename_component(_vesae_REF ${_vesae_ARCHIVE} NAME_WE) - endif() - - string(REPLACE "/" "-" SANITIZED_REF "${_vesae_REF}") - - # Take the last 10 chars of the REF - set(REF_MAX_LENGTH 10) - string(LENGTH ${SANITIZED_REF} REF_LENGTH) - math(EXPR FROM_REF ${REF_LENGTH}-${REF_MAX_LENGTH}) - if(FROM_REF LESS 0) - set(FROM_REF 0) - endif() - string(SUBSTRING ${SANITIZED_REF} ${FROM_REF} ${REF_LENGTH} SHORTENED_SANITIZED_REF) - - # Hash the archive hash along with the patches. Take the first 10 chars of the hash - file(SHA512 ${_vesae_ARCHIVE} PATCHSET_HASH) - foreach(PATCH IN LISTS _vesae_PATCHES) - get_filename_component(ABSOLUTE_PATCH "${PATCH}" ABSOLUTE BASE_DIR "${CURRENT_PORT_DIR}") - file(SHA512 ${ABSOLUTE_PATCH} CURRENT_HASH) - string(APPEND PATCHSET_HASH ${CURRENT_HASH}) - endforeach() - - string(SHA512 PATCHSET_HASH ${PATCHSET_HASH}) - string(SUBSTRING ${PATCHSET_HASH} 0 10 PATCHSET_HASH) - set(SOURCE_PATH "${_vesae_WORKING_DIRECTORY}/${SHORTENED_SANITIZED_REF}-${PATCHSET_HASH}") - if (NOT _VCPKG_EDITABLE) - string(APPEND SOURCE_PATH ".clean") - if(EXISTS ${SOURCE_PATH}) - message(STATUS "Cleaning sources at ${SOURCE_PATH}. Use --editable to skip cleaning for the packages you specify.") - file(REMOVE_RECURSE ${SOURCE_PATH}) - endif() - endif() - - if(NOT EXISTS ${SOURCE_PATH}) - set(TEMP_DIR "${_vesae_WORKING_DIRECTORY}/${SHORTENED_SANITIZED_REF}-${PATCHSET_HASH}.tmp") - file(REMOVE_RECURSE ${TEMP_DIR}) - vcpkg_extract_source_archive("${_vesae_ARCHIVE}" "${TEMP_DIR}") - - if(_vesae_NO_REMOVE_ONE_LEVEL) - set(TEMP_SOURCE_PATH ${TEMP_DIR}) - else() - file(GLOB _ARCHIVE_FILES "${TEMP_DIR}/*") - list(LENGTH _ARCHIVE_FILES _NUM_ARCHIVE_FILES) - set(TEMP_SOURCE_PATH) - foreach(dir IN LISTS _ARCHIVE_FILES) - if (IS_DIRECTORY ${dir}) - set(TEMP_SOURCE_PATH "${dir}") - break() - endif() - endforeach() - - if(NOT _NUM_ARCHIVE_FILES EQUAL 2 OR NOT TEMP_SOURCE_PATH) - message(FATAL_ERROR "Could not unwrap top level directory from archive. Pass NO_REMOVE_ONE_LEVEL to disable this.") - endif() - endif() - - if (_vesae_SKIP_PATCH_CHECK) - set (QUIET QUIET) - else() - set (QUIET) - endif() - - z_vcpkg_apply_patches( - ${QUIET} - SOURCE_PATH ${TEMP_SOURCE_PATH} - PATCHES ${_vesae_PATCHES} - ) - - file(RENAME ${TEMP_SOURCE_PATH} ${SOURCE_PATH}) - file(REMOVE_RECURSE ${TEMP_DIR}) - endif() + vcpkg_extract_source_archive(source_path ${arg_UNPARSED_ARGUMENTS} Z_ALLOW_OLD_PARAMETER_NAMES) - set(${_vesae_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - message(STATUS "Using source at ${SOURCE_PATH}") - return() + set("${arg_OUT_SOURCE_PATH}" "${source_path}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_find_acquire_program.cmake b/scripts/cmake/vcpkg_find_acquire_program.cmake index f6157aebad0cc7..e279073cad4714 100644 --- a/scripts/cmake/vcpkg_find_acquire_program.cmake +++ b/scripts/cmake/vcpkg_find_acquire_program.cmake @@ -522,6 +522,10 @@ function(vcpkg_find_acquire_program VAR) if(DEFINED SUBDIR) list(APPEND PATHS ${PROG_PATH_SUBDIR}) endif() + if("${PROG_PATH_SUBDIR}" MATCHES [[^(.*)[/\\]$]]) + # remove trailing slash, which may turn into a trailing `\` which CMake _does not like_ + set(PROG_PATH_SUBDIR "${CMAKE_MATCH_1}") + endif() do_find() if(NOT ${VAR}) diff --git a/scripts/cmake/vcpkg_from_bitbucket.cmake b/scripts/cmake/vcpkg_from_bitbucket.cmake index a376e810591b56..442ea642dc2922 100644 --- a/scripts/cmake/vcpkg_from_bitbucket.cmake +++ b/scripts/cmake/vcpkg_from_bitbucket.cmake @@ -2,7 +2,6 @@ # vcpkg_from_bitbucket Download and extract a project from Bitbucket. -Enables support for installing HEAD `vcpkg.exe install --head `. ## Usage: ```cmake @@ -58,144 +57,95 @@ This exports the `VCPKG_HEAD_VERSION` variable during head builds. #]===] function(vcpkg_from_bitbucket) - set(oneValueArgs OUT_SOURCE_PATH REPO REF SHA512 HEAD_REF) - set(multipleValuesArgs PATCHES) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vdud "" "${oneValueArgs}" "${multipleValuesArgs}") + cmake_parse_arguments(PARSE_ARGV 0 "arg" + "" + "OUT_SOURCE_PATH;REPO;REF;SHA512;HEAD_REF" + "PATCHES") - if(NOT _vdud_OUT_SOURCE_PATH) - message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "vcpkg_from_bitbucket was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") endif() - if((_vdud_REF AND NOT _vdud_SHA512) OR (NOT _vdud_REF AND _vdud_SHA512)) + if(DEFINED arg_REF AND NOT DEFINED arg_SHA512) message(FATAL_ERROR "SHA512 must be specified if REF is specified.") endif() + if(NOT DEFINED arg_REF AND DEFINED arg_SHA512) + message(FATAL_ERROR "REF must be specified if SHA512 is specified.") + endif() - if(NOT _vdud_REPO) + if(NOT DEFINED arg_OUT_SOURCE_PATH) + message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + endif() + if(NOT DEFINED arg_REPO) message(FATAL_ERROR "The Bitbucket repository must be specified.") endif() - if(NOT _vdud_REF AND NOT _vdud_HEAD_REF) - message(FATAL_ERROR "At least one of REF and HEAD_REF must be specified.") + if(NOT DEFINED arg_REF AND NOT DEFINED arg_HEAD_REF) + message(FATAL_ERROR "At least one of REF or HEAD_REF must be specified.") endif() - string(REGEX REPLACE ".*/" "" REPO_NAME ${_vdud_REPO}) - string(REGEX REPLACE "/.*" "" ORG_NAME ${_vdud_REPO}) - - macro(set_SOURCE_PATH BASE BASEREF) - set(SOURCE_PATH "${BASE}/${ORG_NAME}-${REPO_NAME}-${BASEREF}") - if(EXISTS ${SOURCE_PATH}) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - else() - # Sometimes GitHub strips a leading 'v' off the REF. - string(REGEX REPLACE "^v" "" REF ${BASEREF}) - set(SOURCE_PATH "${BASE}/${ORG_NAME}-${REPO_NAME}-${REF}") - if(EXISTS ${SOURCE_PATH}) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - else() - message(FATAL_ERROR "Could not determine source path: '${BASE}/${ORG_NAME}-${REPO_NAME}-${BASEREF}' does not exist") - endif() - endif() - endmacro() - - if(VCPKG_USE_HEAD_VERSION AND NOT _vdud_HEAD_REF) - message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") - set(VCPKG_USE_HEAD_VERSION OFF) + if(NOT arg_REPO MATCHES "^([^/]*)/([^/]*)$") + message(FATAL_ERROR "REPO (${arg_REPO}) is not a valid repo name: + must be an organization name followed by a repository name separated by a single slash.") endif() - - # Handle --no-head scenarios - if(NOT VCPKG_USE_HEAD_VERSION) - if(NOT _vdud_REF) - message(FATAL_ERROR "Package does not specify REF. It must built using --head.") - endif() - - set(URL "https://bitbucket.com/${ORG_NAME}/${REPO_NAME}/get/${_vdud_REF}.tar.gz") - set(downloaded_file_path "${DOWNLOADS}/${ORG_NAME}-${REPO_NAME}-${_vdud_REF}.tar.gz") - - file(DOWNLOAD "https://api.bitbucket.com/2.0/repositories/${ORG_NAME}/${REPO_NAME}/refs/tags/${_vdud_REF}" - ${downloaded_file_path}.version - STATUS download_status - ) - list(GET download_status 0 status_code) - if ("${status_code}" STREQUAL "0") - # Parse the github refs response with regex. - # TODO: use some JSON swiss-army-knife utility instead. - file(READ "${downloaded_file_path}.version" _contents) - string(REGEX MATCH "\"hash\": \"[a-f0-9]+\"" x "${_contents}") - string(REGEX REPLACE "\"hash\": \"([a-f0-9]+)\"" "\\1" _version ${x}) - string(SUBSTRING ${_version} 0 12 _version) # Get the 12 first numbers from commit hash + set(org_name "${CMAKE_MATCH_1}") + set(repo_name "${CMAKE_MATCH_2}") + + set(redownload_param "") + set(working_directory_param "") + set(sha512_param "SHA512" "${arg_SHA512}") + set(ref_to_use "${arg_REF}") + if(VCPKG_USE_HEAD_VERSION) + if(DEFINED arg_HEAD_REF) + set(redownload_param "ALWAYS_REDOWNLOAD") + set(sha512_param "SKIP_SHA512") + set(working_directory_param "WORKING_DIRECTORY" "${CURRENT_BUILDTREES_DIR}/src/head") + set(ref_to_use "${arg_HEAD_REF}") else() - string(SUBSTRING ${_vdud_REF} 0 12 _version) # Get the 12 first numbers from commit hash + message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") endif() - - vcpkg_download_distfile(ARCHIVE - URLS "https://bitbucket.com/${ORG_NAME}/${REPO_NAME}/get/${_vdud_REF}.tar.gz" - SHA512 "${_vdud_SHA512}" - FILENAME "${ORG_NAME}-${REPO_NAME}-${_vdud_REF}.tar.gz" - ) - - vcpkg_extract_source_archive_ex( - OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${ARCHIVE}" - REF "${_vdud_REF}" - PATCHES ${_vdud_PATCHES} - ) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - return() + elseif(NOT DEFINED arg_REF) + message(FATAL_ERROR "Package does not specify REF. It must be built using --head.") endif() - # The following is for --head scenarios - set(URL "https://bitbucket.com/${ORG_NAME}/${REPO_NAME}/get/${_vdud_HEAD_REF}.tar.gz") - set(downloaded_file_name "${ORG_NAME}-${REPO_NAME}-${_vdud_HEAD_REF}.tar.gz") - set(downloaded_file_path "${DOWNLOADS}/${downloaded_file_name}") - - if(_VCPKG_NO_DOWNLOADS) - if(NOT EXISTS ${downloaded_file_path} OR NOT EXISTS ${downloaded_file_path}.version) - message(FATAL_ERROR "Downloads are disabled, but '${downloaded_file_path}' does not exist.") - endif() - message(STATUS "Using cached ${downloaded_file_path}") - else() - if(EXISTS ${downloaded_file_path}) - message(STATUS "Purging cached ${downloaded_file_path} to fetch latest (use --no-downloads to suppress)") - file(REMOVE ${downloaded_file_path}) - endif() - if(EXISTS ${downloaded_file_path}.version) - file(REMOVE ${downloaded_file_path}.version) - endif() - if(EXISTS ${CURRENT_BUILDTREES_DIR}/src/head) - file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/src/head) - endif() + # avoid using either - or _, to allow both `foo/bar` and `foo-bar` to coexist + # we assume that no one will name a ref "foo_-bar" + string(REPLACE "/" "_-" sanitized_ref "${ref_to_use}") + set(downloaded_file_name "${org_name}-${repo_name}-${sanitized_ref}.tar.gz") - # Try to download the file and version information from bitbucket. - vcpkg_download_distfile(ARCHIVE_VERSION - URLS "https://api.bitbucket.com/2.0/repositories/${ORG_NAME}/${REPO_NAME}/refs/branches/${_vdud_HEAD_REF}" + # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. + if(VCPKG_USE_HEAD_VERSION) + vcpkg_download_distfile(archive_version + URLS "https://api.bitbucket.com/2.0/repositories/${org_name}/${repo_name}/refs/branches/${arg_HEAD_REF}" FILENAME "${downloaded_file_name}.version" SKIP_SHA512 + ALWAYS_REDOWNLOAD ) - - vcpkg_download_distfile(ARCHIVE - URLS "${URL}" - FILENAME "${downloaded_file_name}" - SKIP_SHA512 - ) + # Parse the github refs response with regex. + # TODO: add json-pointer support to vcpkg + file(READ "${archive_version}" version_contents) + if(NOT version_contents MATCHES [["hash": "([a-f0-9]+)"]]) + message(FATAL_ERROR "Failed to parse API response from '${version_url}': + +${version_contents} +") + endif() + set(VCPKG_HEAD_VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) endif() - # Parse the github refs response with regex. - # TODO: use some JSON swiss-army-knife utility instead. - file(READ "${ARCHIVE_VERSION}" _contents) - string(REGEX MATCH "\"hash\": \"[a-f0-9]+\"" x "${_contents}") - string(REGEX REPLACE "\"hash\": \"([a-f0-9]+)\"" "\\1" _version ${x}) - string(SUBSTRING ${_version} 0 12 _vdud_HEAD_REF) # Get the 12 first numbers from commit hash - - # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. - set(VCPKG_HEAD_VERSION ${_version} PARENT_SCOPE) - + # download the file information from bitbucket. + vcpkg_download_distfile(archive + URLS "https://bitbucket.com/${org_name}/${repo_name}/get/${ref_to_use}.tar.gz" + FILENAME "${downloaded_file_name}" + ${sha512_param} + ${redownload_param} + ) vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${downloaded_file_path}" - REF "${_vdud_HEAD_REF}" - WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/src/head" - PATCHES ${_vdud_PATCHES} + ARCHIVE "${archive}" + REF "${sanitized_ref}" + PATCHES ${arg_PATCHES} + ${working_directory_param} ) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) + set("${arg_OUT_SOURCE_PATH}" "${SOURCE_PATH}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_from_git.cmake b/scripts/cmake/vcpkg_from_git.cmake index d2055f82e07311..ac46e32cc194a2 100644 --- a/scripts/cmake/vcpkg_from_git.cmake +++ b/scripts/cmake/vcpkg_from_git.cmake @@ -9,7 +9,7 @@ vcpkg_from_git( OUT_SOURCE_PATH URL REF <59f7335e4d...> - [TAG ] + [HEAD_REF ] [PATCHES ...] ) ``` @@ -26,17 +26,16 @@ The url of the git repository. ### REF The git sha of the commit to download. -### TAG -An optional git tag to be verified against the `REF`. If the remote repository's tag does not match the specified `REF`, the build will fail. +### HEAD_REF +The git branch to use when the package is requested to be built from the latest sources. + +Example: `main`, `develop`, `HEAD` ### PATCHES A list of patches to be applied to the extracted sources. Relative paths are based on the port directory. -### X_OUT_REF (internal only) -This parameter is used for automatic REF updates for certain ports in the central vcpkg catalog. It should not be used by any ports outside the central catalog and within the central catalog it should not be used on any user path. This parameter may change behavior incompatibly or be removed at any time. - ## Notes: `OUT_SOURCE_PATH`, `REF`, and `URL` must be specified. @@ -48,94 +47,107 @@ This parameter is used for automatic REF updates for certain ports in the centra include(vcpkg_execute_in_download_mode) function(vcpkg_from_git) - set(oneValueArgs OUT_SOURCE_PATH URL REF TAG X_OUT_REF) - set(multipleValuesArgs PATCHES) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vdud "" "${oneValueArgs}" "${multipleValuesArgs}") - - if(NOT DEFINED _vdud_OUT_SOURCE_PATH) - message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") - endif() - - if(NOT DEFINED _vdud_URL) - message(FATAL_ERROR "The git url must be specified") - endif() - - if(NOT DEFINED _vdud_REF) - message(FATAL_ERROR "The git ref must be specified.") - endif() - - if(NOT DEFINED _vdud_TAG) - set(_vdud_TAG ${_vdud_REF}) - endif() - - # using .tar.gz instead of .zip because the hash of the latter is affected by timezone. - string(REPLACE "/" "-" SANITIZED_REF "${_vdud_TAG}") - set(TEMP_ARCHIVE "${DOWNLOADS}/temp/${PORT}-${SANITIZED_REF}.tar.gz") - set(ARCHIVE "${DOWNLOADS}/${PORT}-${SANITIZED_REF}.tar.gz") - set(TEMP_SOURCE_PATH "${CURRENT_BUILDTREES_DIR}/src/${SANITIZED_REF}") - - if(NOT EXISTS "${ARCHIVE}") - if(_VCPKG_NO_DOWNLOADS) - message(FATAL_ERROR "Downloads are disabled, but '${ARCHIVE}' does not exist.") - endif() - message(STATUS "Fetching ${_vdud_URL}...") - find_program(GIT NAMES git git.cmd) - # Note: git init is safe to run multiple times - vcpkg_execute_required_process( - ALLOW_IN_DOWNLOAD_MODE - COMMAND ${GIT} init git-tmp - WORKING_DIRECTORY ${DOWNLOADS} - LOGNAME git-init-${TARGET_TRIPLET} - ) - vcpkg_execute_required_process( - ALLOW_IN_DOWNLOAD_MODE - COMMAND ${GIT} fetch ${_vdud_URL} ${_vdud_TAG} --depth 1 -n - WORKING_DIRECTORY ${DOWNLOADS}/git-tmp - LOGNAME git-fetch-${TARGET_TRIPLET} + cmake_parse_arguments(PARSE_ARGV 0 "arg" + "" + "OUT_SOURCE_PATH;URL;REF;HEAD_REF;TAG" + "PATCHES" ) - vcpkg_execute_in_download_mode( - COMMAND ${GIT} rev-parse FETCH_HEAD - OUTPUT_VARIABLE REV_PARSE_HEAD - ERROR_VARIABLE REV_PARSE_HEAD - RESULT_VARIABLE error_code - WORKING_DIRECTORY ${DOWNLOADS}/git-tmp - ) - if(error_code) - message(FATAL_ERROR "unable to determine FETCH_HEAD after fetching git repository") + + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "vcpkg_from_git was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + if(DEFINED arg_TAG) + message(WARNING "The TAG argument to vcpkg_from_git has been deprecated and has no effect.") endif() - string(REGEX REPLACE "\n$" "" REV_PARSE_HEAD "${REV_PARSE_HEAD}") - if(NOT REV_PARSE_HEAD STREQUAL _vdud_REF AND NOT DEFINED _vdud_X_OUT_REF) - message(STATUS "[Expected : ( ${_vdud_REF} )]") - message(STATUS "[ Actual : ( ${REV_PARSE_HEAD} )]") - message(FATAL_ERROR "REF (${_vdud_REF}) does not match FETCH_HEAD (${REV_PARSE_HEAD})") - elseif(DEFINED _vdud_X_OUT_REF) - set(${_vdud_X_OUT_REF} ${REV_PARSE_HEAD} PARENT_SCOPE) - return() + + + if(NOT DEFINED arg_OUT_SOURCE_PATH) + message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + endif() + if(NOT DEFINED arg_URL) + message(FATAL_ERROR "The git url must be specified") + endif() + if(NOT DEFINED arg_REF AND NOT DEFINED arg_HEAD_REF) + message(FATAL_ERROR "At least one of REF or HEAD_REF must be specified.") + endif() + + set(working_directory_param "") + set(ref_to_use "${arg_REF}") + if(VCPKG_USE_HEAD_VERSION) + if(DEFINED arg_HEAD_REF) + set(working_directory_param "WORKING_DIRECTORY" "${CURRENT_BUILDTREES_DIR}/src/head") + set(ref_to_use "${arg_HEAD_REF}") + else() + message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") + endif() + elseif(NOT DEFINED arg_REF) + message(FATAL_ERROR "Package does not specify REF. It must be built using --head.") + endif() + + string(REPLACE "/" "_-" sanitized_ref "${ref_to_use}") + set(temp_archive "${DOWNLOADS}/temp/${PORT}-${sanitized_ref}.tar.gz") + set(archive "${DOWNLOADS}/${PORT}-${sanitized_ref}.tar.gz") + + if(NOT EXISTS "${archive}") + if(_VCPKG_NO_DOWNLOADS) + message(FATAL_ERROR "Downloads are disabled, but '${archive}' does not exist.") + endif() + message(STATUS "Fetching ${arg_URL} ${ref_to_use}...") + find_program(GIT NAMES git git.cmd) + file(MAKE_DIRECTORY "${DOWNLOADS}") + # Note: git init is safe to run multiple times + vcpkg_execute_required_process( + ALLOW_IN_DOWNLOAD_MODE + COMMAND "${GIT}" init git-tmp + WORKING_DIRECTORY "${DOWNLOADS}" + LOGNAME "git-init-${TARGET_TRIPLET}" + ) + vcpkg_execute_required_process( + ALLOW_IN_DOWNLOAD_MODE + COMMAND "${GIT}" fetch "${arg_URL}" "${ref_to_use}" --depth 1 -n + WORKING_DIRECTORY "${DOWNLOADS}/git-tmp" + LOGNAME "git-fetch-${TARGET_TRIPLET}" + ) + vcpkg_execute_in_download_mode( + COMMAND "${GIT}" rev-parse FETCH_HEAD + OUTPUT_VARIABLE rev_parse_head + ERROR_VARIABLE rev_parse_head + RESULT_VARIABLE error_code + WORKING_DIRECTORY "${DOWNLOADS}/git-tmp" + ) + if(error_code) + message(FATAL_ERROR "unable to determine FETCH_HEAD after fetching git repository") + endif() + string(STRIP "${rev_parse_head}" rev_parse_head) + if(VCPKG_USE_HEAD_VERSION) + set(VCPKG_HEAD_VERSION "${rev_parse_head}" PARENT_SCOPE) + elseif(NOT rev_parse_head STREQUAL arg_REF) + message(FATAL_ERROR "REF (${arg_REF}) does not match FETCH_HEAD (${rev_parse_head}) + [Expected : ( ${arg_REF} )]) + [ Actual : ( ${rev_parse_head} )]" + ) + endif() + + file(MAKE_DIRECTORY "${DOWNLOADS}/temp") + vcpkg_execute_required_process( + ALLOW_IN_DOWNLOAD_MODE + COMMAND "${GIT}" archive "${rev_parse_head}" -o "${temp_archive}" + WORKING_DIRECTORY "${DOWNLOADS}/git-tmp" + LOGNAME git-archive + ) + file(RENAME "${temp_archive}" "${archive}") + else() + message(STATUS "Using cached ${archive}") endif() - file(MAKE_DIRECTORY "${DOWNLOADS}/temp") - vcpkg_execute_required_process( - ALLOW_IN_DOWNLOAD_MODE - COMMAND ${GIT} archive FETCH_HEAD -o "${TEMP_ARCHIVE}" - WORKING_DIRECTORY ${DOWNLOADS}/git-tmp - LOGNAME git-archive + vcpkg_extract_source_archive_ex( + OUT_SOURCE_PATH SOURCE_PATH + ARCHIVE "${archive}" + REF "${sanitized_ref}" + PATCHES ${arg_PATCHES} + NO_REMOVE_ONE_LEVEL + ${working_directory_param} ) - get_filename_component(downloaded_file_dir "${ARCHIVE}" DIRECTORY) - file(MAKE_DIRECTORY "${downloaded_file_dir}") - file(RENAME "${TEMP_ARCHIVE}" "${ARCHIVE}") - else() - message(STATUS "Using cached ${ARCHIVE}") - endif() - - vcpkg_extract_source_archive_ex( - OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${ARCHIVE}" - REF "${SANITIZED_REF}" - PATCHES ${_vdud_PATCHES} - NO_REMOVE_ONE_LEVEL - ) - - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) + set("${arg_OUT_SOURCE_PATH}" "${SOURCE_PATH}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_from_github.cmake b/scripts/cmake/vcpkg_from_github.cmake index cda1fc395e6894..8a6a709243506e 100644 --- a/scripts/cmake/vcpkg_from_github.cmake +++ b/scripts/cmake/vcpkg_from_github.cmake @@ -73,159 +73,115 @@ This exports the `VCPKG_HEAD_VERSION` variable during head builds. #]===] function(vcpkg_from_github) - set(oneValueArgs OUT_SOURCE_PATH REPO REF SHA512 HEAD_REF GITHUB_HOST AUTHORIZATION_TOKEN FILE_DISAMBIGUATOR) - set(multipleValuesArgs PATCHES) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vdud "" "${oneValueArgs}" "${multipleValuesArgs}") + cmake_parse_arguments(PARSE_ARGV 0 "arg" + "" + "OUT_SOURCE_PATH;REPO;REF;SHA512;HEAD_REF;GITHUB_HOST;AUTHORIZATION_TOKEN;FILE_DISAMBIGUATOR" + "PATCHES") - if(NOT DEFINED _vdud_OUT_SOURCE_PATH) - message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "vcpkg_from_github was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") endif() - if((DEFINED _vdud_REF AND NOT DEFINED _vdud_SHA512) OR (NOT DEFINED _vdud_REF AND DEFINED _vdud_SHA512)) + if(DEFINED arg_REF AND NOT DEFINED arg_SHA512) message(FATAL_ERROR "SHA512 must be specified if REF is specified.") endif() - - if(NOT DEFINED _vdud_REPO) - message(FATAL_ERROR "The GitHub repository must be specified.") + if(NOT DEFINED arg_REF AND DEFINED arg_SHA512) + message(FATAL_ERROR "REF must be specified if SHA512 is specified.") endif() - if(NOT DEFINED _vdud_REF AND NOT DEFINED _vdud_HEAD_REF) - message(FATAL_ERROR "At least one of REF and HEAD_REF must be specified.") + if(NOT DEFINED arg_OUT_SOURCE_PATH) + message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") endif() - - if(NOT DEFINED _vdud_GITHUB_HOST) - set(GITHUB_HOST https://github.com) - set(GITHUB_API_URL https://api.github.com) - else() - set(GITHUB_HOST "${_vdud_GITHUB_HOST}") - set(GITHUB_API_URL "${_vdud_GITHUB_HOST}/api/v3") + if(NOT DEFINED arg_REPO) + message(FATAL_ERROR "The GitHub repository must be specified.") endif() - if(DEFINED _vdud_AUTHORIZATION_TOKEN) - set(HEADERS "HEADERS" "Authorization: token ${_vdud_AUTHORIZATION_TOKEN}") + if(NOT DEFINED arg_GITHUB_HOST) + set(github_host "https://github.com") + set(github_api_url "https://api.github.com") else() - set(HEADERS) + set(github_host "${arg_GITHUB_HOST}") + set(github_api_url "${arg_GITHUB_HOST}/api/v3") endif() - string(REGEX REPLACE ".*/" "" REPO_NAME "${_vdud_REPO}") - string(REGEX REPLACE "/.*" "" ORG_NAME "${_vdud_REPO}") - - macro(set_TEMP_SOURCE_PATH BASE BASEREF) - set(TEMP_SOURCE_PATH "${BASE}/${REPO_NAME}-${BASEREF}") - if(NOT EXISTS "${TEMP_SOURCE_PATH}") - # Sometimes GitHub strips a leading 'v' off the REF. - string(REGEX REPLACE "^v" "" REF "${BASEREF}") - string(REPLACE "/" "-" REF "${REF}") - set(TEMP_SOURCE_PATH "${BASE}/${REPO_NAME}-${REF}") - if(NOT EXISTS "${TEMP_SOURCE_PATH}") - message(FATAL_ERROR "Could not determine source path: '${BASE}/${REPO_NAME}-${BASEREF}' does not exist") - endif() - endif() - endmacro() - - if(VCPKG_USE_HEAD_VERSION AND NOT DEFINED _vdud_HEAD_REF) - message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") - set(VCPKG_USE_HEAD_VERSION OFF) + set(headers_param "") + if(DEFINED arg_AUTHORIZATION_TOKEN) + set(headers_param "HEADERS" "Authorization: token ${arg_AUTHORIZATION_TOKEN}") endif() - # Handle --no-head scenarios - if(NOT VCPKG_USE_HEAD_VERSION) - if(NOT _vdud_REF) - message(FATAL_ERROR "Package does not specify REF. It must built using --head.") - endif() - string(REPLACE "/" "-" SANITIZED_REF "${_vdud_REF}") + if(NOT DEFINED arg_REF AND NOT DEFINED arg_HEAD_REF) + message(FATAL_ERROR "At least one of REF or HEAD_REF must be specified.") + endif() - set(downloaded_file_name "${ORG_NAME}-${REPO_NAME}-${SANITIZED_REF}") - if (_vdud_FILE_DISAMBIGUATOR) - set(downloaded_file_name "${downloaded_file_name}-${_vdud_FILE_DISAMBIGUATOR}") + if(NOT arg_REPO MATCHES "^([^/]*)/([^/]*)$") + message(FATAL_ERROR "REPO (${arg_REPO}) is not a valid repo name: + must be an organization name followed by a repository name separated by a single slash.") + endif() + set(org_name "${CMAKE_MATCH_1}") + set(repo_name "${CMAKE_MATCH_2}") + + set(redownload_param "") + set(working_directory_param "") + set(sha512_param "SHA512" "${arg_SHA512}") + set(ref_to_use "${arg_REF}") + if(VCPKG_USE_HEAD_VERSION) + if(DEFINED arg_HEAD_REF) + set(redownload_param "ALWAYS_REDOWNLOAD") + set(sha512_param "SKIP_SHA512") + set(working_directory_param "WORKING_DIRECTORY" "${CURRENT_BUILDTREES_DIR}/src/head") + set(ref_to_use "${arg_HEAD_REF}") + else() + message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") endif() - - set(downloaded_file_name "${downloaded_file_name}.tar.gz") - - vcpkg_download_distfile(ARCHIVE - URLS "${GITHUB_HOST}/${ORG_NAME}/${REPO_NAME}/archive/${_vdud_REF}.tar.gz" - SHA512 "${_vdud_SHA512}" - FILENAME "${downloaded_file_name}" - ${HEADERS} - ) - - vcpkg_extract_source_archive_ex( - OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${ARCHIVE}" - REF "${SANITIZED_REF}" - PATCHES ${_vdud_PATCHES} - ) - - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - return() + elseif(NOT DEFINED arg_REF) + message(FATAL_ERROR "Package does not specify REF. It must be built using --head.") endif() - # The following is for --head scenarios - set(URL "${GITHUB_HOST}/${ORG_NAME}/${REPO_NAME}/archive/${_vdud_HEAD_REF}.tar.gz") - string(REPLACE "/" "-" SANITIZED_HEAD_REF "${_vdud_HEAD_REF}") - set(downloaded_file_name "${ORG_NAME}-${REPO_NAME}-${SANITIZED_HEAD_REF}") - if (_vdud_FILE_DISAMBIGUATOR) - set(downloaded_file_name "${downloaded_file_name}-${_vdud_FILE_DISAMBIGUATOR}") + # avoid using either - or _, to allow both `foo/bar` and `foo-bar` to coexist + # we assume that no one will name a ref "foo_-bar" + string(REPLACE "/" "_-" sanitized_ref "${ref_to_use}") + if(DEFINED arg_FILE_DISAMBIGUATOR AND NOT VCPKG_USE_HEAD_VERSION) + set(downloaded_file_name "${org_name}-${repo_name}-${sanitized_ref}-${arg_FILE_DISAMBIGUATOR}.tar.gz") + else() + set(downloaded_file_name "${org_name}-${repo_name}-${sanitized_ref}.tar.gz") endif() - set(downloaded_file_name "${downloaded_file_name}.tar.gz") - - set(downloaded_file_path "${DOWNLOADS}/${downloaded_file_name}") - if(_VCPKG_NO_DOWNLOADS) - if(NOT EXISTS "${downloaded_file_path}" OR NOT EXISTS "${downloaded_file_path}.version") - message(FATAL_ERROR "Downloads are disabled, but '${downloaded_file_path}' does not exist.") - endif() - message(STATUS "Using cached ${downloaded_file_path}") - else() - if(EXISTS "${downloaded_file_path}") - message(STATUS "Purging cached ${downloaded_file_path} to fetch latest (use --no-downloads to suppress)") - file(REMOVE "${downloaded_file_path}") - endif() - if(EXISTS "${downloaded_file_path}.version") - file(REMOVE "${downloaded_file_path}.version") - endif() - if(EXISTS "${CURRENT_BUILDTREES_DIR}/src/head") - file(REMOVE_RECURSE "${CURRENT_BUILDTREES_DIR}/src/head") - endif() - - # Try to download the file and version information from github. - vcpkg_download_distfile(ARCHIVE_VERSION - URLS "${GITHUB_API_URL}/repos/${ORG_NAME}/${REPO_NAME}/git/refs/heads/${_vdud_HEAD_REF}" + # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. + if(VCPKG_USE_HEAD_VERSION) + vcpkg_download_distfile(archive_version + URLS "${github_api_url}/repos/${org_name}/${repo_name}/git/refs/heads/${arg_HEAD_REF}" FILENAME "${downloaded_file_name}.version" SKIP_SHA512 - ${HEADERS} + ALWAYS_REDOWNLOAD ) - - vcpkg_download_distfile(ARCHIVE - URLS ${URL} - FILENAME "${downloaded_file_name}" - SKIP_SHA512 - ${HEADERS} - ) - endif() - - # Parse the github refs response with regex. - # TODO: use some JSON swiss-army-knife utility instead. - file(READ "${downloaded_file_path}.version" _contents) - string(REGEX MATCH "\"sha\": \"[a-f0-9]+\"" x "${_contents}") - string(REGEX REPLACE "\"sha\": \"([a-f0-9]+)\"" "\\1" _version ${x}) - - # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. - # When multiple vcpkg_from_github's are used after each other, only use the version from the first (hopefully the primary one). - if(NOT DEFINED VCPKG_HEAD_VERSION) - set(VCPKG_HEAD_VERSION "${_version}" PARENT_SCOPE) + # Parse the github refs response with regex. + # TODO: add json-pointer support to vcpkg + file(READ "${archive_version}" version_contents) + if(NOT version_contents MATCHES [["sha": "([a-f0-9]+)"]]) + message(FATAL_ERROR "Failed to parse API response from '${version_url}': + +${version_contents} +") + endif() + set(VCPKG_HEAD_VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) endif() + # Try to download the file information from github + vcpkg_download_distfile(archive + URLS "${github_host}/${org_name}/${repo_name}/archive/${ref_to_use}.tar.gz" + FILENAME "${downloaded_file_name}" + ${headers_param} + ${sha512_param} + ${redownload_param} + ) vcpkg_extract_source_archive_ex( - SKIP_PATCH_CHECK OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${downloaded_file_path}" - REF "${SANITIZED_HEAD_REF}" - WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}/src/head" - PATCHES ${_vdud_PATCHES} + ARCHIVE "${archive}" + REF "${sanitized_ref}" + PATCHES ${arg_PATCHES} + ${working_directory_param} ) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) + set("${arg_OUT_SOURCE_PATH}" "${SOURCE_PATH}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_from_gitlab.cmake b/scripts/cmake/vcpkg_from_gitlab.cmake index 865c5326ea3a14..75b09601f3ae8f 100644 --- a/scripts/cmake/vcpkg_from_gitlab.cmake +++ b/scripts/cmake/vcpkg_from_gitlab.cmake @@ -70,132 +70,120 @@ This exports the `VCPKG_HEAD_VERSION` variable during head builds. include(vcpkg_execute_in_download_mode) function(vcpkg_from_gitlab) - set(oneValueArgs OUT_SOURCE_PATH GITLAB_URL USER REPO REF SHA512 HEAD_REF FILE_DISAMBIGUATOR) - set(multipleValuesArgs PATCHES) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vdud "" "${oneValueArgs}" "${multipleValuesArgs}") + cmake_parse_arguments(PARSE_ARGV 0 "arg" + "" + "OUT_SOURCE_PATH;GITLAB_URL;REPO;REF;SHA512;HEAD_REF;FILE_DISAMBIGUATOR" + "PATCHES") - if(NOT DEFINED _vdud_GITLAB_URL) - message(FATAL_ERROR "GITLAB_URL must be specified.") + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "vcpkg_from_gitlab was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") endif() - if(NOT DEFINED _vdud_OUT_SOURCE_PATH) - message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + if(NOT DEFINED arg_GITLAB_URL) + message(FATAL_ERROR "GITLAB_URL must be specified.") endif() - if((DEFINED _vdud_REF AND NOT DEFINED _vdud_SHA512) OR (NOT DEFINED _vdud_REF AND DEFINED _vdud_SHA512)) + if(DEFINED arg_REF AND NOT DEFINED arg_SHA512) message(FATAL_ERROR "SHA512 must be specified if REF is specified.") endif() + if(NOT DEFINED arg_REF AND DEFINED arg_SHA512) + message(FATAL_ERROR "REF must be specified if SHA512 is specified.") + endif() - if(NOT DEFINED _vdud_REPO) - message(FATAL_ERROR "REPO must be specified.") + if(NOT DEFINED arg_OUT_SOURCE_PATH) + message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") + endif() + if(NOT DEFINED arg_REPO) + message(FATAL_ERROR "The GitHub repository must be specified.") endif() - if(NOT DEFINED _vdud_REF AND NOT DEFINED _vdud_HEAD_REF) - message(FATAL_ERROR "At least one of REF and HEAD_REF must be specified.") + set(headers_param "") + if(DEFINED arg_AUTHORIZATION_TOKEN) + set(headers_param "HEADERS" "Authorization: token ${arg_AUTHORIZATION_TOKEN}") endif() - if(VCPKG_USE_HEAD_VERSION AND NOT DEFINED _vdud_HEAD_REF) - message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") - set(VCPKG_USE_HEAD_VERSION OFF) + if(NOT DEFINED arg_REF AND NOT DEFINED arg_HEAD_REF) + message(FATAL_ERROR "At least one of REF or HEAD_REF must be specified.") endif() - string(REPLACE "/" ";" GITLAB_REPO_LINK ${_vdud_REPO}) - - list(LENGTH GITLAB_REPO_LINK len) - if(${len} EQUAL "2") - list(GET GITLAB_REPO_LINK 0 ORG_NAME) - list(GET GITLAB_REPO_LINK 1 REPO_NAME) - set(GITLAB_LINK ${_vdud_GITLAB_URL}/${ORG_NAME}/${REPO_NAME}) - endif() - - if(${len} EQUAL "3") - list(GET GITLAB_REPO_LINK 0 ORG_NAME) - list(GET GITLAB_REPO_LINK 1 GROUP_NAME) - list(GET GITLAB_REPO_LINK 2 REPO_NAME) - set(GITLAB_LINK ${_vdud_GITLAB_URL}/${ORG_NAME}/${GROUP_NAME}/${REPO_NAME}) - endif() - - # Handle --no-head scenarios - if(NOT VCPKG_USE_HEAD_VERSION) - if(NOT _vdud_REF) - message(FATAL_ERROR "Package does not specify REF. It must built using --head.") - endif() + if(arg_REPO MATCHES [[^([^/]*)/([^/]*)$]]) # 2 elements + set(org_name "${CMAKE_MATCH_1}") + set(repo_name "${CMAKE_MATCH_2}") + set(gitlab_link "${arg_GITLAB_URL}/${org_name}/${repo_name}") + elseif(arg_REPO MATCHES [[^([^/]*)/([^/]*)/([^/]*)$]]) # 3 elements + set(org_name "${CMAKE_MATCH_1}") + set(group_name "${CMAKE_MATCH_2}") + set(repo_name "${CMAKE_MATCH_3}") + set(gitlab_link "${arg_GITLAB_URL}/${org_name}/${group_name}/${repo_name}") + else() + message(FATAL_ERROR "REPO (${arg_REPO}) is not a valid repo name. It must be: + - an organization name followed by a repository name separated by a single slash, or + - an organization name, group name, and repository name separated by slashes.") + endif() - string(REPLACE "/" "-" SANITIZED_REF "${_vdud_REF}") - set(downloaded_file_name "${ORG_NAME}-${REPO_NAME}-${SANITIZED_REF}") - if (_vdud_FILE_DISAMBIGUATOR) - set(downloaded_file_name "${downloaded_file_name}-${_vdud_FILE_DISAMBIGUATOR}") + set(redownload_param "") + set(working_directory_param "") + set(sha512_param "SHA512" "${arg_SHA512}") + set(ref_to_use "${arg_REF}") + if(VCPKG_USE_HEAD_VERSION) + if(DEFINED arg_HEAD_REF) + set(redownload_param "ALWAYS_REDOWNLOAD") + set(sha512_param "SKIP_SHA512") + set(working_directory_param "WORKING_DIRECTORY" "${CURRENT_BUILDTREES_DIR}/src/head") + set(ref_to_use "${arg_HEAD_REF}") + else() + message(STATUS "Package does not specify HEAD_REF. Falling back to non-HEAD version.") endif() + elseif(NOT DEFINED arg_REF) + message(FATAL_ERROR "Package does not specify REF. It must be built using --head.") + endif() - set(downloaded_file_name "${downloaded_file_name}.tar.gz") - - vcpkg_download_distfile(ARCHIVE - URLS "${GITLAB_LINK}/-/archive/${_vdud_REF}/${REPO_NAME}-${_vdud_REF}.tar.gz" - SHA512 "${_vdud_SHA512}" - FILENAME "${downloaded_file_name}" - ) - - vcpkg_extract_source_archive_ex( - OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${ARCHIVE}" - REF "${SANITIZED_REF}" - PATCHES ${_vdud_PATCHES} - ) - - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) - return() + # avoid using either - or _, to allow both `foo/bar` and `foo-bar` to coexist + # we assume that no one will name a ref "foo_-bar" + string(REPLACE "/" "_-" sanitized_ref "${ref_to_use}") + if(DEFINED arg_FILE_DISAMBIGUATOR AND NOT VCPKG_USE_HEAD_VERSION) + set(downloaded_file_name "${org_name}-${repo_name}-${sanitized_ref}-${arg_FILE_DISAMBIGUATOR}.tar.gz") + else() + set(downloaded_file_name "${org_name}-${repo_name}-${sanitized_ref}.tar.gz") endif() - # The following is for --head scenarios - set(URL "${GITLAB_LINK}/-/archive/${_vdud_HEAD_REF}/${_vdud_HEAD_REF}.tar.gz") - string(REPLACE "/" "-" SANITIZED_HEAD_REF "${_vdud_HEAD_REF}") - set(downloaded_file_name "${ORG_NAME}-${REPO_NAME}-${SANITIZED_HEAD_REF}.tar.gz") - set(downloaded_file_path "${DOWNLOADS}/${downloaded_file_name}") - if(_VCPKG_NO_DOWNLOADS) - if(NOT EXISTS ${downloaded_file_path} OR NOT EXISTS ${downloaded_file_path}.version) - message(FATAL_ERROR "Downloads are disabled, but '${downloaded_file_path}' does not exist.") - endif() - message(STATUS "Using cached ${downloaded_file_path}") - else() - if(EXISTS ${downloaded_file_path}) - message(STATUS "Purging cached ${downloaded_file_path} to fetch latest (use --no-downloads to suppress)") - file(REMOVE ${downloaded_file_path}) + # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. + if(VCPKG_USE_HEAD_VERSION) + # There are issues with the Gitlab API project paths being URL-escaped, so we use git here to get the head revision + vcpkg_execute_in_download_mode(COMMAND ${GIT} ls-remote + "${gitlab_link}.git" "${arg_HEAD_REF}" + RESULT_VARIABLE git_result + OUTPUT_VARIABLE git_output + ) + if(NOT git_result EQUAL 0) + message(FATAL_ERROR "git ls-remote failed to read ref data of repository: '${gitlab_link}'") endif() - if(EXISTS ${downloaded_file_path}.version) - file(REMOVE ${downloaded_file_path}.version) + if(NOT git_output MATCHES "^([a-f0-9]*)\t") + message(FATAL_ERROR "git ls-remote returned unexpected result: +${git_output} +") endif() - if(EXISTS ${CURRENT_BUILDTREES_DIR}/src/head) - file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/src/head) + # When multiple vcpkg_from_gitlab's are used after each other, only use the version from the first (hopefully the primary one). + if(NOT DEFINED VCPKG_HEAD_VERSION) + set(VCPKG_HEAD_VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) endif() - - vcpkg_download_distfile(ARCHIVE - URLS ${URL} - FILENAME ${downloaded_file_name} - SKIP_SHA512 - ) endif() - # There are issues with the Gitlab API project paths being URL-escaped, so we use git here to get the head revision - vcpkg_execute_in_download_mode(COMMAND ${GIT} ls-remote - "${GITLAB_LINK}.git" "${_vdud_HEAD_REF}" - RESULT_VARIABLE _git_result - OUTPUT_VARIABLE _git_output + # download the file information from gitlab + vcpkg_download_distfile(archive + URLS "${gitlab_link}/-/archive/${ref_to_use}/${repo_name}-${ref_to_use}.tar.gz" + FILENAME "${downloaded_file_name}" + ${headers_param} + ${sha512_param} + ${redownload_param} ) - string(REGEX MATCH "[a-f0-9]+" _version "${_git_output}") - # exports VCPKG_HEAD_VERSION to the caller. This will get picked up by ports.cmake after the build. - # When multiple vcpkg_from_gitlab's are used after each other, only use the version from the first (hopefully the primary one). - if(NOT DEFINED VCPKG_HEAD_VERSION) - set(VCPKG_HEAD_VERSION ${_version} PARENT_SCOPE) - endif() - vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH - ARCHIVE "${downloaded_file_path}" - REF "${SANITIZED_HEAD_REF}" - WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/src/head - PATCHES ${_vdud_PATCHES} + ARCHIVE "${archive}" + REF "${sanitized_ref}" + PATCHES ${arg_PATCHES} + ${working_directory_param} ) - set(${_vdud_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) + set("${arg_OUT_SOURCE_PATH}" "${SOURCE_PATH}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_from_sourceforge.cmake b/scripts/cmake/vcpkg_from_sourceforge.cmake index de0e6c509ed9b0..a65cd725205693 100644 --- a/scripts/cmake/vcpkg_from_sourceforge.cmake +++ b/scripts/cmake/vcpkg_from_sourceforge.cmake @@ -3,6 +3,10 @@ Download and extract a project from sourceforge. +This function automatically checks a set of sourceforge mirrors. +Additional mirrors can be injected through the `VCPKG_SOURCEFORGE_EXTRA_MIRRORS` +list variable in the triplet. + ## Usage: ```cmake vcpkg_from_sourceforge( @@ -53,9 +57,6 @@ A list of patches to be applied to the extracted sources. Relative paths are based on the port directory. -### DISABLE_SSL -Disable ssl when downloading source. - ### NO_REMOVE_ONE_LEVEL Specifies that the default removal of the top level folder should not occur. @@ -67,67 +68,51 @@ Specifies that the default removal of the top level folder should not occur. #]===] function(vcpkg_from_sourceforge) - set(booleanValueArgs DISABLE_SSL NO_REMOVE_ONE_LEVEL) - set(oneValueArgs OUT_SOURCE_PATH REPO REF SHA512 FILENAME WORKING_DIRECTORY) - set(multipleValuesArgs PATCHES) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vdus "${booleanValueArgs}" "${oneValueArgs}" "${multipleValuesArgs}") + cmake_parse_arguments(PARSE_ARGV 0 "arg" + "DISABLE_SSL;NO_REMOVE_ONE_LEVEL" + "OUT_SOURCE_PATH;REPO;REF;SHA512;FILENAME;WORKING_DIRECTORY" + "PATCHES") - if(NOT DEFINED _vdus_OUT_SOURCE_PATH) + if(NOT DEFINED arg_OUT_SOURCE_PATH) message(FATAL_ERROR "OUT_SOURCE_PATH must be specified.") endif() - - if(NOT DEFINED _vdus_SHA512) + if(NOT DEFINED arg_SHA512) message(FATAL_ERROR "SHA512 must be specified.") endif() - - if(NOT DEFINED _vdus_REPO) + if(NOT DEFINED arg_REPO) message(FATAL_ERROR "The sourceforge repository must be specified.") endif() - if(DEFINED _vdus_WORKING_DIRECTORY) - set(WORKING_DIRECTORY WORKING_DIRECTORY "${_vdus_WORKING_DIRECTORY}") - else() - set(WORKING_DIRECTORY) - endif() - if (_vdus_DISABLE_SSL) - set(URL_PROTOCOL http:) - else() - set(URL_PROTOCOL https:) + if(arg_DISABLE_SSL) + message(WARNING "DISABLE_SSL has been deprecated and has no effect") endif() - set(SOURCEFORGE_HOST ${URL_PROTOCOL}//sourceforge.net/projects) - - string(FIND ${_vdus_REPO} "/" FOUND_ORG) - if (NOT FOUND_ORG EQUAL -1) - string(SUBSTRING "${_vdus_REPO}" 0 ${FOUND_ORG} ORG_NAME) - math(EXPR FOUND_ORG "${FOUND_ORG} + 1") # skip the slash - string(SUBSTRING "${_vdus_REPO}" ${FOUND_ORG} -1 REPO_NAME) - if (REPO_NAME MATCHES "/") - message(FATAL_ERROR "REPO should contain at most one slash (found ${_vdus_REPO}).") - endif() - set(ORG_NAME ${ORG_NAME}/) + set(sourceforge_host "https://sourceforge.net/projects") + + if(arg_REPO MATCHES "^([^/]*)$") # just one element + set(org_name "${CMAKE_MATCH_1}") + set(repo_name "") + elseif(arg_REPO MATCHES "^([^/]*)/([^/]*)$") # two elements + set(org_name "${CMAKE_MATCH_1}") + set(repo_name "${CMAKE_MATCH_2}") else() - set(ORG_NAME ${_vdus_REPO}/) - set(REPO_NAME ) + message(FATAL_ERROR "REPO (${arg_REPO}) is not a valid repo name. It must be: + - an organization name without any slashes, or + - an organization name followed by a repository name separated by a single slash") endif() - if (DEFINED _vdus_REF) - set(URL "${SOURCEFORGE_HOST}/${ORG_NAME}files/${REPO_NAME}/${_vdus_REF}/${_vdus_FILENAME}") + if(DEFINED arg_REF) + set(url "${sourceforge_host}/${org_name}/files/${repo_name}/${arg_REF}/${arg_FILENAME}") + elseif(DEFINED repo_name) + set(url "${sourceforge_host}/${org_name}/${repo_name}/files/${arg_FILENAME}") else() - set(URL "${SOURCEFORGE_HOST}/${ORG_NAME}${REPO_NAME}/files/${_vdus_FILENAME}") + set(url "${sourceforge_host}/${org_name}/files/${arg_FILENAME}") endif() - set(NO_REMOVE_ONE_LEVEL ) - if (_vdus_NO_REMOVE_ONE_LEVEL) - set(NO_REMOVE_ONE_LEVEL "NO_REMOVE_ONE_LEVEL") - endif() - - string(SUBSTRING "${_vdus_SHA512}" 0 10 SANITIZED_REF) + string(SUBSTRING "${arg_SHA512}" 0 10 sanitized_ref) - set(Z_VCPKG_SOURCEFORGE_MIRRORS ${SOURCEFORGE_MIRRORS}) - list(APPEND Z_VCPKG_SOURCEFORGE_MIRRORS + set(sourceforge_mirrors cfhcable # United States pilotfiber # New York, NY gigenet # Chicago, IL @@ -149,26 +134,43 @@ function(vcpkg_from_sourceforge) ufpr # Curitiba, Brazil tenet # Wynberg, South Africa ) + if(DEFINED SOURCEFORGE_MIRRORS AND NOT DEFINED VCPKG_SOURCEFORGE_EXTRA_MIRRORS) + message(WARNING "Extension point SOURCEFORGE_MIRRORS has been deprecated. + Please use the replacement VCPKG_SOURCEFORGE_EXTRA_MIRRORS variable instead.") + list(APPEND sourceforge_mirrors "${SOURCEFORGE_MIRRORS}") + list(REMOVE_DUPLICATES sourceforge_mirrors) + elseif(DEFINED VCPKG_SOURCEFORGE_EXTRA_MIRRORS) + list(APPEND sourceforge_mirrors "${VCPKG_SOURCEFORGE_EXTRA_MIRRORS}") + list(REMOVE_DUPLICATES sourceforge_mirrors) + endif() - set(URLS "${URL}/download") - foreach(SOURCEFORGE_MIRROR IN LISTS Z_VCPKG_SOURCEFORGE_MIRRORS) - list(APPEND URLS "${URL}/download?use_mirror=${SOURCEFORGE_MIRROR}") + set(all_urls "${url}/download") + foreach(mirror IN LISTS sourceforge_mirrors) + list(APPEND all_urls "${url}/download?use_mirror=${mirror}") endforeach() - + vcpkg_download_distfile(ARCHIVE - URLS ${URLS} - SHA512 "${_vdus_SHA512}" - FILENAME "${_vdus_FILENAME}" + URLS ${all_urls} + SHA512 "${arg_SHA512}" + FILENAME "${arg_FILENAME}" ) + set(no_remove_one_level_param "") + set(working_directory_param "") + if(arg_NO_REMOVE_ONE_LEVEL) + set(no_remove_one_level_param "NO_REMOVE_ONE_LEVEL") + endif() + if(DEFINED arg_WORKING_DIRECTORY) + set(working_directory_param "WORKING_DIRECTORY" "${arg_WORKING_DIRECTORY}") + endif() vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH ARCHIVE "${ARCHIVE}" - REF "${SANITIZED_REF}" - ${NO_REMOVE_ONE_LEVEL} - ${WORKING_DIRECTORY} - PATCHES ${_vdus_PATCHES} + REF "${sanitized_ref}" + ${no_remove_one_level_param} + ${working_directory_param} + PATCHES ${arg_PATCHES} ) - set(${_vdus_OUT_SOURCE_PATH} "${SOURCE_PATH}" PARENT_SCOPE) + set("${arg_OUT_SOURCE_PATH}" "${SOURCE_PATH}" PARENT_SCOPE) endfunction() diff --git a/scripts/cmake/vcpkg_install_msbuild.cmake b/scripts/cmake/vcpkg_install_msbuild.cmake index 811cedf8f76878..a6b9ec9c2973fd 100644 --- a/scripts/cmake/vcpkg_install_msbuild.cmake +++ b/scripts/cmake/vcpkg_install_msbuild.cmake @@ -87,8 +87,8 @@ Additional options passed to msbuild for Debug builds. These are in addition to ## Examples -* [xalan-c](https://github.com/Microsoft/vcpkg/blob/master/ports/xalan-c/portfile.cmake) -* [libimobiledevice](https://github.com/Microsoft/vcpkg/blob/master/ports/libimobiledevice/portfile.cmake) +* [libirecovery](https://github.com/Microsoft/vcpkg/blob/master/ports/libirecovery/portfile.cmake) +* [libfabric](https://github.com/Microsoft/vcpkg/blob/master/ports/libfabric/portfile.cmake) #]===] function(vcpkg_install_msbuild) diff --git a/scripts/cmake/z_vcpkg_forward_output_variable.cmake b/scripts/cmake/z_vcpkg_forward_output_variable.cmake new file mode 100644 index 00000000000000..4d775b8cc478f5 --- /dev/null +++ b/scripts/cmake/z_vcpkg_forward_output_variable.cmake @@ -0,0 +1,48 @@ +#[===[.md: +# z_vcpkg_forward_output_variable + +This macro helps with forwarding values from inner function calls, +through a local function scope, into pointer out parameters. + +```cmake +z_vcpkg_forward_output_variable(ptr_to_parent_var var_to_forward) +``` + +is equivalent to + +```cmake +if(DEFINED ptr_to_parent_var) + if(DEFINED value_var) + set("${ptr_to_parent_var}" "${value_var}" PARENT_SCOPE) + else() + unset("${ptr_to_parent_var}" PARENT_SCOPE) + endif() +endif() +``` + +Take note that the first argument should be a local variable that has a value of the parent variable name. +Most commonly, this local is the result of a pointer-out parameter to a function. +If the variable in the first parameter is not defined, this function does nothing, +simplifying functions with optional out parameters. +Most commonly, this should be used in cases like: + +```cmake +function(my_function out_var) + file(SHA512 "somefile.txt" local_var) + z_vcpkg_forward_output_variable(out_var local_var) +endfunction() +``` +#]===] + +macro(z_vcpkg_forward_output_variable ptr_to_parent_var var_to_forward) + if("${ARGC}" GREATER "2") + message(FATAL_ERROR "z_vcpkg_forward_output_variable was passed extra arguments: ${ARGN}") + endif() + if(DEFINED "${ptr_to_parent_var}") + if(DEFINED "${var_to_forward}") + set("${${ptr_to_parent_var}}" "${${var_to_forward}}" PARENT_SCOPE) + else() + unset("${${ptr_to_parent_var}}" PARENT_SCOPE) + endif() + endif() +endmacro() diff --git a/scripts/detect_compiler/CMakeLists.txt b/scripts/detect_compiler/CMakeLists.txt index 5ae17c5b27f385..c55da9ebb2bdeb 100644 --- a/scripts/detect_compiler/CMakeLists.txt +++ b/scripts/detect_compiler/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.20) project(detect_compiler NONE) if(CMAKE_GENERATOR STREQUAL "Ninja" AND CMAKE_SYSTEM_NAME STREQUAL "Windows") diff --git a/scripts/get_cmake_vars/CMakeLists.txt b/scripts/get_cmake_vars/CMakeLists.txt index 2b0bd671a51832..084042fb116ab2 100644 --- a/scripts/get_cmake_vars/CMakeLists.txt +++ b/scripts/get_cmake_vars/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.17) +cmake_minimum_required(VERSION 3.20) set(VCPKG_LANGUAGES "C;CXX" CACHE STRING "Languages to enables for this project") diff --git a/scripts/ports.cmake b/scripts/ports.cmake index d91c81b0b284e7..ce6fc557b775a1 100644 --- a/scripts/ports.cmake +++ b/scripts/ports.cmake @@ -1,5 +1,5 @@ # rebuild: 1 -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.20) set(SCRIPTS "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "Location to stored scripts") include("${SCRIPTS}/cmake/z_vcpkg_function_arguments.cmake") @@ -26,7 +26,7 @@ endif() list(APPEND CMAKE_MODULE_PATH "${SCRIPTS}/cmake") include("${SCRIPTS}/cmake/vcpkg_minimum_required.cmake") -vcpkg_minimum_required(VERSION 2021-01-13) +vcpkg_minimum_required(VERSION 2021-05-05) file(TO_CMAKE_PATH "${BUILDTREES_DIR}" BUILDTREES_DIR) file(TO_CMAKE_PATH "${PACKAGES_DIR}" PACKAGES_DIR) @@ -134,6 +134,7 @@ if(CMD MATCHES "^BUILD$") include("${SCRIPTS}/cmake/vcpkg_test_cmake.cmake") include("${SCRIPTS}/cmake/z_vcpkg_apply_patches.cmake") + include("${SCRIPTS}/cmake/z_vcpkg_forward_output_variable.cmake") include("${SCRIPTS}/cmake/z_vcpkg_prettify_command_line.cmake") include("${CURRENT_PORT_DIR}/portfile.cmake") diff --git a/scripts/vcpkgTools.xml b/scripts/vcpkgTools.xml index 4df3264db02534..785d1b8b4e3c60 100644 --- a/scripts/vcpkgTools.xml +++ b/scripts/vcpkgTools.xml @@ -28,13 +28,6 @@ 1e81c37d3b144cfb81478140e7921f314134845d2f0e0f941109ef57d510e7bd37dda6cc292ec00782472e7f1671349b857be9aac1c3f974423c8d1875a46302 cmake-3.20.2-linux-x86_64.tar.gz - - 3.12.4 - cmake-3.12.4-FreeBSD-x86_64/bin/cmake - https://github.com/ivysnow/CMake/releases/download/v3.12.4/cmake-3.12.4-FreeBSD-x86_64.tar.gz - b5aeb2de36f3c29757c9404e33756da88580ddfa07f29079c7f275ae0d6d018fdfe3f55d54d1403f38e359865cf93436e084c6b1ea91f26c88bc01dde3793479 - cmake-3.12.4-FreeBSD-x86_64.tar.gz - 2.26.2-1 mingw32\bin\git.exe diff --git a/versions/a-/avisynthplus.json b/versions/a-/avisynthplus.json index 73c4843932863b..c8cd5d877581bf 100644 --- a/versions/a-/avisynthplus.json +++ b/versions/a-/avisynthplus.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "747e0dd9f81ace8b2f473dc455871938d930df28", + "version-semver": "3.7.0", + "port-version": 1 + }, { "git-tree": "3d573152a7d82faefcb525b1d6cf688a1465a71b", "version-semver": "3.7.0", diff --git a/versions/b-/bond.json b/versions/b-/bond.json index d4c2879d564df5..88acf8925e8ae7 100644 --- a/versions/b-/bond.json +++ b/versions/b-/bond.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "29fa989c86f7846056f2afc162152f79169ec813", + "version-string": "9.0.3", + "port-version": 1 + }, { "git-tree": "bde4f6ac4c95a05f823e8de810f57df015738ac4", "version-string": "9.0.3", diff --git a/versions/baseline.json b/versions/baseline.json index 1d13df61403923..29454476b8b506 100644 --- a/versions/baseline.json +++ b/versions/baseline.json @@ -226,7 +226,7 @@ }, "avisynthplus": { "baseline": "3.7.0", - "port-version": 0 + "port-version": 1 }, "avro-c": { "baseline": "1.9.2-1", @@ -434,7 +434,7 @@ }, "bond": { "baseline": "9.0.3", - "port-version": 0 + "port-version": 1 }, "boolinq": { "baseline": "3.0.1", @@ -4349,8 +4349,8 @@ "port-version": 0 }, "nmap": { - "baseline": "7.70-4", - "port-version": 0 + "baseline": "7.70", + "port-version": 5 }, "nmslib": { "baseline": "2.0.6", @@ -4554,7 +4554,7 @@ }, "opencv3": { "baseline": "3.4.14", - "port-version": 0 + "port-version": 1 }, "opencv4": { "baseline": "4.5.2", @@ -5065,8 +5065,8 @@ "port-version": 2 }, "qcustomplot": { - "baseline": "2.0.1-4", - "port-version": 0 + "baseline": "2.0.1", + "port-version": 5 }, "qhull": { "baseline": "8.0.2", @@ -5162,7 +5162,7 @@ }, "qt5-mqtt": { "baseline": "5.15.2", - "port-version": 0 + "port-version": 1 }, "qt5-multimedia": { "baseline": "5.15.2", @@ -6530,7 +6530,7 @@ }, "vcpkg-cmake-config": { "baseline": "2021-05-22", - "port-version": 0 + "port-version": 1 }, "vcpkg-gfortran": { "baseline": "3", diff --git a/versions/n-/nmap.json b/versions/n-/nmap.json index 64104cebb57b76..16b6862f6cbbab 100644 --- a/versions/n-/nmap.json +++ b/versions/n-/nmap.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "b435c01d439c57ba46d2de58b81fd1da81555776", + "version": "7.70", + "port-version": 5 + }, { "git-tree": "83ebdc9303a1f8917df4275921160636cdb05eef", "version-string": "7.70-4", diff --git a/versions/o-/opencv3.json b/versions/o-/opencv3.json index 3237895a29d590..2294e2eb7d528f 100644 --- a/versions/o-/opencv3.json +++ b/versions/o-/opencv3.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "850be938a178de206c52be71229048d501bd61e8", + "version": "3.4.14", + "port-version": 1 + }, { "git-tree": "766b570f861ad21af950db7c02e5dc48d4fd1a1e", "version": "3.4.14", diff --git a/versions/q-/qcustomplot.json b/versions/q-/qcustomplot.json index ccae06e9571136..f22ce4aebaf6cb 100644 --- a/versions/q-/qcustomplot.json +++ b/versions/q-/qcustomplot.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "7fcc18d2987ed5b3af803d5e0ac5c9afd026fc37", + "version": "2.0.1", + "port-version": 5 + }, { "git-tree": "c995c8e160e05060606844f9a0ea84b1fd5d61d3", "version-string": "2.0.1-4", diff --git a/versions/q-/qt5-mqtt.json b/versions/q-/qt5-mqtt.json index c4a29965ffbd1e..36e684e44ada85 100644 --- a/versions/q-/qt5-mqtt.json +++ b/versions/q-/qt5-mqtt.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "9a02099176012e710ae215855f4e72fe6f5b704a", + "version": "5.15.2", + "port-version": 1 + }, { "git-tree": "af160578b6f6fe501b01817d6d171d123a4841d1", "version-string": "5.15.2", diff --git a/versions/v-/vcpkg-cmake-config.json b/versions/v-/vcpkg-cmake-config.json index 0b1778c5c43605..1a528ef23c9aeb 100644 --- a/versions/v-/vcpkg-cmake-config.json +++ b/versions/v-/vcpkg-cmake-config.json @@ -1,5 +1,10 @@ { "versions": [ + { + "git-tree": "330cc51bc99c6b71ed5fb51901f6f838684015a5", + "version-date": "2021-05-22", + "port-version": 1 + }, { "git-tree": "2d4f997a32b8e8bfe98d12beb2bfe6be713c7086", "version-date": "2021-05-22",