mirror of
git://code.qt.io/qt/qt5.git
synced 2026-03-31 10:47:07 +08:00
init-repository is now implemented using CMake + .sh / .bat scripts.
The intent behind the change is not to require Perl to checkout and
build Qt, because it can be troublesome to acquire on Windows and it
can also lead to issues during builds due to CMake picking up a Perl
distribution-shipped compiler.
All previous options were ported over like
- module-subset
- alternates
- etc.
A few new options were added:
- --resolve-deps / --no-resolve-deps
- --optional-deps / --no-optional-deps
- --verbose
and some other internal ones for testing reasons.
The new script does automatic resolving of dependencies
based on the depends / recommends keys in .gitmodules unless
--no-resolve-deps is passed.
So if you configure with --module-subset=qtsvg, the script will also
initialize qtbase.
If --no-optional-deps is passed, only required dependencies ('depends'
ky) will be included and optional dependencies ('recommends' key) will
be excluded.
The new script now has a new default behavior when calling
init-repository a second time with --force, without specifying a
--module-subset option. Instead of initializing all submodules, it
will just update the existing / previously initialized submodules.
It also understands a new module-subset keyword "existing", which
expands to the previously initialized submodules, so someone can
initialize an additional submodule by calling
init-repository -f --module-subset=existing,qtsvg
Implementation notes:
The overall code flow is init-repository -> cmake/QtIRScript.cmake
-> qt_ir_run_main_script -> qt_ir_run_after_args_parsed ->
qt_ir_handle_init_submodules (recursive) -> qt_ir_clone_one_submodule
with some bells and whistles on the side.
The command line parsing is an adapted copy of the functions
in qtbase/cmake/QtProcessConfigureArgs.cmake. We can't use those exact
functions because qtbase is not available when init-repository is
initially called, and force cloning qtbase was deemed undesirable.
We also have a new mechanism to detect whether init-repository was
previously called. The perl script used the existence of the qtbase
submodule as the check. In the cmake script, we instead set a custom
marker into the local repo config file.
Otherwise the code logic should be a faithful reimplementation of
init-repository.pl aside from some small things like logging and
progress reporting.
The pre-existing git cloning logic in QtTopLevelHelpers was not used
because it would not be compatible with the alternates option and I
didn't want to accidentally break the pre-existing code. Plus
init-repository is a bit opinionated about how it clones and checks
out repos.
The dependency collection and sorting logic uses the pre-existing code
though.
See follow up commit about implicitly calling init-repository when
qt5/configure is called and the repo was not initialized before.
[ChangeLog][General] init-repository was rewritten using CMake. Perl
is no longer required to initialize the qt5.git super repo.
Task-number: QTBUG-120030
Task-number: QTBUG-122622
Change-Id: Ibc38ab79d3fdedd62111ebbec496eabd64c20d2b
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
159 lines
5.5 KiB
CMake
159 lines
5.5 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()
|
|
|
|
# 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)
|
|
string(REPLACE ";" " " 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()
|
|
|
|
# Main logic of the script.
|
|
function(qt_ir_run_after_args_parsed)
|
|
qt_ir_is_help_requested(show_help)
|
|
if(show_help)
|
|
qt_ir_show_help()
|
|
return()
|
|
endif()
|
|
|
|
set(working_directory "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
|
|
qt_ir_handle_if_already_initialized(should_exit "${working_directory}")
|
|
if(should_exit)
|
|
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}"
|
|
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)
|
|
qt_ir_set_known_command_line_options()
|
|
qt_ir_process_args_from_optfile("${OPTFILE}")
|
|
|
|
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()
|
|
endfunction()
|