Init repository logic eats the '-verbose' argument as the one that is handled by internal init repository logic. The argument is also a valid argument for configure script. Introduce the 'COMMON' argument for of the qt_ir_commandline_option macro. The argument indicates that the option is applicable for both configure and init-repository scripts. This is implemented only for boolean arguments. The '-verbose' argument adopted the new feature. Pick-to: 6.7 6.8 Change-Id: I5cb76502c8ecccccf3546fd7f7f111fe25700d0a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
424 lines
14 KiB
CMake
424 lines
14 KiB
CMake
# Copyright (C) 2024 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
# This file contains a modified subset of the qtbase/QtProcessConfigureArgs.cmake commands
|
|
# with renamed functions, because we need similar logic for init-repository, but
|
|
# we can't access qtbase before we clone it.
|
|
|
|
# Call a function with the given arguments.
|
|
function(qt_ir_call_function func)
|
|
set(call_code "${func}(")
|
|
math(EXPR n "${ARGC} - 1")
|
|
foreach(i RANGE 1 ${n})
|
|
string(APPEND call_code "\"${ARGV${i}}\" ")
|
|
endforeach()
|
|
string(APPEND call_code ")")
|
|
string(REPLACE "\\" "\\\\" call_code "${call_code}")
|
|
if(${CMAKE_VERSION} VERSION_LESS "3.18.0")
|
|
set(incfile qt_tmp_func_call.cmake)
|
|
file(WRITE "${incfile}" "${call_code}")
|
|
include(${incfile})
|
|
file(REMOVE "${incfile}")
|
|
else()
|
|
cmake_language(EVAL CODE "${call_code}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Show an error.
|
|
function(qt_ir_add_error)
|
|
message(FATAL_ERROR ${ARGV})
|
|
endfunction()
|
|
|
|
# Check if there are still unhandled command line arguments.
|
|
function(qt_ir_args_has_next_command_line_arg out_var)
|
|
qt_ir_get_unhandled_args(args)
|
|
|
|
list(LENGTH args n)
|
|
if(n GREATER 0)
|
|
set(result TRUE)
|
|
else()
|
|
set(result FALSE)
|
|
endif()
|
|
set(${out_var} ${result} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Get the next unhandled command line argument without popping it.
|
|
function(qt_ir_args_peek_next_command_line_arg out_var)
|
|
qt_ir_get_unhandled_args(args)
|
|
list(GET args 0 result)
|
|
set(${out_var} ${result} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Get the next unhandled command line argument.
|
|
function(qt_ir_args_get_next_command_line_arg out_var)
|
|
qt_ir_get_unhandled_args(args)
|
|
list(POP_FRONT args result)
|
|
qt_ir_set_unhandled_args("${args}")
|
|
set(${out_var} ${result} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Helper macro to parse the arguments for the command line options.
|
|
macro(qt_ir_commandline_option_parse_arguments)
|
|
set(options UNSUPPORTED COMMON)
|
|
set(oneValueArgs TYPE NAME SHORT_NAME ALIAS VALUE DEFAULT_VALUE)
|
|
set(multiValueArgs VALUES MAPPING)
|
|
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
endmacro()
|
|
|
|
# We use this to define the command line options that init-repository accepts.
|
|
# Arguments
|
|
# name - name of the long form option
|
|
# e.g. 'module-subset' will parse '--module-subset'
|
|
# UNSUPPORTED - mark the option as unsupported in the cmake port of init-repository,
|
|
# which means we will fall back to calling the perl script instead
|
|
# TYPE - the type of the option, currently we support boolean, string and void
|
|
# VALUE - the value to be set for a 'void' type option
|
|
# VALUES - the valid values for an option
|
|
# MAPPING - currently unused
|
|
# SHORT_NAME - an alternative short name flag,
|
|
# e.g. 'f' will parse -f for --force
|
|
# ALIAS - mark the option as an alias of another option, both will have the
|
|
# same value when retrieved.
|
|
# DEFAULT_VALUE - the default value to be set for the option when it's not specified
|
|
# on the command line
|
|
# COMMON - the argument is common for init-repository and configure scripts
|
|
#
|
|
# NOTE: Make sure to update the SHORT_NAME code path when adding new options.
|
|
function(qt_ir_commandline_option_helper name)
|
|
qt_ir_commandline_option_parse_arguments(${ARGN})
|
|
|
|
set(unsupported_options "${commandline_known_unsupported_options}")
|
|
if(arg_UNSUPPORTED)
|
|
set(commandline_option_${name}_unsupported
|
|
"${arg_UNSUPPORTED}" PARENT_SCOPE)
|
|
list(APPEND unsupported_options "${name}")
|
|
endif()
|
|
set(commandline_known_unsupported_options "${unsupported_options}" PARENT_SCOPE)
|
|
|
|
set(commandline_known_options
|
|
"${commandline_known_options};${name}" PARENT_SCOPE)
|
|
|
|
if(arg_COMMON)
|
|
set(commandline_option_${name}_common "true" PARENT_SCOPE)
|
|
if(NOT "${arg_TYPE}" STREQUAL "boolean")
|
|
message(FATAL_ERROR "${name} is '${arg_TYPE}', but COMMON arguments can be"
|
|
" 'boolean' only.")
|
|
endif()
|
|
endif()
|
|
|
|
set(commandline_option_${name}_type "${arg_TYPE}" PARENT_SCOPE)
|
|
|
|
if(NOT "${arg_VALUE}" STREQUAL "")
|
|
set(commandline_option_${name}_value "${arg_VALUE}" PARENT_SCOPE)
|
|
endif()
|
|
|
|
if(arg_VALUES)
|
|
set(commandline_option_${name}_values ${arg_VALUES} PARENT_SCOPE)
|
|
elseif(arg_MAPPING)
|
|
set(commandline_option_${name}_mapping ${arg_MAPPING} PARENT_SCOPE)
|
|
endif()
|
|
|
|
if(NOT "${arg_SHORT_NAME}" STREQUAL "")
|
|
set(commandline_option_${name}_short_name "${arg_SHORT_NAME}" PARENT_SCOPE)
|
|
endif()
|
|
|
|
if(NOT "${arg_ALIAS}" STREQUAL "")
|
|
set(commandline_option_${name}_alias "${arg_ALIAS}" PARENT_SCOPE)
|
|
endif()
|
|
|
|
# Should be last, in case alias was specified
|
|
if(NOT "${arg_DEFAULT_VALUE}" STREQUAL "")
|
|
set(commandline_option_${name}_default_value "${arg_DEFAULT_VALUE}" PARENT_SCOPE)
|
|
qt_ir_command_line_set_input("${name}" "${arg_DEFAULT_VALUE}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Defines an option that init-repository understands.
|
|
# Uses qt_ir_commandline_option_helper to define both long and short option names.
|
|
macro(qt_ir_commandline_option name)
|
|
# Define the main option
|
|
qt_ir_commandline_option_helper("${name}" ${ARGN})
|
|
|
|
qt_ir_commandline_option_parse_arguments(${ARGN})
|
|
|
|
# Define the short name option if it's requested
|
|
if(NOT "${arg_SHORT_NAME}" STREQUAL ""
|
|
AND "${commandline_option_${arg_SHORT_NAME}_type}" STREQUAL "")
|
|
set(unsupported "")
|
|
if(arg_UNSUPPORTED)
|
|
set(unsupported "UNSUPPORTED")
|
|
endif()
|
|
|
|
set(common "")
|
|
if(arg_COMMON)
|
|
set(common "COMMON")
|
|
endif()
|
|
|
|
qt_ir_commandline_option_helper("${arg_SHORT_NAME}"
|
|
TYPE "${arg_TYPE}"
|
|
ALIAS "${name}"
|
|
VALUE "${arg_VALUE}"
|
|
VALUES ${arg_VALUES}
|
|
MAPPING ${arg_MAPPING}
|
|
DEFAULT_VALUE ${arg_DEFAULT_VALUE}
|
|
${unsupported}
|
|
${common}
|
|
)
|
|
endif()
|
|
endmacro()
|
|
|
|
# Saves the value of a command line option into a global property.
|
|
function(qt_ir_command_line_set_input name val)
|
|
if(NOT "${commandline_option_${name}_alias}" STREQUAL "")
|
|
set(name "${commandline_option_${name}_alias}")
|
|
endif()
|
|
|
|
set_property(GLOBAL PROPERTY _qt_ir_input_${name} "${val}")
|
|
set_property(GLOBAL APPEND PROPERTY _qt_ir_inputs ${name})
|
|
endfunction()
|
|
|
|
# Appends a value of a command line option into a global property.
|
|
# Currently unused
|
|
function(qt_ir_command_line_append_input name val)
|
|
if(NOT "${commandline_option_${name}_alias}" STREQUAL "")
|
|
set(name "${commandline_option_${name}_alias}")
|
|
endif()
|
|
|
|
get_property(oldval GLOBAL PROPERTY _qt_ir_input_${name})
|
|
if(NOT "${oldval}" STREQUAL "")
|
|
string(PREPEND val "${oldval};")
|
|
endif()
|
|
qt_ir_command_line_set_input(${name} "${val}" )
|
|
endfunction()
|
|
|
|
# Checks if the value of a command line option is valid.
|
|
function(qt_ir_validate_value opt val out_var)
|
|
set(${out_var} TRUE PARENT_SCOPE)
|
|
|
|
set(valid_values ${commandline_option_${arg}_values})
|
|
list(LENGTH valid_values n)
|
|
if(n EQUAL 0)
|
|
return()
|
|
endif()
|
|
|
|
foreach(v ${valid_values})
|
|
if(val STREQUAL v)
|
|
return()
|
|
endif()
|
|
endforeach()
|
|
|
|
set(${out_var} FALSE PARENT_SCOPE)
|
|
list(JOIN valid_values " " valid_values_str)
|
|
qt_ir_add_error("Invalid value '${val}' supplied to command line option '${opt}'."
|
|
"\nAllowed values: ${valid_values_str}\n")
|
|
endfunction()
|
|
|
|
# Sets / handles the value of a command line boolean option.
|
|
function(qt_ir_commandline_boolean arg val nextok)
|
|
if("${val}" STREQUAL "")
|
|
set(val "yes")
|
|
endif()
|
|
if(NOT val STREQUAL "yes" AND NOT val STREQUAL "no")
|
|
message(FATAL_ERROR
|
|
"Invalid value '${val}' given for boolean command line option '${arg}'.")
|
|
endif()
|
|
qt_ir_command_line_set_input("${arg}" "${val}")
|
|
endfunction()
|
|
|
|
# Sets / handles the value of a command line string option.
|
|
function(qt_ir_commandline_string arg val nextok)
|
|
if(nextok)
|
|
qt_ir_args_get_next_command_line_arg(val)
|
|
|
|
if("${val}" MATCHES "^-")
|
|
qt_ir_add_error("No value supplied to command line options '${arg}'.")
|
|
endif()
|
|
endif()
|
|
qt_ir_validate_value("${arg}" "${val}" success)
|
|
if(success)
|
|
qt_ir_command_line_set_input("${arg}" "${val}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Sets / handles the value of a command line void option.
|
|
# This is an option like --force, which doesn't take any arguments.
|
|
# Currently unused
|
|
function(qt_ir_commandline_void arg val nextok)
|
|
if(NOT "${val}" STREQUAL "")
|
|
qt_i_add_error("Command line option '${arg}' expects no argument ('${val}' given).")
|
|
endif()
|
|
if(DEFINED commandline_option_${arg}_value)
|
|
set(val ${commandline_option_${arg}_value})
|
|
endif()
|
|
if("${val}" STREQUAL "")
|
|
set(val yes)
|
|
endif()
|
|
qt_ir_command_line_set_input("${arg}" "${val}")
|
|
endfunction()
|
|
|
|
# Reads the command line arguments from the optfile_path.
|
|
function(qt_ir_get_raw_args_from_optfile optfile_path out_var)
|
|
file(STRINGS "${optfile_path}" args)
|
|
qt_ir_escape_semicolons(args "${args}")
|
|
set(${out_var} "${args}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Reads the optfile_path, iterates over the given command line arguments,
|
|
# sets the input for recongized options.
|
|
#
|
|
# Handles the following styles of CLI arguments:
|
|
# --no-foo / --disable-foo
|
|
# -no-foo / -disable-foo
|
|
# --foo=<values>
|
|
# --foo <values>
|
|
# -foo <values>
|
|
# --foo
|
|
# -foo
|
|
# --f
|
|
# -f
|
|
#
|
|
# Currently handles the following types of CLI arguments:
|
|
# string
|
|
# boolean
|
|
# void
|
|
#
|
|
# IGNORE_UNKNOWN_ARGS tells the function not to fail if it encounters an unknown
|
|
# option, and instead append it to a global list of unknown options.
|
|
# It is needed when the script is called from the configure script with
|
|
# configure-only-known options.
|
|
function(qt_ir_process_args_from_optfile optfile_path)
|
|
set(options IGNORE_UNKNOWN_ARGS)
|
|
set(oneValueArgs "")
|
|
set(multiValueArgs "")
|
|
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
|
|
qt_ir_get_raw_args_from_optfile("${optfile_path}" configure_args)
|
|
qt_ir_set_unhandled_args("${configure_args}")
|
|
|
|
while(1)
|
|
qt_ir_args_has_next_command_line_arg(has_next)
|
|
if(NOT has_next)
|
|
break()
|
|
endif()
|
|
qt_ir_args_get_next_command_line_arg(arg)
|
|
|
|
# parse out opt and val
|
|
set(nextok FALSE)
|
|
if(arg MATCHES "^--?(disable|no)-(.*)")
|
|
set(opt "${CMAKE_MATCH_2}")
|
|
set(val "no")
|
|
elseif(arg MATCHES "^--([^=]+)=(.*)")
|
|
set(opt "${CMAKE_MATCH_1}")
|
|
set(val "${CMAKE_MATCH_2}")
|
|
elseif(arg MATCHES "^--(.*)")
|
|
set(nextok TRUE)
|
|
set(opt "${CMAKE_MATCH_1}")
|
|
unset(val)
|
|
elseif(arg MATCHES "^-(.*)")
|
|
set(nextok TRUE)
|
|
set(opt "${CMAKE_MATCH_1}")
|
|
unset(val)
|
|
else()
|
|
if(NOT arg_IGNORE_UNKNOWN_ARGS)
|
|
qt_ir_add_error("Invalid command line parameter '${arg}'.")
|
|
else()
|
|
message(DEBUG "Unknown command line parameter '${arg}'. Collecting.")
|
|
qt_ir_append_unknown_args("${arg}")
|
|
continue()
|
|
endif()
|
|
endif()
|
|
|
|
set(type "${commandline_option_${opt}_type}")
|
|
|
|
if("${type}" STREQUAL "")
|
|
if(NOT arg_IGNORE_UNKNOWN_ARGS)
|
|
qt_ir_add_error("Unknown command line option '${arg}'.")
|
|
else()
|
|
message(DEBUG "Unknown command line option '${arg}'. Collecting.")
|
|
qt_ir_append_unknown_args("${arg}")
|
|
continue()
|
|
endif()
|
|
elseif(commandline_option_${opt}_common AND arg_IGNORE_UNKNOWN_ARGS)
|
|
message(DEBUG "Common command line option '${arg}'. Collecting.")
|
|
qt_ir_append_unknown_args("${arg}")
|
|
endif()
|
|
|
|
if(NOT COMMAND "qt_ir_commandline_${type}")
|
|
qt_ir_add_error("Unknown type '${type}' for command line option '${opt}'.")
|
|
endif()
|
|
qt_ir_call_function("qt_ir_commandline_${type}" "${opt}" "${val}" "${nextok}")
|
|
endwhile()
|
|
endfunction()
|
|
|
|
# Shows help for the command line options.
|
|
function(qt_ir_show_help)
|
|
set(help_file "${CMAKE_CURRENT_LIST_DIR}/QtIRHelp.txt")
|
|
if(EXISTS "${help_file}")
|
|
file(READ "${help_file}" content)
|
|
message("${content}")
|
|
endif()
|
|
|
|
message([[
|
|
General Options:
|
|
-help, -h ............ Display this help screen
|
|
]])
|
|
endfunction()
|
|
|
|
# Gets the unhandled command line args.
|
|
function(qt_ir_get_unhandled_args out_var)
|
|
get_property(args GLOBAL PROPERTY _qt_ir_unhandled_args)
|
|
set(${out_var} "${args}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Sets the unhandled command line args.
|
|
function(qt_ir_set_unhandled_args args)
|
|
set_property(GLOBAL PROPERTY _qt_ir_unhandled_args "${args}")
|
|
endfunction()
|
|
|
|
# Adds to the unknown command line args.
|
|
function(qt_ir_append_unknown_args args)
|
|
set_property(GLOBAL APPEND PROPERTY _qt_ir_unknown_args ${args})
|
|
endfunction()
|
|
|
|
# Gets the unhandled command line args.
|
|
function(qt_ir_get_unknown_args out_var)
|
|
get_property(args GLOBAL PROPERTY _qt_ir_unknown_args)
|
|
set(${out_var} "${args}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Gets the unsupported options that init-repository.pl supports, but the cmake port does
|
|
# not support.
|
|
function(qt_ir_get_unsupported_options out_var)
|
|
set(${out_var} "${commandline_known_unsupported_options}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Get the value of a command line option.
|
|
function(qt_ir_get_option_value name out_var)
|
|
if(NOT "${commandline_option_${name}_alias}" STREQUAL "")
|
|
set(name "${commandline_option_${name}_alias}")
|
|
endif()
|
|
|
|
get_property(value GLOBAL PROPERTY _qt_ir_input_${name})
|
|
set(${out_var} "${value}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Set the value of a command line option manually.
|
|
function(qt_ir_set_option_value name value)
|
|
if(NOT "${commandline_option_${name}_alias}" STREQUAL "")
|
|
set(name "${commandline_option_${name}_alias}")
|
|
endif()
|
|
|
|
qt_ir_command_line_set_input("${name}" "${value}")
|
|
endfunction()
|
|
|
|
# Get the value of a command line option as a cmakke flag option, to be passed
|
|
# to functions that use cmake_parse_arguments.
|
|
function(qt_ir_get_option_as_cmake_flag_option cli_name cmake_option_name out_var)
|
|
qt_ir_get_option_value("${cli_name}" bool_value)
|
|
set(cmake_option "")
|
|
if(bool_value)
|
|
set(cmake_option "${cmake_option_name}")
|
|
endif()
|
|
set(${out_var} "${cmake_option}" PARENT_SCOPE)
|
|
endfunction()
|