These test helpers are moved to qtbase submodule. Change-Id: If8aa31fe1d9a93f2667249abd90ae9b8cb81d07a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
367 lines
14 KiB
CMake
367 lines
14 KiB
CMake
# Copyright (C) 2024 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
# Includes all helper files for access to necessary functions.
|
|
macro(qt_ir_include_all_helpers)
|
|
include(QtIRCommandLineHelpers)
|
|
include(QtIRGitHelpers)
|
|
include(QtIROptionsHelpers)
|
|
include(QtIRParsingHelpers)
|
|
include(QtIRProcessHelpers)
|
|
include(QtTopLevelHelpers)
|
|
endmacro()
|
|
|
|
# Convenience macro to get the working directory from the arguments passed to
|
|
# cmake_parse_arguments. Saves a few lines and makes reading the code slightly
|
|
# easier.
|
|
macro(qt_ir_get_working_directory_from_arg out_var)
|
|
if(NOT arg_WORKING_DIRECTORY)
|
|
message(FATAL_ERROR "No working directory specified")
|
|
endif()
|
|
set(${out_var} "${arg_WORKING_DIRECTORY}")
|
|
endmacro()
|
|
|
|
# Convenience function to set the variable to the name of cmake_parse_arguments
|
|
# flag option if it is active.
|
|
function(qt_ir_get_cmake_flag flag_name out_var)
|
|
if(arg_${flag_name})
|
|
set(${out_var} "${flag_name}" PARENT_SCOPE)
|
|
else()
|
|
set(${out_var} "" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# There are some init-repository options that we do not want to allow when called from
|
|
# configure. Make sure we error out when they are set by the user.
|
|
function(qt_ir_validate_options_for_configure)
|
|
set(disallowed_options
|
|
# Disallow mirror options, because users should set up a proper git mirror manually,
|
|
# not via configure.
|
|
mirror
|
|
oslo
|
|
berlin
|
|
)
|
|
foreach(disallowed_option IN LISTS disallowed_options)
|
|
qt_ir_get_option_value(${disallowed_option} value)
|
|
if(value)
|
|
set(msg
|
|
"Initialization option '${disallowed_option}' is not supported by configure. "
|
|
"If you think this option should be supported, please let us know at "
|
|
"https://bugreports.qt.io/"
|
|
)
|
|
message(FATAL_ERROR ${msg})
|
|
endif()
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# Handle the case when init-repository is called from the configure script.
|
|
function(qt_ir_handle_called_from_configure top_level_src_path out_var_exit_reason)
|
|
# Nothing special to do if we're not called from configure.
|
|
qt_ir_is_called_from_configure(is_called_from_configure)
|
|
if(NOT is_called_from_configure)
|
|
set(${out_var_exit_reason} FALSE PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
# Check whether qtbase was cloned, if not, tell the user how to initialize
|
|
# the repos as part of the configure script.
|
|
qt_ir_get_option_value(init-submodules init_submodules)
|
|
set(configure_script "${top_level_src_path}/qtbase/configure")
|
|
if(NOT EXISTS "${configure_script}" AND NOT init_submodules)
|
|
set(msg "Oops. It looks like you didn't initialize any submodules yet.\nCall configure "
|
|
"with the -init-submodules option to automatically clone a default set of "
|
|
"submodules before configuring Qt.\nYou can also pass "
|
|
"-submodules submodule2,submodule3 to clone a particular set of submodules "
|
|
"and their dependencies. See ./init-repository --help for more information on values "
|
|
"accepted by --module-subset (which gets its values from -submodules).")
|
|
message(${msg})
|
|
set(${out_var_exit_reason} NEED_INIT_SUBMODULES PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
# Don't do init-repository things when called from configure, qtbase exists and the
|
|
# -init-submodules option is not passed. We assume the repo was already
|
|
# initialized.
|
|
if(NOT init_submodules)
|
|
set(${out_var_exit_reason} ALREADY_INITIALIZED PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
qt_ir_validate_options_for_configure()
|
|
|
|
# -init_submodules implies --force
|
|
qt_ir_set_option_value(force TRUE)
|
|
|
|
set(${out_var_exit_reason} FALSE PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Returns a list of command line arguments with the init-repository specific
|
|
# options removed, which are not recognized by configure.
|
|
# It also handles -submodules values like 'essential', 'existing' and '-qtsvg' and transforms them
|
|
# into the final list of submodules to be included and excluded, which are then translated
|
|
# to configure -submodules and -skip options.
|
|
function(qt_ir_get_args_from_optfile_configure_filtered optfile_path out_var)
|
|
cmake_parse_arguments(arg "ALREADY_INITIALIZED" "" "" ${ARGV})
|
|
|
|
# Get args unknown to init-repository, and pass them to configure as-is.
|
|
qt_ir_get_unknown_args(unknown_args)
|
|
|
|
set(filtered_args ${unknown_args})
|
|
set(extra_configure_args "")
|
|
set(extra_cmake_args "")
|
|
|
|
# If the -submodules or --module-subset options were specified, transform
|
|
# the values into something configure understands and pass them to configure.
|
|
qt_ir_get_option_value(module-subset submodules)
|
|
if(submodules)
|
|
qt_ir_get_top_level_submodules(include_submodules exclude_submodules)
|
|
if(NOT include_submodules AND arg_ALREADY_INITIALIZED)
|
|
string(REPLACE "," ";" include_submodules "${submodules}")
|
|
endif()
|
|
|
|
# qtrepotools is always implicitly cloned, but it doesn't actually
|
|
# have a CMakeLists.txt, so remove it.
|
|
list(REMOVE_ITEM include_submodules "qtrepotools")
|
|
|
|
# Make sure to explicitly pass -DBUILD_<module>=ON, in case they were
|
|
# skipped before, otherwise configure might fail.
|
|
if(include_submodules)
|
|
set(explicit_build_submodules "${include_submodules}")
|
|
list(TRANSFORM explicit_build_submodules PREPEND "-DBUILD_")
|
|
list(TRANSFORM explicit_build_submodules APPEND "=ON")
|
|
list(APPEND extra_cmake_args ${explicit_build_submodules})
|
|
endif()
|
|
|
|
list(JOIN include_submodules "," include_submodules)
|
|
list(JOIN exclude_submodules "," exclude_submodules)
|
|
|
|
# Handle case when the -skip argument is already passed.
|
|
# In that case read the passed values, merge with new ones,
|
|
# remove both the -skip and its values, and re-add it later.
|
|
list(FIND filtered_args "-skip" skip_index)
|
|
if(exclude_submodules AND skip_index GREATER -1)
|
|
list(LENGTH filtered_args filtered_args_length)
|
|
math(EXPR skip_args_index "${skip_index} + 1")
|
|
|
|
if(skip_args_index LESS filtered_args_length)
|
|
list(GET filtered_args "${skip_args_index}" skip_args)
|
|
string(REPLACE "," ";" skip_args "${skip_args}")
|
|
list(APPEND skip_args ${exclude_submodules})
|
|
list(REMOVE_DUPLICATES skip_args)
|
|
list(JOIN skip_args "," exclude_submodules)
|
|
list(REMOVE_AT filtered_args "${skip_args_index}")
|
|
list(REMOVE_AT filtered_args "${skip_index}")
|
|
endif()
|
|
endif()
|
|
|
|
# Handle case when only '-submodules existing' is passed and the
|
|
# subset ends up empty.
|
|
if(include_submodules)
|
|
list(APPEND extra_configure_args "-submodules" "${include_submodules}")
|
|
endif()
|
|
if(exclude_submodules)
|
|
list(APPEND extra_configure_args "-skip" "${exclude_submodules}")
|
|
endif()
|
|
endif()
|
|
|
|
# Insert the extra arguments into the proper positions before and after '--'.
|
|
list(FIND filtered_args "--" cmake_args_index)
|
|
|
|
# -- is not found
|
|
if(cmake_args_index EQUAL -1)
|
|
# Append extra configure args if present
|
|
if(extra_configure_args)
|
|
list(APPEND filtered_args ${extra_configure_args})
|
|
endif()
|
|
# Append extra cmake args if present, but make sure to add -- first at the end
|
|
if(extra_cmake_args)
|
|
list(APPEND filtered_args "--")
|
|
list(APPEND filtered_args ${extra_cmake_args})
|
|
endif()
|
|
else()
|
|
# -- is found, that means we probably have cmake args
|
|
# Insert extra configure args if present, before the -- index.
|
|
if(extra_configure_args)
|
|
list(INSERT filtered_args "${cmake_args_index}" ${extra_configure_args})
|
|
endif()
|
|
# Find the -- index again, because it might have moved
|
|
list(FIND filtered_args "--" cmake_args_index)
|
|
# Compute the index of the argument after the --.
|
|
math(EXPR cmake_args_index "${cmake_args_index} + 1")
|
|
# Insert extra cmake args if present, after the -- index.
|
|
if(extra_cmake_args)
|
|
list(INSERT filtered_args "${cmake_args_index}" ${extra_cmake_args})
|
|
endif()
|
|
endif()
|
|
|
|
# Pass --help if it was requested.
|
|
qt_ir_is_help_requested(show_help)
|
|
if(show_help)
|
|
list(APPEND filtered_args "-help")
|
|
endif()
|
|
|
|
set(${out_var} "${filtered_args}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Checks whether any of the arguments passed on the command line are options
|
|
# that are marked as unsupported in the cmake port of init-repository.
|
|
function(qt_ir_check_if_unsupported_options_used out_var out_var_option_name)
|
|
qt_ir_get_unsupported_options(unsupported_options)
|
|
|
|
set(unsupported_options_used FALSE)
|
|
foreach(unsupported_option IN LISTS unsupported_options)
|
|
qt_ir_get_option_value(${unsupported_option} value)
|
|
if(value)
|
|
set(${out_var_option_name} "${unsupported_option}" PARENT_SCOPE)
|
|
set(unsupported_options_used TRUE)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
set(${out_var} "${unsupported_options_used}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# When an unsupported option is used, show an error message and tell the user
|
|
# to run the perly script manually.
|
|
function(qt_ir_show_error_how_to_run_perl opt_file unsupported_option_name)
|
|
qt_ir_get_raw_args_from_optfile("${opt_file}" args)
|
|
qt_ir_prettify_command_args(args "${args}")
|
|
|
|
set(perl_cmd "perl ./init-repository.pl ${args}")
|
|
|
|
message(FATAL_ERROR
|
|
"Option '${unsupported_option_name}' is not implemented in the cmake "
|
|
"port of init-repository. Please let us know if this option is really "
|
|
"important for you at https://bugreports.qt.io/. Meanwhile, you can "
|
|
"still run the perl script directly. \n ${perl_cmd}")
|
|
endfunction()
|
|
|
|
# Check whether help was requested.
|
|
function(qt_ir_is_help_requested out_var)
|
|
qt_ir_get_option_value(help value)
|
|
set(${out_var} "${value}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Check whether the verbose option was used.
|
|
function(qt_ir_is_verbose out_var)
|
|
qt_ir_get_option_value(verbose value)
|
|
set(${out_var} "${value}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(qt_ir_is_called_from_configure out_var)
|
|
qt_ir_get_option_value(from-configure value)
|
|
set(${out_var} "${value}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Main logic of the script.
|
|
function(qt_ir_run_after_args_parsed top_level_src_path out_var_exit_reason)
|
|
set(${out_var_exit_reason} FALSE PARENT_SCOPE)
|
|
|
|
qt_ir_is_called_from_configure(is_called_from_configure)
|
|
|
|
qt_ir_is_help_requested(show_help)
|
|
if(show_help AND NOT is_called_from_configure)
|
|
qt_ir_show_help()
|
|
set(${out_var_exit_reason} SHOWED_HELP PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
set(working_directory "${top_level_src_path}")
|
|
|
|
qt_ir_handle_if_already_initialized(already_initialized "${working_directory}")
|
|
if(already_initialized)
|
|
set(${out_var_exit_reason} ALREADY_INITIALIZED PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
# This will be used by the module subset processing to determine whether we
|
|
# should re-initialize the previously initialized (existing) subset.
|
|
qt_ir_check_if_already_initialized_cmake_style(is_initialized
|
|
"${working_directory}" FORCE_QUIET)
|
|
set(previously_initialized_option "")
|
|
if(is_initialized)
|
|
set(previously_initialized_option PREVIOUSLY_INITIALIZED)
|
|
endif()
|
|
|
|
|
|
# Ge the name of the qt5 repo (tqtc- or not) and the base url for all other repos
|
|
qt_ir_get_qt5_repo_name_and_base_url(
|
|
OUT_VAR_QT5_REPO_NAME qt5_repo_name
|
|
OUT_VAR_BASE_URL base_url
|
|
WORKING_DIRECTORY "${working_directory}")
|
|
|
|
qt_ir_get_already_initialized_submodules("${prefix}"
|
|
already_initialized_submodules
|
|
"${qt5_repo_name}"
|
|
"${working_directory}")
|
|
|
|
# Get some additional options to pass down.
|
|
qt_ir_get_option_value(alternates alternates)
|
|
qt_ir_get_option_as_cmake_flag_option(branch "CHECKOUT_BRANCH" checkout_branch_option)
|
|
|
|
# The prefix for the cmake-style 'dictionary' that will be used by various functions.
|
|
set(prefix "ir_top")
|
|
|
|
# Initialize and clone the submodules
|
|
qt_ir_handle_init_submodules("${prefix}"
|
|
ALTERNATES "${alternates}"
|
|
ALREADY_INITIALIZED_SUBMODULES "${already_initialized_submodules}"
|
|
BASE_URL "${base_url}"
|
|
PARENT_REPO_BASE_GIT_PATH "${qt5_repo_name}"
|
|
PROCESS_SUBMODULES_FROM_COMMAND_LINE
|
|
WORKING_DIRECTORY "${working_directory}"
|
|
${checkout_branch_option}
|
|
${previously_initialized_option}
|
|
)
|
|
|
|
# Add gerrit remotes.
|
|
qt_ir_add_git_remotes("${qt5_repo_name}" "${working_directory}")
|
|
|
|
# Install commit and other various hooks.
|
|
qt_ir_install_git_hooks(
|
|
PARENT_REPO_BASE_GIT_PATH "${qt5_repo_name}"
|
|
TOP_LEVEL_SRC_PATH "${top_level_src_path}"
|
|
WORKING_DIRECTORY "${working_directory}"
|
|
)
|
|
|
|
# Mark the repo as being initialized.
|
|
qt_ir_set_is_initialized("${working_directory}")
|
|
endfunction()
|
|
|
|
# Entrypoint of the init-repository script.
|
|
function(qt_ir_run_main_script top_level_src_path out_var_exit_reason)
|
|
set(${out_var_exit_reason} FALSE PARENT_SCOPE)
|
|
|
|
# Windows passes backslash paths.
|
|
file(TO_CMAKE_PATH "${top_level_src_path}" top_level_src_path)
|
|
|
|
qt_ir_set_known_command_line_options()
|
|
|
|
# If called from configure, there might be arguments that init-repository doesn't know about
|
|
# because they are meant for configure. In that case ignore unknown arguments.
|
|
qt_ir_get_option_value(from-configure from_configure)
|
|
if(from_configure)
|
|
set(ignore_unknown_args "IGNORE_UNKNOWN_ARGS")
|
|
else()
|
|
set(ignore_unknown_args "")
|
|
endif()
|
|
|
|
qt_ir_process_args_from_optfile("${OPTFILE}" "${ignore_unknown_args}")
|
|
|
|
qt_ir_handle_called_from_configure("${top_level_src_path}" exit_reason)
|
|
if(exit_reason)
|
|
set(${out_var_exit_reason} "${exit_reason}" PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
|
|
qt_ir_check_if_unsupported_options_used(
|
|
unsupported_options_used option_name)
|
|
if(unsupported_options_used)
|
|
qt_ir_show_error_how_to_run_perl("${OPTFILE}" "${option_name}")
|
|
endif()
|
|
|
|
qt_ir_run_after_args_parsed("${top_level_src_path}" exit_reason)
|
|
set(${out_var_exit_reason} "${exit_reason}" PARENT_SCOPE)
|
|
|
|
# TODO: Consider using cmake_language(EXIT <exit-code>) when cmake 3.29 is released.
|
|
endfunction()
|