From 0e1dc121856eef84bf1852134e548bf9898dabac Mon Sep 17 00:00:00 2001 From: nicole mazzuca <83086508+strega-nil-ms@users.noreply.github.com> Date: Tue, 20 Jul 2021 12:24:58 -0500 Subject: [rollup] Rollup PR 2021-07-16 (#19001) * [rollup:2021-07-16 1/7] PR #18201 (@JackBoosY) [vcpkg-cmake] Add check for unused cmake variables * [rollup:2021-07-16 2/7] PR #18397 (@strega-nil) [vcpkg_list] add new function * [rollup:2021-07-16 3/7] PR #18782 (@strega-nil) [scripts-audit] vcpkg_build_ninja * [rollup:2021-07-16 4/7] PR #18784 (@strega-nil) [scripts-audit] vcpkg_minimum_required * [rollup:2021-07-16 5/7] PR #18785 (@strega-nil) [scripts-audit] vcpkg_replace_string * [rollup:2021-07-16 6/7] PR #18786 (@strega-nil) [scripts-audit] windows scripts * [rollup:2021-07-16 7/7] PR #18945 (@strega-nil) [many ports] remove deprecated vcpkg_check_features call [1/5] Co-authored-by: nicole mazzuca Co-authored-by: PhoebeHui <20694052+PhoebeHui@users.noreply.github.com> --- scripts/buildsystems/vcpkg.cmake | 7 +- scripts/cmake/vcpkg_build_ninja.cmake | 33 +- scripts/cmake/vcpkg_configure_cmake.cmake | 64 +- .../vcpkg_get_program_files_platform_bitness.cmake | 13 +- scripts/cmake/vcpkg_get_windows_sdk.cmake | 10 +- scripts/cmake/vcpkg_internal_get_cmake_vars.cmake | 1 + scripts/cmake/vcpkg_list.cmake | 257 +++++++ scripts/cmake/vcpkg_minimum_required.cmake | 20 +- scripts/cmake/vcpkg_replace_string.cmake | 11 +- scripts/cmake/z_vcpkg_function_arguments.cmake | 16 +- scripts/ports.cmake | 1 + scripts/test_ports/unit-test-cmake/portfile.cmake | 73 ++ .../unit-test-cmake/test-vcpkg_list.cmake | 813 +++++++++++++++++++++ .../test-z_vcpkg_function_arguments.cmake | 63 ++ scripts/test_ports/unit-test-cmake/vcpkg.json | 18 + 15 files changed, 1352 insertions(+), 48 deletions(-) create mode 100644 scripts/cmake/vcpkg_list.cmake create mode 100644 scripts/test_ports/unit-test-cmake/portfile.cmake create mode 100644 scripts/test_ports/unit-test-cmake/test-vcpkg_list.cmake create mode 100644 scripts/test_ports/unit-test-cmake/test-z_vcpkg_function_arguments.cmake create mode 100644 scripts/test_ports/unit-test-cmake/vcpkg.json (limited to 'scripts') diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake index 8ab287852..ff0873457 100644 --- a/scripts/buildsystems/vcpkg.cmake +++ b/scripts/buildsystems/vcpkg.cmake @@ -153,7 +153,7 @@ macro(z_vcpkg_function_arguments OUT_VAR) message(FATAL_ERROR "z_vcpkg_function_arguments: invalid arguments (${ARGV})") endif() - set("${OUT_VAR}") + set("${OUT_VAR}" "") # this allows us to get the value of the enclosing function's ARGC set(z_vcpkg_function_arguments_ARGC_NAME "ARGC") @@ -164,8 +164,11 @@ macro(z_vcpkg_function_arguments OUT_VAR) if(NOT z_vcpkg_function_arguments_LAST_ARG LESS z_vcpkg_function_arguments_FIRST_ARG) foreach(z_vcpkg_function_arguments_N RANGE "${z_vcpkg_function_arguments_FIRST_ARG}" "${z_vcpkg_function_arguments_LAST_ARG}") string(REPLACE ";" "\\;" z_vcpkg_function_arguments_ESCAPED_ARG "${ARGV${z_vcpkg_function_arguments_N}}") - list(APPEND "${OUT_VAR}" "${z_vcpkg_function_arguments_ESCAPED_ARG}") + # adds an extra `;` on the first time through + set("${OUT_VAR}" "${${OUT_VAR}};${z_vcpkg_function_arguments_ESCAPED_ARG}") endforeach() + # remove leading `;` + string(SUBSTRING "${${OUT_VAR}}" 1 -1 "${OUT_VAR}") endif() endmacro() diff --git a/scripts/cmake/vcpkg_build_ninja.cmake b/scripts/cmake/vcpkg_build_ninja.cmake index 2c9276e63..5a0a1755f 100644 --- a/scripts/cmake/vcpkg_build_ninja.cmake +++ b/scripts/cmake/vcpkg_build_ninja.cmake @@ -15,26 +15,33 @@ vcpkg_build_ninja( Only build the specified targets. #]===] +function(z_vcpkg_build_ninja_build config targets) + message(STATUS "Building (${config})...") + vcpkg_execute_build_process( + COMMAND "${NINJA}" -C "${CURRENT_BUILDTREES_DIR}/${config}" ${targets} + WORKING_DIRECTORY "${SOURCE_PATH}" + LOGNAME "build-${config}" + ) +endfunction() + + function(vcpkg_build_ninja) - # parse parameters such that semicolons in options arguments to COMMAND don't get erased - cmake_parse_arguments(PARSE_ARGV 0 _vbn "" "" "TARGETS") + cmake_parse_arguments(PARSE_ARGV 0 arg "" "" "TARGETS") - vcpkg_find_acquire_program(NINJA) + if(DEFINED arg_UNPARSED_ARGUMENTS) + message(WARNING "${CMAKE_CURRENT_FUNCTION} was passed extra arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + if(NOT DEFINED arg_TARGETS) + set(arg_TARGETS "") + endif() - function(build CONFIG) - message(STATUS "Building (${CONFIG})...") - vcpkg_execute_build_process( - COMMAND "${NINJA}" -C "${CURRENT_BUILDTREES_DIR}/${CONFIG}" ${_vbn_TARGETS} - WORKING_DIRECTORY "${SOURCE_PATH}" - LOGNAME build-${CONFIG} - ) - endfunction() + vcpkg_find_acquire_program(NINJA) if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug") - build(${TARGET_TRIPLET}-dbg) + z_vcpkg_build_ninja_build("${TARGET_TRIPLET}-dbg" "${arg_TARGETS}") endif() if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release") - build(${TARGET_TRIPLET}-rel) + z_vcpkg_build_ninja_build("${TARGET_TRIPLET}-rel" "${arg_TARGETS}") endif() endfunction() diff --git a/scripts/cmake/vcpkg_configure_cmake.cmake b/scripts/cmake/vcpkg_configure_cmake.cmake index 1eb50e852..bce3f6af5 100644 --- a/scripts/cmake/vcpkg_configure_cmake.cmake +++ b/scripts/cmake/vcpkg_configure_cmake.cmake @@ -15,6 +15,7 @@ vcpkg_configure_cmake( [OPTIONS <-DUSE_THIS_IN_ALL_BUILDS=1>...] [OPTIONS_RELEASE <-DOPTIMIZE=1>...] [OPTIONS_DEBUG <-DDEBUGGABLE=1>...] + [MAYBE_UNUSED_VARIABLES ...] ) ``` @@ -53,6 +54,9 @@ Additional options passed to CMake during the Release configuration. These are i ### OPTIONS_DEBUG Additional options passed to CMake during the Debug configuration. These are in addition to `OPTIONS`. +### MAYBE_UNUSED_VARIABLES +Any CMake variables which are explicitly passed in, but which may not be used on all platforms. + ### LOGNAME Name of the log to write the output of the configure call to. @@ -73,9 +77,9 @@ function(vcpkg_configure_cmake) endif() cmake_parse_arguments(PARSE_ARGV 0 arg - "PREFER_NINJA;DISABLE_PARALLEL_CONFIGURE;NO_CHARSET_FLAG" + "PREFER_NINJA;DISABLE_PARALLEL_CONFIGURE;NO_CHARSET_FLAG;Z_VCPKG_IGNORE_UNUSED_VARIABLES" "SOURCE_PATH;GENERATOR;LOGNAME" - "OPTIONS;OPTIONS_DEBUG;OPTIONS_RELEASE" + "OPTIONS;OPTIONS_DEBUG;OPTIONS_RELEASE;MAYBE_UNUSED_VARIABLES" ) if(NOT VCPKG_PLATFORM_TOOLSET) @@ -87,6 +91,18 @@ function(vcpkg_configure_cmake) set(arg_LOGNAME config-${TARGET_TRIPLET}) endif() + set(manually_specified_variables "") + if(NOT arg_Z_VCPKG_IGNORE_UNUSED_VARIABLES) + foreach(option IN LISTS arg_OPTIONS arg_OPTIONS_RELEASE arg_OPTIONS_DEBUG) + if(option MATCHES "^-D([^:=]*)[:=]") + list(APPEND manually_specified_variables "${CMAKE_MATCH_1}") + endif() + endforeach() + list(REMOVE_DUPLICATES manually_specified_variables) + list(REMOVE_ITEM manually_specified_variables ${arg_MAYBE_UNUSED_VARIABLES}) + debug_message("manually specified variables: ${manually_specified_variables}") + endif() + if(CMAKE_HOST_WIN32) if(DEFINED ENV{PROCESSOR_ARCHITEW6432}) set(arg_HOST_ARCHITECTURE $ENV{PROCESSOR_ARCHITEW6432}) @@ -326,6 +342,10 @@ function(vcpkg_configure_cmake) WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/vcpkg-parallel-configure LOGNAME ${arg_LOGNAME} ) + + list(APPEND config_logs + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-out.log" + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-err.log") else() if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug") message(STATUS "Configuring ${TARGET_TRIPLET}-dbg") @@ -335,6 +355,9 @@ function(vcpkg_configure_cmake) WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg LOGNAME ${arg_LOGNAME}-dbg ) + list(APPEND config_logs + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-dbg-out.log" + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-dbg-err.log") endif() if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release") @@ -345,7 +368,44 @@ function(vcpkg_configure_cmake) WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel LOGNAME ${arg_LOGNAME}-rel ) + list(APPEND config_logs + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-rel-out.log" + "${CURRENT_BUILDTREES_DIR}/${arg_LOGNAME}-rel-err.log") + endif() + endif() + + # Check unused variables + set(all_unused_variables) + foreach(config_log IN LISTS config_logs) + if (NOT EXISTS "${config_log}") + continue() + endif() + file(READ "${config_log}" log_contents) + debug_message("Reading configure log ${config_log}...") + if(NOT log_contents MATCHES "Manually-specified variables were not used by the project:\n\n(( [^\n]*\n)*)") + continue() endif() + string(STRIP "${CMAKE_MATCH_1}" unused_variables) # remove leading ` ` and trailing `\n` + string(REPLACE "\n " ";" unused_variables "${unused_variables}") + debug_message("unused variables: ${unused_variables}") + + foreach(unused_variable IN LISTS unused_variables) + if(unused_variable IN_LIST manually_specified_variables) + debug_message("manually specified unused variable: ${unused_variable}") + list(APPEND all_unused_variables "${unused_variable}") + else() + debug_message("unused variable (not manually specified): ${unused_variable}") + endif() + endforeach() + endforeach() + + if(DEFINED all_unused_variables) + list(REMOVE_DUPLICATES all_unused_variables) + list(JOIN all_unused_variables "\n " all_unused_variables) + message(WARNING "The following variables are not used in CMakeLists.txt: + ${all_unused_variables} +Please recheck them and remove the unnecessary options from the `vcpkg_configure_cmake` call. +If these options should still be passed for whatever reason, please use the `MAYBE_UNUSED_VARIABLES` argument.") endif() set(Z_VCPKG_CMAKE_GENERATOR "${GENERATOR}" PARENT_SCOPE) diff --git a/scripts/cmake/vcpkg_get_program_files_platform_bitness.cmake b/scripts/cmake/vcpkg_get_program_files_platform_bitness.cmake index 7e3a5af52..b40b24c42 100644 --- a/scripts/cmake/vcpkg_get_program_files_platform_bitness.cmake +++ b/scripts/cmake/vcpkg_get_program_files_platform_bitness.cmake @@ -11,13 +11,10 @@ vcpkg_get_program_files_platform_bitness() ``` #]===] -function(vcpkg_get_program_files_platform_bitness ret) - - set(ret_temp $ENV{ProgramW6432}) - if (NOT DEFINED ret_temp) - set(ret_temp $ENV{PROGRAMFILES}) +function(vcpkg_get_program_files_platform_bitness out_var) + if(DEFINED ENV{ProgramW6432}) + set("${out_var}" "$ENV{ProgramW6432}" PARENT_SCOPE) + else() + set("${out_var}" "$ENV{PROGRAMFILES}" PARENT_SCOPE) endif() - - set(${ret} ${ret_temp} PARENT_SCOPE) - endfunction() diff --git a/scripts/cmake/vcpkg_get_windows_sdk.cmake b/scripts/cmake/vcpkg_get_windows_sdk.cmake index f16d4f53e..0a80d4c76 100644 --- a/scripts/cmake/vcpkg_get_windows_sdk.cmake +++ b/scripts/cmake/vcpkg_get_windows_sdk.cmake @@ -9,8 +9,10 @@ vcpkg_get_windows_sdk() ``` #]===] -function(vcpkg_get_windows_sdk ret) - set(WINDOWS_SDK $ENV{WindowsSDKVersion}) - string(REPLACE "\\" "" WINDOWS_SDK "${WINDOWS_SDK}") - set(${ret} ${WINDOWS_SDK} PARENT_SCOPE) +function(vcpkg_get_windows_sdk out_var) + if("$ENV{WindowsSDKVersion}" MATCHES [[^([0-9.]*)\\?$]]) + set("${out_var}" "${CMAKE_MATCH_1}" PARENT_SCOPE) + else() + message(FATAL_ERROR "Unexpected format for ENV{WindowsSDKVersion} ($ENV{WindowsSDKVersion})") + endif() endfunction() diff --git a/scripts/cmake/vcpkg_internal_get_cmake_vars.cmake b/scripts/cmake/vcpkg_internal_get_cmake_vars.cmake index 6c705ae8f..030d74120 100644 --- a/scripts/cmake/vcpkg_internal_get_cmake_vars.cmake +++ b/scripts/cmake/vcpkg_internal_get_cmake_vars.cmake @@ -53,6 +53,7 @@ function(vcpkg_internal_get_cmake_vars) OPTIONS_RELEASE "-DVCPKG_OUTPUT_FILE:PATH=${CURRENT_BUILDTREES_DIR}/cmake-vars-${TARGET_TRIPLET}-rel.cmake.log" PREFER_NINJA LOGNAME get-cmake-vars-${TARGET_TRIPLET} + Z_VCPKG_IGNORE_UNUSED_VARIABLES ) set(_include_string) diff --git a/scripts/cmake/vcpkg_list.cmake b/scripts/cmake/vcpkg_list.cmake new file mode 100644 index 000000000..74523dc62 --- /dev/null +++ b/scripts/cmake/vcpkg_list.cmake @@ -0,0 +1,257 @@ +#[===[.md: +# vcpkg_list + +A replacement for CMake's `list()` function, which correctly handles elements +with internal semicolons (in other words, escaped semicolons). +Use `vcpkg_list()` instead of `list()` whenever possible. + +```cmake +vcpkg_list(SET [...]) +vcpkg_list( [...]) +``` + +In addition to all of the commands from `list()`, `vcpkg_list` adds +a `vcpkg_list(SET)` command. +This command takes its arguments, escapes them, and then concatenates +them into a list; this should be used instead of `set()` for setting any +list variable. + +Otherwise, the `vcpkg_list()` function is the same as the built-in +`list()` function, with the following restrictions: + +- `GET`, `REMOVE_ITEM`, and `REMOVE_AT` support only one index/value +- `POP_BACK` and `POP_FRONT` do not support getting the value into + another out variable. Use C++ style `GET` then `POP_(BACK|FRONT)`. +- `FILTER` and `TRANSFORM` are unsupported. + +See the [CMake documentation for `list()`](https://cmake.org/cmake/help/latest/command/list.html) +for more information. + +## Notes: Some Weirdnesses + +The most major weirdness is due to `""` pulling double-duty as "list of zero elements", +and "list of one element, which is empty". `vcpkg_list` always uses the former understanding. +This can cause weird behavior, for example: + +```cmake +set(lst "") +vcpkg_list(APPEND lst "" "") +# lst = ";" +``` + +This is because you're appending two elements to the empty list. +One very weird behavior that comes out of this would be: + +```cmake +set(lst "") +vcpkg_list(APPEND lst "") +# lst = "" +``` + +since `""` is the empty list, we append the empty element and end up with a list +of one element, which is empty. This does not happen for non-empty lists; +for example: + +```cmake +set(lst "a") +vcpkg_list(APPEND lst "") +# lst = "a;" +``` + +only the empty list has this odd behavior. + +## Examples + +### Creating a list + +```cmake +vcpkg_list(SET foo_param) +if(DEFINED arg_FOO) + vcpkg_list(SET foo_param FOO "${arg_FOO}") +endif() +``` + +### Appending to a list + +```cmake +set(OPTIONS -DFOO=BAR) +if(VCPKG_TARGET_IS_WINDOWS) + vcpkg_list(APPEND OPTIONS "-DOS=WINDOWS;FOO") +endif() +``` + +### Popping the end off a list + +```cmake +if(NOT list STREQUAL "") + vcpkg_list(GET list end -1) + vcpkg_list(POP_BACK list) +endif() +``` +#]===] + +macro(z_vcpkg_list_escape_once_more lst) + string(REPLACE [[\;]] [[\\;]] "${lst}" "${${lst}}") +endmacro() + +function(vcpkg_list) + # NOTE: as this function replaces an existing CMake command, + # it does not use cmake_parse_arguments + + # vcpkg_list( ...) + # A0 A1 + + if(ARGC LESS "2") + message(FATAL_ERROR "vcpkg_list requires at least two arguments.") + endif() + + if(ARGV1 MATCHES "^ARGV([0-9]*)$|^ARG[CN]$|^CMAKE_CURRENT_FUNCTION") + message(FATAL_ERROR "vcpkg_list does not support the list_var being ${ARGV1}. + Please use a different variable name.") + endif() + + set(list "${${ARGV1}}") + set(operation "${ARGV0}") + set(list_var "${ARGV1}") + + if(operation STREQUAL "SET") + z_vcpkg_function_arguments(args 2) + set("${list_var}" "${args}" PARENT_SCOPE) + return() + endif() + + # Normal reading functions + if(operation STREQUAL "LENGTH") + # vcpkg_list(LENGTH ) + # A0 A1 A2 + if(NOT ARGC EQUAL "3") + message(FATAL_ERROR "vcpkg_list sub-command ${operation} requires two arguments.") + endif() + list(LENGTH list out) + set("${ARGV2}" "${out}" PARENT_SCOPE) + return() + endif() + if(operation MATCHES "^(GET|JOIN|FIND)$") + # vcpkg_list( ) + # A0 A1 A2 A3 + if(NOT ARGC EQUAL "4") + message(FATAL_ERROR "vcpkg_list sub-command ${operation} requires three arguments.") + endif() + if(operation STREQUAL "GET") + list(LENGTH list length) + if(length EQUAL "0") + message(FATAL_ERROR "vcpkg_list GET given empty list") + elseif(ARGV2 GREATER_EQUAL length OR ARGV2 LESS "-${length}") + message(FATAL_ERROR "vcpkg_list index: ${ARGV2} is not in range") + endif() + endif() + list("${operation}" list "${ARGV2}" out) + set("${ARGV3}" "${out}" PARENT_SCOPE) + return() + endif() + if(operation STREQUAL "SUBLIST") + # vcpkg_list(SUBLIST ) + # A0 A1 A2 A3 A4 + if(NOT ARGC EQUAL "5") + message(FATAL_ERROR "vcpkg_list sub-command SUBLIST requires four arguments.") + endif() + list(LENGTH list length) + if(ARGV2 LESS "0" OR (ARGV2 GREATER_EQUAL length AND NOT ARGV2 EQUAL "0")) + message(FATAL_ERROR "vcpkg_list begin index: ${ARGV2} is out of range") + endif() + z_vcpkg_list_escape_once_more(list) + list(SUBLIST list "${ARGV2}" "${ARGV3}" out) + set("${ARGV4}" "${out}" PARENT_SCOPE) + return() + endif() + + # modification functions + + if(operation MATCHES "^(APPEND|PREPEND)$") + # vcpkg_list( [...]) + # A0 A1 A2... + + # if ARGC <= 2, then we don't have to do anything + if(ARGC GREATER 2) + z_vcpkg_function_arguments(args 2) + if(list STREQUAL "") + set("${list_var}" "${args}" PARENT_SCOPE) + elseif(operation STREQUAL "APPEND") + set("${list_var}" "${list};${args}" PARENT_SCOPE) + else() + set("${list_var}" "${args};${list}" PARENT_SCOPE) + endif() + endif() + return() + endif() + if(operation STREQUAL "INSERT") + # vcpkg_list(INSERT [...]) + # A0 A1 A2 A3... + + list(LENGTH list length) + if(ARGV2 LESS "-{$length}" OR ARGV2 GREATER length) + message(FATAL_ERROR "vcpkg_list index: ${ARGV2} out of range") + endif() + if(ARGC GREATER 3) + # list(LENGTH) is one of the few subcommands that's fine + list(LENGTH list length) + if(ARGV2 LESS "0") + math(EXPR ARGV2 "${length} + ${ARGV2}") + endif() + if(ARGV2 LESS "0" OR ARGV2 GREATER length) + message(FATAL_ERROR "list index: ${ARGV2} out of range (-${length}, ${length})") + endif() + + z_vcpkg_function_arguments(args 3) + if(list STREQUAL "") + set("${list_var}" "${args}" PARENT_SCOPE) + elseif(ARGV2 EQUAL "0") + set("${list_var}" "${args};${list}" PARENT_SCOPE) + elseif(ARGV2 EQUAL length) + set("${list_var}" "${list};${args}" PARENT_SCOPE) + else() + vcpkg_list(SUBLIST list 0 "${ARGV2}" list_start) + vcpkg_list(SUBLIST list "${ARGV2}" -1 list_end) + set("${list_var}" "${list_start};${args};${list_end}" PARENT_SCOPE) + endif() + elseif(ARGC LESS 3) + message(FATAL_ERROR "vcpkg_list sub-command INSERT requires at least two arguments.") + endif() + return() + endif() + + if(operation MATCHES "^(POP_BACK|POP_FRONT|REVERSE|REMOVE_DUPLICATES)$") + # vcpkg_list( ) + # A0 A1 + if(NOT ARGC EQUAL 2) + message(FATAL_ERROR "vcpkg_list sub-command ${operation} requires one argument.") + endif() + z_vcpkg_list_escape_once_more(list) + list("${operation}" list) + set("${list_var}" "${list}" PARENT_SCOPE) + return() + endif() + + if(operation MATCHES "^(REMOVE_AT|REMOVE_ITEM)$") + # vcpkg_list( ) + # A0 A1 A2 + if(NOT ARGC EQUAL 3) + message(FATAL_ERROR "vcpkg_list sub-command ${operation} requires two arguments.") + endif() + if(operation STREQUAL "REMOVE_AT") + list(LENGTH list length) + if(ARGV2 GREATER_EQUAL length OR ARGV2 LESS "-${length}") + message(FATAL_ERROR "vcpkg_list index: ${ARGV2} out of range") + endif() + endif() + + z_vcpkg_list_escape_once_more(list) + string(REPLACE [[;]] [[\;]] ARGV2 "${ARGV2}") + + list("${operation}" list "${ARGV2}") + set("${list_var}" "${list}" PARENT_SCOPE) + return() + endif() + + message(FATAL_ERROR "vcpkg_list sub-command ${operation} is not yet implemented.") +endfunction() diff --git a/scripts/cmake/vcpkg_minimum_required.cmake b/scripts/cmake/vcpkg_minimum_required.cmake index 202935b89..44777875e 100644 --- a/scripts/cmake/vcpkg_minimum_required.cmake +++ b/scripts/cmake/vcpkg_minimum_required.cmake @@ -14,7 +14,7 @@ The date-version to check against. #]===] function(vcpkg_minimum_required) - cmake_parse_arguments(PARSE_ARGV 0 _vcpkg "" "VERSION" "") + cmake_parse_arguments(PARSE_ARGV 0 arg "" "VERSION" "") if (NOT DEFINED VCPKG_BASE_VERSION) message(FATAL_ERROR "Your vcpkg executable is outdated and is not compatible with the current CMake scripts. " @@ -22,27 +22,27 @@ function(vcpkg_minimum_required) ) endif() - set(_vcpkg_date_regex "^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$") - if (NOT VCPKG_BASE_VERSION MATCHES "${_vcpkg_date_regex}") + set(vcpkg_date_regex "^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$") + if (NOT VCPKG_BASE_VERSION MATCHES "${vcpkg_date_regex}") message(FATAL_ERROR - "vcpkg internal failure; \${VCPKG_BASE_VERSION} (${VCPKG_BASE_VERSION}) was not a valid date." + "vcpkg internal failure; VCPKG_BASE_VERSION (${VCPKG_BASE_VERSION}) was not a valid date." ) endif() - if (NOT _vcpkg_VERSION MATCHES "${_vcpkg_date_regex}") + if (NOT arg_VERSION MATCHES "${vcpkg_date_regex}") message(FATAL_ERROR "VERSION parameter to vcpkg_minimum_required was not a valid date. " - "Comparing with vcpkg tool version ${_vcpkg_matched_base_version}" + "Comparing with vcpkg tool version ${VCPKG_BASE_VERSION}" ) endif() - string(REPLACE "-" "." _VCPKG_BASE_VERSION_as_dotted "${VCPKG_BASE_VERSION}") - string(REPLACE "-" "." _vcpkg_VERSION_as_dotted "${_vcpkg_VERSION}") + string(REPLACE "-" "." VCPKG_BASE_VERSION_as_dotted "${VCPKG_BASE_VERSION}") + string(REPLACE "-" "." arg_VERSION_as_dotted "${arg_VERSION}") - if (_VCPKG_BASE_VERSION_as_dotted VERSION_LESS _vcpkg_VERSION_as_dotted) + if (VCPKG_BASE_VERSION_as_dotted VERSION_LESS vcpkg_VERSION_as_dotted) message(FATAL_ERROR "Your vcpkg executable is from ${VCPKG_BASE_VERSION} which is older than required by the caller " - "of vcpkg_minimum_required (${_vcpkg_VERSION}). " + "of vcpkg_minimum_required(VERSION ${arg_VERSION}). " "Please re-acquire vcpkg by running bootstrap-vcpkg." ) endif() diff --git a/scripts/cmake/vcpkg_replace_string.cmake b/scripts/cmake/vcpkg_replace_string.cmake index d24b8677e..1f8b37b65 100644 --- a/scripts/cmake/vcpkg_replace_string.cmake +++ b/scripts/cmake/vcpkg_replace_string.cmake @@ -4,13 +4,12 @@ Replace a string in a file. ```cmake -vcpkg_replace_string(filename match_string replace_string) +vcpkg_replace_string( ) ``` - #]===] -function(vcpkg_replace_string filename match_string replace_string) - file(READ ${filename} _contents) - string(REPLACE "${match_string}" "${replace_string}" _contents "${_contents}") - file(WRITE ${filename} "${_contents}") +function(vcpkg_replace_string filename match replace) + file(READ "${filename}" contents) + string(REPLACE "${match}" "${replace}" contents "${contents}") + file(WRITE "${filename}" "${contents}") endfunction() diff --git a/scripts/cmake/z_vcpkg_function_arguments.cmake b/scripts/cmake/z_vcpkg_function_arguments.cmake index 2c5b694ed..043c86191 100644 --- a/scripts/cmake/z_vcpkg_function_arguments.cmake +++ b/scripts/cmake/z_vcpkg_function_arguments.cmake @@ -32,22 +32,32 @@ macro(z_vcpkg_function_arguments OUT_VAR) set(z_vcpkg_function_arguments_FIRST_ARG 0) elseif("${ARGC}" EQUAL 2) set(z_vcpkg_function_arguments_FIRST_ARG "${ARGV1}") + + if(NOT z_vcpkg_function_arguments_FIRST_ARG GREATER_EQUAL "0" AND NOT z_vcpkg_function_arguments_FIRST_ARG LESS "0") + message(FATAL_ERROR "z_vcpkg_function_arguments: index (${z_vcpkg_function_arguments_FIRST_ARG}) is not a number") + elseif(z_vcpkg_function_arguments_FIRST_ARG LESS "0" OR z_vcpkg_function_arguments_FIRST_ARG GREATER ARGC) + message(FATAL_ERROR "z_vcpkg_function_arguments: index (${z_vcpkg_function_arguments_FIRST_ARG}) out of range") + endif() else() # vcpkg bug message(FATAL_ERROR "z_vcpkg_function_arguments: invalid arguments (${ARGV})") endif() - set("${OUT_VAR}") + set("${OUT_VAR}" "") # this allows us to get the value of the enclosing function's ARGC set(z_vcpkg_function_arguments_ARGC_NAME "ARGC") set(z_vcpkg_function_arguments_ARGC "${${z_vcpkg_function_arguments_ARGC_NAME}}") math(EXPR z_vcpkg_function_arguments_LAST_ARG "${z_vcpkg_function_arguments_ARGC} - 1") - if(z_vcpkg_function_arguments_LAST_ARG GREATER_EQUAL z_vcpkg_function_arguments_FIRST_ARG) + # GREATER_EQUAL added in CMake 3.7 + if(NOT z_vcpkg_function_arguments_LAST_ARG LESS z_vcpkg_function_arguments_FIRST_ARG) foreach(z_vcpkg_function_arguments_N RANGE "${z_vcpkg_function_arguments_FIRST_ARG}" "${z_vcpkg_function_arguments_LAST_ARG}") string(REPLACE ";" "\\;" z_vcpkg_function_arguments_ESCAPED_ARG "${ARGV${z_vcpkg_function_arguments_N}}") - list(APPEND "${OUT_VAR}" "${z_vcpkg_function_arguments_ESCAPED_ARG}") + # adds an extra ";" on the front + set("${OUT_VAR}" "${${OUT_VAR}};${z_vcpkg_function_arguments_ESCAPED_ARG}") endforeach() + # and then removes that extra semicolon + string(SUBSTRING "${${OUT_VAR}}" 1 -1 "${OUT_VAR}") endif() endmacro() diff --git a/scripts/ports.cmake b/scripts/ports.cmake index ce6fc557b..98a6e2352 100644 --- a/scripts/ports.cmake +++ b/scripts/ports.cmake @@ -130,6 +130,7 @@ if(CMD MATCHES "^BUILD$") include("${SCRIPTS}/cmake/vcpkg_install_nmake.cmake") include("${SCRIPTS}/cmake/vcpkg_install_qmake.cmake") include("${SCRIPTS}/cmake/vcpkg_internal_get_cmake_vars.cmake") + include("${SCRIPTS}/cmake/vcpkg_list.cmake") include("${SCRIPTS}/cmake/vcpkg_replace_string.cmake") include("${SCRIPTS}/cmake/vcpkg_test_cmake.cmake") diff --git a/scripts/test_ports/unit-test-cmake/portfile.cmake b/scripts/test_ports/unit-test-cmake/portfile.cmake new file mode 100644 index 000000000..638b15974 --- /dev/null +++ b/scripts/test_ports/unit-test-cmake/portfile.cmake @@ -0,0 +1,73 @@ +function(set_fatal_error) + if(ARGC EQUAL 0) + set(Z_VCPKG_UNIT_TEST_HAS_FATAL_ERROR "OFF" CACHE BOOL "" FORCE) + else() + set(Z_VCPKG_UNIT_TEST_HAS_FATAL_ERROR "ON" CACHE BOOL "" FORCE) + set(Z_VCPKG_UNIT_TEST_FATAL_ERROR "${ARGV0}" CACHE STRING "" FORCE) + endif() +endfunction() +function(set_has_error) + set(Z_VCPKG_UNIT_TEST_HAS_ERROR ON CACHE BOOL "" FORCE) +endfunction() + +macro(message level msg) + if("${level}" STREQUAL "FATAL_ERROR") + set_fatal_error("${msg}") + return() + else() + _message("${level}" "${msg}") # note: this results in incorrect printing, but that's fine + # message(STATUS "\${asdf}") will result in + # message(STATUS "${asdf}"), since that's how macro arguments work. + endif() +endmacro() + +set(Z_VCPKG_UNIT_TEST_HAS_ERROR OFF CACHE BOOL "" FORCE) +set_fatal_error() + +function(unit_test_check_variable_equal utcve_test utcve_variable utcve_value) + cmake_language(EVAL CODE "${utcve_test}") + if(Z_VCPKG_UNIT_TEST_HAS_FATAL_ERROR) + set_fatal_error() + set_has_error() + message(STATUS "${utcve_test} had an unexpected FATAL_ERROR; + expected: \"${utcve_value}\"") + message(STATUS "FATAL_ERROR: ${Z_VCPKG_UNIT_TEST_FATAL_ERROR}") + return() + endif() + + if(NOT DEFINED "${utcve_variable}") + message(STATUS "${utcve_test} failed to set ${utcve_variable}; + expected: \"${utcve_value}\"") + set_has_error() + return() + endif() + if(NOT "${${utcve_variable}}" STREQUAL "${utcve_value}") + message(STATUS "${utcve_test} resulted in the wrong value for ${utcve_variable}; + expected: \"${utcve_value}\" + actual : \"${${utcve_variable}}\"") + set_has_error() + return() + endif() +endfunction() + +function(unit_test_ensure_fatal_error utcve_test) + cmake_language(EVAL CODE "${utcve_test}") + if(NOT Z_VCPKG_UNIT_TEST_HAS_FATAL_ERROR) + set_has_error() + message(STATUS "${utcve_test} was expected to be a FATAL_ERROR.") + endif() + set_fatal_error() +endfunction() + +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) + +if("list" IN_LIST FEATURES) + include("${CMAKE_CURRENT_LIST_DIR}/test-vcpkg_list.cmake") +endif() +if("function-arguments" IN_LIST FEATURES) + include("${CMAKE_CURRENT_LIST_DIR}/test-z_vcpkg_function_arguments.cmake") +endif() + +if(Z_VCPKG_UNIT_TEST_HAS_ERROR) + _message(FATAL_ERROR "At least one test failed") +endif() diff --git a/scripts/test_ports/unit-test-cmake/test-vcpkg_list.cmake b/scripts/test_ports/unit-test-cmake/test-vcpkg_list.cmake new file mode 100644 index 000000000..c0f3ac8c0 --- /dev/null +++ b/scripts/test_ports/unit-test-cmake/test-vcpkg_list.cmake @@ -0,0 +1,813 @@ +# vcpkg_list(SET ...) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst "")]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst "" "")]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst a)]] + lst "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst a b)]] + lst "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(SET lst "a;b")]] + lst [[a\;b]] +) +unit_test_check_variable_equal( + [=[vcpkg_list(SET lst "a;b" "c" [[d\;e]])]=] + lst [[a\;b;c;d\\;e]] +) + +# vcpkg_list(LENGTH ) +set(lst [[]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 0 +) +set(lst [[;]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 2 +) +set(lst [[a]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 1 +) +set(lst [[a;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 2 +) +set(lst [[a\\;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 1 +) +set(lst [[a\;b;c\\;d]]) +unit_test_check_variable_equal( + [[vcpkg_list(LENGTH lst out)]] + out 2 +) + +# vcpkg_list(GET ) +set(lst "") +unit_test_ensure_fatal_error([[vcpkg_list(GET lst 0 out)]]) + +set(lst "a") +unit_test_check_variable_equal( + [[vcpkg_list(GET lst 0 out)]] + out "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst -1 out)]] + out "a" +) +unit_test_ensure_fatal_error([[vcpkg_list(GET lst 2 out)]]) +unit_test_ensure_fatal_error([[vcpkg_list(GET lst -2 out)]]) + +set(lst ";b") +unit_test_check_variable_equal( + [[vcpkg_list(GET lst 0 out)]] + out "" +) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst -1 out)]] + out "b" +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(GET lst 0 out)]] + out "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst -1 out)]] + out "b" +) + +set(lst [[a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst 0 out)]] + out "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst -1 out)]] + out "c" +) + +set(lst [[a;b\;c;d\\;e]]) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst 1 out)]] + out "b;c" +) +unit_test_check_variable_equal( + [[vcpkg_list(GET lst -1 out)]] + out [[d\;e]] +) + +# vcpkg_list(JOIN ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "-" out)]] + out "" +) + +set(lst "a") +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "-" out)]] + out "a" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "-" out)]] + out "-" +) + +set(lst [[a;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "-" out)]] + out [[a-b]] +) +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "+" out)]] + out [[a+b]] +) + +set(lst [[a;b\;c\\;d]]) +unit_test_check_variable_equal( + [[vcpkg_list(JOIN lst "-" out)]] + out [[a-b;c\;d]] +) + +# vcpkg_list(SUBLIST ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 0 out)]] + out "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 1 out)]] + out "" +) +unit_test_ensure_fatal_error([[vcpkg_list(SUBLIST lst 1 0 out)]]) + +set(lst "a") +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 0 out)]] + out "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 1 out)]] + out "a" +) +unit_test_ensure_fatal_error([[vcpkg_list(SUBLIST lst 2 0 out)]]) +unit_test_ensure_fatal_error([[vcpkg_list(SUBLIST lst 2 1 out)]]) + +set(lst ";;") +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 0 out)]] + out "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 1 out)]] + out "" +) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 2 out)]] + out ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 0 3 out)]] + out ";;" +) + +set(lst "a;b;c;d") +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 1 2 out)]] + out "b;c" +) + +set(lst [[a\;b;c\;d;e]]) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 1 2 out)]] + out [[c\;d;e]] +) + +set(lst [[a\;b;c\\;d;e;f;g;h]]) +unit_test_check_variable_equal( + [[vcpkg_list(SUBLIST lst 1 -1 out)]] + out [[c\\;d;e;f;g;h]] +) + +# vcpkg_list(FIND ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst "a" out)]] + out -1 +) + +set(lst "b") +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst "a" out)]] + out -1 +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst "a" out)]] + out 0 +) +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst b out)]] + out 1 +) + +set(lst ";b") +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst "" out)]] + out 0 +) +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst b out)]] + out 1 +) + +set(lst [[a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst "a;b" out)]] + out 0 +) +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst c out)]] + out 1 +) +unit_test_check_variable_equal( + [[vcpkg_list(FIND lst a out)]] + out -1 +) + +set(lst [[a\\;b;c]]) +unit_test_check_variable_equal( + [=[vcpkg_list(FIND lst [[a\;b]] out)]=] + out 0 +) + +# vcpkg_list(APPEND [...]) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst)]] + lst [[]] +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "")]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "" "")]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst a)]] + lst "a" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst)]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "")]] + lst ";;" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst b)]] + lst ";;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "b;c" d)]] + lst [[;;b\;c;d]] +) + +set(lst "a") +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst)]] + lst "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "")]] + lst "a;" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst b)]] + lst "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "b;c" d)]] + lst [[a;b\;c;d]] +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst)]] + lst "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "")]] + lst "a;b;" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst c)]] + lst "a;b;c" +) +unit_test_check_variable_equal( + [[vcpkg_list(APPEND lst "c;d" e)]] + lst [[a;b;c\;d;e]] +) +unit_test_check_variable_equal( + [=[vcpkg_list(APPEND lst [[c\;d]])]=] + lst [[a;b;c\\;d]] +) + +# vcpkg_list(PREPEND [...]) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "")]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "" "")]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst a)]] + lst "a" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst)]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "")]] + lst ";;" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst b)]] + lst "b;;" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "b;c" d)]] + lst [[b\;c;d;;]] +) + +set(lst "a") +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst)]] + lst "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "")]] + lst ";a" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst b)]] + lst "b;a" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "b;c" d)]] + lst [[b\;c;d;a]] +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst)]] + lst "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "")]] + lst ";a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst c)]] + lst "c;a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(PREPEND lst "c;d" e)]] + lst [[c\;d;e;a;b]] +) +unit_test_check_variable_equal( + [=[vcpkg_list(PREPEND lst [[c\;d]])]=] + lst [[c\\;d;a;b]] +) + +# list(INSERT [...]) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0 "")]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0 "" "")]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0 "a")]] + lst "a" +) +unit_test_ensure_fatal_error([[vcpkg_list(INSERT lst 1 "")]]) +unit_test_ensure_fatal_error([[vcpkg_list(INSERT lst -1 "")]]) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0)]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 1)]] + lst ";" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 1 "")]] + lst ";;" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 0 b)]] + lst "b;;" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 1 b)]] + lst ";b;" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 2 b)]] + lst ";;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst -1 "b;c" d)]] + lst [[;b\;c;d;]] +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst -2 "b;c" d)]] + lst [[b\;c;d;;]] +) +unit_test_ensure_fatal_error([[vcpkg_list(INSERT lst 3 "")]]) +unit_test_ensure_fatal_error([[vcpkg_list(INSERT lst -3 "")]]) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst -1 c)]] + lst "a;c;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 1 c)]] + lst "a;c;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 2 c)]] + lst "a;b;c" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst -2 c)]] + lst "c;a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(INSERT lst 1 "c;d")]] + lst [[a;c\;d;b]] +) +unit_test_check_variable_equal( + [=[vcpkg_list(INSERT lst 1 [[c\;d]] e)]=] + lst [[a;c\\;d;e;b]] +) + +# vcpkg_list(POP_BACK ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "" +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "a" +) + +set(lst "a;;b") +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "a;" +) + +set(lst [[a\;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "" +) + +set(lst [[c;a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst [[c;a\;b]] +) + +# vcpkg_list(POP_FRONT ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(POP_BACK lst)]] + lst "" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(POP_FRONT lst)]] + lst "" +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(POP_FRONT lst)]] + lst "b" +) + +set(lst "a;;b") +unit_test_check_variable_equal( + [[vcpkg_list(POP_FRONT lst)]] + lst ";b" +) + +set(lst [[a\;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(POP_FRONT lst)]] + lst "" +) + +set(lst [[c;a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(POP_FRONT lst)]] + lst [[a\;b;c]] +) + +# vcpkg_list(REMOVE_DUPLICATES ) +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "" +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "a;b" +) + +set(lst "a;a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "a;b" +) + +set(lst "a;b;a") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "a;b" +) + +set(lst "c;a;b;a;c") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "c;a;b" +) + +set(lst "a;;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst "a;;b" +) + +set(lst [[a\;b;a\;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst [[a\;b]] +) + +set(lst [[c;a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_DUPLICATES lst)]] + lst [[c;a\;b]] +) + +# vcpkg_list(REVERSE ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst "" +) +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst ";" +) +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst "b;a" +) +set(lst "a;b;c;d;e;f;g") +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst "g;f;e;d;c;b;a" +) + +set(lst [[a\;b;a\;b\\;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst [[a\;b\\;c;a\;b]] +) +set(lst [[c;a\;b]]) +unit_test_check_variable_equal( + [[vcpkg_list(REVERSE lst)]] + lst [[a\;b;c]] +) + +# vcpkg_list(REMOVE_ITEM ) +set(lst "") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "a")]] + lst "" +) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "")]] + lst "" +) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst a)]] + lst "b" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst b)]] + lst "a" +) + +set(lst "a;a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst a)]] + lst "b" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst b)]] + lst "a;a" +) + +set(lst "a;b;c;a;d") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst b)]] + lst "a;c;a;d" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst a)]] + lst "b;c;d" +) + +set(lst "a;;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "")]] + lst "a;b" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst a)]] + lst ";b" +) + +set(lst [[e;a\;b;c\;d]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "a;b")]] + lst [[e;c\;d]] +) + +set(lst [[c;a\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "c")]] + lst [[a\;b]] +) + +set(lst [[c;a\\;b;c]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_ITEM lst "a\\;b")]] + lst [[c;c]] +) + +# vcpkg_list(REMOVE_AT ) +set(lst "") +unit_test_ensure_fatal_error([[vcpkg_list(REMOVE_AT lst 0)]]) + +set(lst ";") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 0)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 1)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst -1)]] + lst "" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst -2)]] + lst "" +) +unit_test_ensure_fatal_error([[vcpkg_list(REMOVE_AT lst 2)]]) +unit_test_ensure_fatal_error([[vcpkg_list(REMOVE_AT lst -3)]]) + +set(lst "a;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 0)]] + lst "b" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 1)]] + lst "a" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst -1)]] + lst "a" +) + +set(lst "a;;b") +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 0)]] + lst ";b" +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 1)]] + lst "a;b" +) + +set(lst [[e;a\;b;c\;d]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 0)]] + lst [[a\;b;c\;d]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 1)]] + lst [[e;c\;d]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst -1)]] + lst [[e;a\;b]] +) + +set(lst [[c;a\\;b;c\;d;e]]) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 0)]] + lst [[a\\;b;c\;d;e]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 1)]] + lst [[c;c\;d;e]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 2)]] + lst [[c;a\\;b;e]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst 3)]] + lst [[c;a\\;b;c\;d]] +) +unit_test_check_variable_equal( + [[vcpkg_list(REMOVE_AT lst -1)]] + lst [[c;a\\;b;c\;d]] +) diff --git a/scripts/test_ports/unit-test-cmake/test-z_vcpkg_function_arguments.cmake b/scripts/test_ports/unit-test-cmake/test-z_vcpkg_function_arguments.cmake new file mode 100644 index 000000000..e88eb683f --- /dev/null +++ b/scripts/test_ports/unit-test-cmake/test-z_vcpkg_function_arguments.cmake @@ -0,0 +1,63 @@ +# these both set `args` in the top level +function(check_function_args start) + z_vcpkg_function_arguments(out "${start}") + set(args "${out}" PARENT_SCOPE) +endfunction() +function(check_all_function_args) + z_vcpkg_function_arguments(out) + set(args "${out}" PARENT_SCOPE) +endfunction() + +unit_test_ensure_fatal_error([[check_function_args(-1)]]) +unit_test_ensure_fatal_error([[check_function_args(3)]]) +unit_test_ensure_fatal_error([[check_function_args(notanumber)]]) +unit_test_check_variable_equal( + [[check_all_function_args()]] + args "" +) +unit_test_check_variable_equal( + [[check_all_function_args("")]] + args "" +) +unit_test_check_variable_equal( + [[check_all_function_args("" "")]] + args ";" +) +unit_test_check_variable_equal( + [[check_all_function_args("" "" "" "")]] + args ";;;" +) + +unit_test_check_variable_equal( + [[check_all_function_args(a b c)]] + args "a;b;c" +) +unit_test_check_variable_equal( + [[check_function_args(2 a b c)]] + args "b;c" +) +unit_test_check_variable_equal( + [[check_function_args(3 a b c)]] + args "c" +) + +unit_test_check_variable_equal( + [=[check_all_function_args("a;b" [[c\;d]] e)]=] + args [[a\;b;c\\;d;e]] +) +unit_test_check_variable_equal( + [=[check_all_function_args("a;b" [[c\;d]] [[e\\;f]])]=] + args [[a\;b;c\\;d;e\\\;f]] +) +unit_test_check_variable_equal( + [=[check_function_args(2 "a;b" [[c\;d]] e)]=] + args [[c\\;d;e]] +) +unit_test_check_variable_equal( + [=[check_function_args(3 "a;b" [[c\;d]] e)]=] + args "e" +) +unit_test_check_variable_equal( + [=[check_function_args(4 "a;b" [[c\;d]] e)]=] + args "" +) diff --git a/scripts/test_ports/unit-test-cmake/vcpkg.json b/scripts/test_ports/unit-test-cmake/vcpkg.json new file mode 100644 index 000000000..5079f9e73 --- /dev/null +++ b/scripts/test_ports/unit-test-cmake/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "unit-test-cmake", + "version-string": "0", + "description": "Ensures that the CMake scripts are unit tested.", + "supports": "x64", + "default-features": [ + "function-arguments", + "list" + ], + "features": { + "function-arguments": { + "description": "Test the z_vcpkg_function_arguments function" + }, + "list": { + "description": "Test the vcpkg_list function" + } + } +} -- cgit v1.2.3