CMake: Rewrite init-repository using CMake and .sh / .bat scripts
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>
This commit is contained in:
parent
1971e8075d
commit
29019c9cae
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@ CMakeUserPresets.json
|
||||
build
|
||||
build-*
|
||||
.DS_Store
|
||||
init-repository.opt
|
||||
init-repository.opt.in
|
||||
|
369
cmake/QtIRCommandLineHelpers.cmake
Normal file
369
cmake/QtIRCommandLineHelpers.cmake
Normal file
@ -0,0 +1,369 @@
|
||||
# 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)
|
||||
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
|
||||
#
|
||||
# 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)
|
||||
|
||||
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 "${arg_UNSUPPORTED}")
|
||||
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}
|
||||
)
|
||||
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)
|
||||
set(${out_var} "${args}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Reads the optfile_path, iterates over the given command line arguments,
|
||||
# sets the input for recongized options.
|
||||
#
|
||||
# IGNORE_UNKNOWN_ARGS tells the function not to fail if it encounters an unknown
|
||||
# option, 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()
|
||||
qt_ir_add_error("Invalid command line parameter '${arg}'.")
|
||||
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}'. Ignoring.")
|
||||
continue()
|
||||
endif()
|
||||
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()
|
||||
|
||||
# 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()
|
1113
cmake/QtIRGitHelpers.cmake
Normal file
1113
cmake/QtIRGitHelpers.cmake
Normal file
File diff suppressed because it is too large
Load Diff
132
cmake/QtIRHelp.txt
Normal file
132
cmake/QtIRHelp.txt
Normal file
@ -0,0 +1,132 @@
|
||||
Usage:
|
||||
./init-repository [options]
|
||||
|
||||
This script may be run after an initial `git clone' of the Qt supermodule
|
||||
in order to check out all submodules. It fetches them from canonical URLs
|
||||
inferred from the clone's origin.
|
||||
|
||||
Options:
|
||||
Global options:
|
||||
|
||||
--force, -f
|
||||
Force initialization (even if the submodules are already checked
|
||||
out).
|
||||
|
||||
--force-hooks
|
||||
Force initialization of hooks (even if there are already hooks in
|
||||
checked out submodules).
|
||||
|
||||
--quiet, -q
|
||||
Be quiet. Will exit cleanly if the repository is already
|
||||
initialized.
|
||||
|
||||
--verbose
|
||||
Adds a bit more output when executing processes
|
||||
|
||||
--no-resolve-deps
|
||||
By default, each submodule specified via the module-subset option
|
||||
will have its required and optional dependencies also initialized.
|
||||
This option can be passed to disable automatic initialization of
|
||||
dependencies, so that the exact list passed to module-subset is
|
||||
initialized.
|
||||
|
||||
--no-optional-deps
|
||||
By default, each submodule specified via the module-subset option
|
||||
will have its optional dependencies also initialized.
|
||||
This option can be passed to initialize only required dependencies of
|
||||
the given module-subset.
|
||||
|
||||
Module options:
|
||||
|
||||
--module-subset=<module1>,<module2>...
|
||||
Only initialize the specified subset of modules given as the
|
||||
argument. Specified modules must already exist in .gitmodules. The
|
||||
string "all" results in cloning all known modules. The strings
|
||||
"essential", "addon", "preview", "deprecated", "obsolete",
|
||||
"additionalLibrary", and "ignore" refer to classes of modules
|
||||
identified by "status=" lines in the .gitmodules file.
|
||||
You can use "existing" to to reference already initialized submodules.
|
||||
Additionally, "qtrepotools" is implicitly always added to ensure
|
||||
relevant git commit hooks are available. It can be excluded as described
|
||||
below.
|
||||
You can use "default" in the subset as a short-hand for
|
||||
"essential,addon,preview,deprecated", which corresponds to the set of
|
||||
maintained modules included in standard Qt releases; this is also the
|
||||
default module subset when this option is not given when first running
|
||||
init-repositoy. If init-repository is rerun a second time (with --force)
|
||||
the default is to initialize the "existing" submodules, rather than the
|
||||
default subset. Entries may be prefixed with a dash to exclude them
|
||||
from a bigger set, e.g. "all,-ignore" or "existing,-qttools".
|
||||
|
||||
--no-update
|
||||
Skip the `git submodule update' command.
|
||||
|
||||
--no-fetch
|
||||
Skip the `git fetch' commands. Implied by --no-update.
|
||||
|
||||
--branch
|
||||
Instead of checking out specific SHA1s, check out the submodule
|
||||
branches that correspond with the current supermodule commit. By
|
||||
default, this option will cause local commits in the submodules to
|
||||
be rebased. With --no-update, the branches will be checked out, but
|
||||
their heads will not move.
|
||||
|
||||
--ignore-submodules
|
||||
Set git config to ignore submodules by default when doing operations
|
||||
on the qt5 repo, such as `pull', `fetch', `diff' etc.
|
||||
|
||||
After using this option, pass `--ignore-submodules=none' to git to
|
||||
override it as needed.
|
||||
|
||||
Repository options:
|
||||
|
||||
--berlin
|
||||
Switch to internal URLs and make use of the Berlin git mirrors.
|
||||
(Implies `--mirror').
|
||||
|
||||
--oslo
|
||||
Switch to internal URLs and make use of the Oslo git mirrors.
|
||||
(Implies `--mirror').
|
||||
|
||||
--codereview-username <Gerrit/JIRA username>
|
||||
Specify the user name for the (potentially) writable `gerrit' remote
|
||||
for each module, for use with the Gerrit code review tool.
|
||||
|
||||
If this option is omitted, the gerrit remote is created without a
|
||||
username and port number, and thus relies on a correct SSH
|
||||
configuration.
|
||||
|
||||
--alternates <path to other Qt5 repo>
|
||||
Adds alternates for each submodule to another full qt5 checkout.
|
||||
This makes this qt5 checkout very small, as it will use the object
|
||||
store of the alternates before unique objects are stored in its own
|
||||
object store.
|
||||
|
||||
This option has no effect when using `--no-update'.
|
||||
|
||||
NOTE: This will make this repo dependent on the alternate, which is
|
||||
potentially dangerous! The dependency can be broken by also using
|
||||
the `--copy-objects' option, or by running "git repack -a" in each
|
||||
submodule, where required. Please read the note about the `--shared'
|
||||
option in the documentation of `git clone' for more information.
|
||||
|
||||
--copy-objects
|
||||
When `--alternates' is used, automatically do a "git repack -a" in
|
||||
each submodule after cloning, to ensure that the repositories are
|
||||
independent from the source used as a reference for cloning.
|
||||
|
||||
Note that this negates the disk usage benefits gained from the use
|
||||
of `--alternates'.
|
||||
--mirror <url-base>
|
||||
Uses <url-base> as the base URL for submodule git mirrors.
|
||||
|
||||
For example:
|
||||
|
||||
--mirror user\@machine:/foo/bar/qt/
|
||||
|
||||
...will use the following as a mirror for qtbase:
|
||||
|
||||
user\@machine:/foo/bar/qt/qtbase.git
|
||||
|
||||
The mirror is permitted to contain a subset of the submodules; any
|
||||
missing modules will fall back to the canonical URLs.
|
158
cmake/QtIRHelpers.cmake
Normal file
158
cmake/QtIRHelpers.cmake
Normal file
@ -0,0 +1,158 @@
|
||||
# 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()
|
34
cmake/QtIROptionsHelpers.cmake
Normal file
34
cmake/QtIROptionsHelpers.cmake
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Declare command line options known to init-repository.
|
||||
macro(qt_ir_set_known_command_line_options)
|
||||
# Implemented options
|
||||
|
||||
# Note alternates is a qt specific option name, but it uses
|
||||
# git submodule's --reference option underneath which also implies --shared.
|
||||
# It essentially uses the git object storage of another repo, to avoid
|
||||
# cloning the same objects and thus saving space.
|
||||
qt_ir_commandline_option(alternates TYPE string)
|
||||
|
||||
qt_ir_commandline_option(berlin TYPE boolean)
|
||||
qt_ir_commandline_option(branch TYPE boolean)
|
||||
qt_ir_commandline_option(codereview-username TYPE string)
|
||||
qt_ir_commandline_option(copy-objects TYPE boolean)
|
||||
qt_ir_commandline_option(fetch TYPE boolean DEFAULT_VALUE yes)
|
||||
qt_ir_commandline_option(force SHORT_NAME f TYPE boolean)
|
||||
qt_ir_commandline_option(force-hooks TYPE boolean)
|
||||
qt_ir_commandline_option(help SHORT_NAME h TYPE boolean)
|
||||
qt_ir_commandline_option(ignore-submodules TYPE boolean)
|
||||
qt_ir_commandline_option(mirror TYPE string)
|
||||
qt_ir_commandline_option(module-subset TYPE string)
|
||||
qt_ir_commandline_option(optional-deps TYPE boolean DEFAULT_VALUE yes)
|
||||
qt_ir_commandline_option(oslo TYPE boolean)
|
||||
qt_ir_commandline_option(perl-identical-output TYPE boolean)
|
||||
qt_ir_commandline_option(perl-init-check TYPE boolean)
|
||||
qt_ir_commandline_option(quiet SHORT_NAME q TYPE boolean)
|
||||
qt_ir_commandline_option(resolve-deps TYPE boolean DEFAULT_VALUE yes)
|
||||
qt_ir_commandline_option(update TYPE boolean DEFAULT_VALUE yes)
|
||||
qt_ir_commandline_option(verbose TYPE boolean)
|
||||
endmacro()
|
||||
|
237
cmake/QtIRParsingHelpers.cmake
Normal file
237
cmake/QtIRParsingHelpers.cmake
Normal file
@ -0,0 +1,237 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Retrieves the contents of either .git/config or .gitmodules files for further parsing.
|
||||
function(qt_ir_get_git_config_contents out_var)
|
||||
set(options
|
||||
READ_GITMODULES
|
||||
READ_GIT_CONFIG
|
||||
READ_GIT_CONFIG_LOCAL
|
||||
)
|
||||
set(oneValueArgs
|
||||
WORKING_DIRECTORY
|
||||
)
|
||||
set(multiValueArgs "")
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(arg_READ_GITMODULES)
|
||||
set(args -f .gitmodules)
|
||||
set(file_message ".gitmodules")
|
||||
elseif(arg_READ_GIT_CONFIG)
|
||||
set(args "")
|
||||
set(file_message ".git/config")
|
||||
elseif(arg_READ_GIT_CONFIG_LOCAL)
|
||||
set(args "--local")
|
||||
set(file_message ".local .git/config")
|
||||
else()
|
||||
message(FATAL_ERROR "qt_ir_get_git_config_contents: No option specified")
|
||||
endif()
|
||||
|
||||
qt_ir_get_working_directory_from_arg(working_directory)
|
||||
|
||||
qt_ir_execute_process_and_log_and_handle_error(
|
||||
FORCE_QUIET
|
||||
COMMAND_ARGS git config --list ${args}
|
||||
OUT_OUTPUT_VAR git_output
|
||||
WORKING_DIRECTORY "${working_directory}"
|
||||
ERROR_MESSAGE "Failed to get ${file_message} contents for parsing")
|
||||
|
||||
string(STRIP "${git_output}" git_output)
|
||||
set(${out_var} "${git_output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Checks whether the given url has a scheme like https:// or is just a
|
||||
# relative path.
|
||||
function(qt_ir_has_url_scheme url out_var)
|
||||
string(REGEX MATCH "^[a-z][a-z0-9+\-.]*://" has_url_scheme "${url}")
|
||||
|
||||
if(has_url_scheme)
|
||||
set(${out_var} TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(${out_var} FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Parses a key-value line from a .git/config or .gitmodules file
|
||||
macro(qt_ir_parse_git_key_value)
|
||||
string(REGEX REPLACE "^submodule\\.([^.=]+)\\.([^.=]+)=(.*)$" "\\1;\\2;\\3"
|
||||
parsed_line "${line}")
|
||||
|
||||
list(LENGTH parsed_line parsed_line_length)
|
||||
set(submodule_name "")
|
||||
set(key "")
|
||||
set(value "")
|
||||
if(parsed_line_length EQUAL 3)
|
||||
list(GET parsed_line 0 submodule_name)
|
||||
list(GET parsed_line 1 key)
|
||||
list(GET parsed_line 2 value)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Parses a url line from a .gitmodules file
|
||||
# e.g. line - 'submodule.qtbase.url=../qtbase.git'
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# submodule_name
|
||||
# submodule name, the key in 'submodule.${submodule_name}.url'
|
||||
# e.g. 'qtbase'
|
||||
# url_value
|
||||
# the url where to clone a repo from
|
||||
# in perl script it was called $base
|
||||
# e.g. '../qtbase.git', 'https://code.qt.io/playground/qlitehtml.git'
|
||||
# parent_repo_base_git_path
|
||||
# the base git path of the parent of the submodule
|
||||
# it is either a relative dir or a full url
|
||||
# in the perl script it was called $my_repo_base,
|
||||
# it was passed as first arg to git_clone_all_submodules,
|
||||
# it was passed the value of $subbases{$module} when doing recursive submodule cloning
|
||||
# e.g. 'qt5', 'tqtc-qt5', 'qtdeclarative.git', 'https://code.qt.io/playground/qlitehtml.git'
|
||||
#
|
||||
# Outputs
|
||||
#
|
||||
# ${out_var_prefix}_${submodule_name}_url
|
||||
# just the value of ${url_value}
|
||||
# ${out_var_prefix}_${submodule_name}_base_git_path
|
||||
# the whole url if it has a scheme, otherwise it's the value of
|
||||
# ${url_value} relative to ${parent_repo_base_git_path}, so all the ../ are collapsed
|
||||
# e.g. 'qtdeclarative.git'
|
||||
# 'https://code.qt.io/playground/qlitehtml.git',
|
||||
macro(qt_ir_parse_git_url_key out_var_prefix submodule_name url_value parent_repo_base_git_path)
|
||||
qt_ir_has_url_scheme("${url_value}" has_url_scheme)
|
||||
if(NOT has_url_scheme)
|
||||
set(base_git_path "${parent_repo_base_git_path}/${url_value}")
|
||||
|
||||
# The exact code perl code was while ($base =~ s,(?!\.\./)[^/]+/\.\./,,g) {}
|
||||
# That got rid of ../ and ../../ in the path, but it broke down
|
||||
# when more than two ../ were present.
|
||||
# We just use ABSOLUTE to resolve the path and get rid of all ../
|
||||
# Note the empty BASE_DIR is important, otherwise the path is relative to
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}.
|
||||
get_filename_component(base_git_path "${base_git_path}" ABSOLUTE BASE_DIR "")
|
||||
else()
|
||||
set(base_git_path "${url_value}")
|
||||
endif()
|
||||
|
||||
set(${out_var_prefix}_${submodule_name}_url "${url_value}" PARENT_SCOPE)
|
||||
set(${out_var_prefix}_${submodule_name}_base_git_path "${base_git_path}" PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
# Parses a .git/config or .gitmodules file contents and sets variables for each submodule
|
||||
# starting with ${out_var_prefix}_
|
||||
# These include:
|
||||
# ${out_var_prefix}_${submodule_name}_path
|
||||
# the path to the submodule relative to the parent repo
|
||||
# ${out_var_prefix}_${submodule_name}_branch
|
||||
# the branch that should be checked out when the branch option is used
|
||||
# ${out_var_prefix}_${submodule_name}_url
|
||||
# the url key as encountered in the config
|
||||
# ${out_var_prefix}_${submodule_name}_base_git_path
|
||||
# the git base path of the submodule, either a full url or a relative path
|
||||
# ${out_var_prefix}_${submodule_name}_update
|
||||
# the status of the submodule, can be 'none'
|
||||
# ${out_var_prefix}_${submodule_name}_status
|
||||
# the status of the submodule, can be 'essential', 'addon', etc
|
||||
# ${out_var_prefix}_${submodule_name}_depends
|
||||
# the list of submodules that this submodule depends on
|
||||
# ${out_var_prefix}_${submodule_name}_recommends
|
||||
# the list of submodules that this submodule recommends to be used with
|
||||
# ${out_var_prefix}_submodules
|
||||
# a list of all known submodule names encountered in the file
|
||||
# ${out_var_prefix}_submodules_to_remove
|
||||
# a list of all submodules to remove due to update == 'none'
|
||||
# ${out_var_prefix}_statuses to
|
||||
# a list of all known submodule statuses like 'essential', 'addon', etc
|
||||
# ${out_var_prefix}_status_${status}_submodules
|
||||
# a list of all submodules with the specific status
|
||||
function(qt_ir_parse_git_config_file_contents out_var_prefix)
|
||||
set(options
|
||||
READ_GITMODULES
|
||||
READ_GIT_CONFIG
|
||||
READ_GIT_CONFIG_LOCAL
|
||||
)
|
||||
set(oneValueArgs
|
||||
PARENT_REPO_BASE_GIT_PATH
|
||||
WORKING_DIRECTORY
|
||||
)
|
||||
set(multiValueArgs "")
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
qt_ir_get_working_directory_from_arg(working_directory)
|
||||
|
||||
if(NOT arg_PARENT_REPO_BASE_GIT_PATH)
|
||||
message(FATAL_ERROR
|
||||
"qt_ir_parse_git_config_file_contents: No base PARENT_REPO_BASE_GIT_PATH specified")
|
||||
endif()
|
||||
set(parent_repo_base_git_path "${arg_PARENT_REPO_BASE_GIT_PATH}")
|
||||
|
||||
if(arg_READ_GITMODULES)
|
||||
set(read_git_config READ_GITMODULES)
|
||||
elseif(arg_READ_GIT_CONFIG)
|
||||
set(read_git_config READ_GIT_CONFIG)
|
||||
elseif(arg_READ_GIT_CONFIG_LOCAL)
|
||||
set(read_git_config READ_GIT_CONFIG_LOCAL)
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"qt_ir_parse_gitmodules_file_contents: No valid git config file specified")
|
||||
endif()
|
||||
|
||||
qt_ir_get_git_config_contents(contents
|
||||
${read_git_config}
|
||||
WORKING_DIRECTORY "${working_directory}"
|
||||
)
|
||||
string(REPLACE "\n" ";" lines "${contents}")
|
||||
|
||||
set(known_submodules "")
|
||||
set(statuses "")
|
||||
set(submodules_to_remove "")
|
||||
|
||||
foreach(line IN LISTS lines)
|
||||
qt_ir_parse_git_key_value()
|
||||
if(NOT submodule_name OR NOT key OR value STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
list(APPEND known_submodules "${submodule_name}")
|
||||
|
||||
if(key STREQUAL "path")
|
||||
set(${out_var_prefix}_${submodule_name}_path "${value}" PARENT_SCOPE)
|
||||
elseif(key STREQUAL "branch")
|
||||
set(${out_var_prefix}_${submodule_name}_branch "${value}" PARENT_SCOPE)
|
||||
elseif(key STREQUAL "url")
|
||||
qt_ir_parse_git_url_key(
|
||||
"${out_var_prefix}" "${submodule_name}" "${value}" "${parent_repo_base_git_path}")
|
||||
elseif(key STREQUAL "update")
|
||||
# Some repo submodules had a update = none key in their .gitmodules
|
||||
# in which case we're supposed to skip initialzing those submodules,
|
||||
# which the perl script did by adding -${submodule_name} to the subset.
|
||||
# See qtdeclarative Change-Id: I633404f1c00d83dcbdca06a1d287623190323028
|
||||
set(${out_var_prefix}_${submodule_name}_update "${value}" PARENT_SCOPE)
|
||||
if(value STREQUAL "none")
|
||||
list(APPEND submodules_to_remove "-${submodule_name}")
|
||||
endif()
|
||||
elseif(key STREQUAL "status")
|
||||
set(status_submodules "${${out_var_prefix}_status_${value}_submodules}")
|
||||
list(APPEND status_submodules "${submodule_name}")
|
||||
list(REMOVE_DUPLICATES status_submodules)
|
||||
list(APPEND statuses "${value}")
|
||||
|
||||
set(${out_var_prefix}_status_${value}_submodules "${status_submodules}")
|
||||
set(${out_var_prefix}_status_${value}_submodules "${status_submodules}" PARENT_SCOPE)
|
||||
set(${out_var_prefix}_${submodule_name}_status "${value}" PARENT_SCOPE)
|
||||
elseif(key STREQUAL "depends")
|
||||
string(REPLACE " " ";" value "${value}")
|
||||
set(${out_var_prefix}_${submodule_name}_depends "${value}" PARENT_SCOPE)
|
||||
elseif(key STREQUAL "recommends")
|
||||
string(REPLACE " " ";" value "${value}")
|
||||
set(${out_var_prefix}_${submodule_name}_recommends "${value}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES known_submodules)
|
||||
list(REMOVE_DUPLICATES submodules_to_remove)
|
||||
list(REMOVE_DUPLICATES statuses)
|
||||
set(${out_var_prefix}_submodules "${known_submodules}" PARENT_SCOPE)
|
||||
set(${out_var_prefix}_submodules_to_remove "${submodules_to_remove}" PARENT_SCOPE)
|
||||
set(${out_var_prefix}_statuses "${statuses}" PARENT_SCOPE)
|
||||
endfunction()
|
165
cmake/QtIRProcessHelpers.cmake
Normal file
165
cmake/QtIRProcessHelpers.cmake
Normal file
@ -0,0 +1,165 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# A low-level execute_process wrapper that can be used to execute a single command
|
||||
# while controlling the verbosity and error handling.
|
||||
function(qt_ir_execute_process)
|
||||
set(options
|
||||
QUIET
|
||||
)
|
||||
set(oneValueArgs
|
||||
WORKING_DIRECTORY
|
||||
OUT_RESULT_VAR
|
||||
OUT_OUTPUT_VAR
|
||||
OUT_ERROR_VAR
|
||||
)
|
||||
set(multiValueArgs
|
||||
COMMAND_ARGS
|
||||
EP_EXTRA_ARGS
|
||||
)
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT arg_COMMAND_ARGS)
|
||||
message(FATAL_ERROR "Missing arguments to qt_ir_execute_process")
|
||||
endif()
|
||||
|
||||
if(arg_WORKING_DIRECTORY)
|
||||
set(working_dir_value "${arg_WORKING_DIRECTORY}")
|
||||
else()
|
||||
set(working_dir_value ".")
|
||||
endif()
|
||||
set(working_dir WORKING_DIRECTORY "${working_dir_value}")
|
||||
|
||||
set(result_variable "")
|
||||
if(arg_OUT_RESULT_VAR)
|
||||
set(result_variable RESULT_VARIABLE proc_result)
|
||||
endif()
|
||||
|
||||
set(swallow_output "")
|
||||
if(arg_OUT_OUTPUT_VAR OR arg_QUIET)
|
||||
list(APPEND swallow_output OUTPUT_VARIABLE proc_output)
|
||||
endif()
|
||||
if(arg_OUT_ERROR_VAR OR arg_QUIET)
|
||||
list(APPEND swallow_output ERROR_VARIABLE proc_error)
|
||||
endif()
|
||||
if(NOT arg_QUIET)
|
||||
set(working_dir_message "")
|
||||
|
||||
qt_ir_is_verbose(verbose)
|
||||
if(verbose)
|
||||
set(working_dir_message " current working dir: ")
|
||||
if(NOT working_dir_value STREQUAL ".")
|
||||
string(APPEND working_dir_message "${working_dir_value}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" " " command_args_string "${arg_COMMAND_ARGS}")
|
||||
message("+ ${command_args_string}${working_dir_message}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${arg_COMMAND_ARGS}
|
||||
${working_dir}
|
||||
${result_variable}
|
||||
${swallow_output}
|
||||
${arg_EP_EXTRA_ARGS}
|
||||
)
|
||||
|
||||
if(arg_OUT_RESULT_VAR)
|
||||
set(${arg_OUT_RESULT_VAR} "${proc_result}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_OUTPUT_VAR)
|
||||
set(${arg_OUT_OUTPUT_VAR} "${proc_output}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_ERROR_VAR)
|
||||
set(${arg_OUT_ERROR_VAR} "${proc_error}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# A higher level execute_process wrapper that can be used to execute a single command
|
||||
# that is a bit more opinionated and expects options related to init-repository
|
||||
# functionality.
|
||||
# It handles queietness, error handling and logging.
|
||||
# It also allows for slightly more compact syntax for calling processes.
|
||||
function(qt_ir_execute_process_and_log_and_handle_error)
|
||||
set(options
|
||||
NO_HANDLE_ERROR
|
||||
FORCE_VERBOSE
|
||||
FORCE_QUIET
|
||||
)
|
||||
set(oneValueArgs
|
||||
WORKING_DIRECTORY
|
||||
OUT_RESULT_VAR
|
||||
OUT_OUTPUT_VAR
|
||||
OUT_ERROR_VAR
|
||||
ERROR_MESSAGE
|
||||
)
|
||||
set(multiValueArgs
|
||||
COMMAND_ARGS
|
||||
EP_EXTRA_ARGS
|
||||
)
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
qt_ir_get_option_value(quiet quiet)
|
||||
set(quiet_option "")
|
||||
if((quiet OR arg_FORCE_QUIET) AND NOT arg_FORCE_VERBOSE)
|
||||
set(quiet_option "QUIET")
|
||||
endif()
|
||||
|
||||
set(working_dir "")
|
||||
if(arg_WORKING_DIRECTORY)
|
||||
set(working_dir WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
set(extra_args "")
|
||||
if(arg_EP_EXTRA_ARGS)
|
||||
set(extra_args EP_EXTRA_ARGS "${arg_EP_EXTRA_ARGS}")
|
||||
endif()
|
||||
|
||||
set(out_output_var "")
|
||||
if(arg_OUT_OUTPUT_VAR OR quiet)
|
||||
set(out_output_var OUT_OUTPUT_VAR proc_output)
|
||||
endif()
|
||||
|
||||
set(out_error_var "")
|
||||
if(arg_OUT_ERROR_VAR OR quiet)
|
||||
set(out_error_var OUT_ERROR_VAR proc_error)
|
||||
endif()
|
||||
|
||||
qt_ir_execute_process(
|
||||
${quiet_option}
|
||||
COMMAND_ARGS ${arg_COMMAND_ARGS}
|
||||
OUT_RESULT_VAR proc_result
|
||||
${extra_args}
|
||||
${working_dir}
|
||||
${out_output_var}
|
||||
${out_error_var}
|
||||
)
|
||||
|
||||
if(NOT proc_result EQUAL 0 AND NOT arg_NO_HANDLE_ERROR)
|
||||
set(error_message "")
|
||||
if(arg_ERROR_MESSAGE)
|
||||
set(error_message "${arg_ERROR_MESSAGE}\n")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" " " cmd "${arg_COMMAND_ARGS}")
|
||||
string(APPEND error_message "${cmd} exited with status: ${proc_result}\n")
|
||||
if(proc_output)
|
||||
string(APPEND error_message "stdout: ${proc_output}\n")
|
||||
endif()
|
||||
if(proc_error)
|
||||
string(APPEND error_message "stderr: ${proc_error}\n")
|
||||
endif()
|
||||
message(FATAL_ERROR "${error_message}")
|
||||
endif()
|
||||
|
||||
if(arg_OUT_RESULT_VAR)
|
||||
set(${arg_OUT_RESULT_VAR} "${proc_result}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_OUTPUT_VAR)
|
||||
set(${arg_OUT_OUTPUT_VAR} "${proc_output}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_ERROR_VAR)
|
||||
set(${arg_OUT_ERROR_VAR} "${proc_error}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
17
cmake/QtIRScript.cmake
Normal file
17
cmake/QtIRScript.cmake
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# Sets up the include paths for all the helpers init-repository uses.
|
||||
macro(qt_ir_setup_include_paths)
|
||||
list(APPEND CMAKE_MODULE_PATH
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/3rdparty/cmake"
|
||||
)
|
||||
include(QtIRHelpers)
|
||||
endmacro()
|
||||
|
||||
qt_ir_setup_include_paths()
|
||||
qt_ir_include_all_helpers()
|
||||
qt_ir_run_main_script()
|
@ -1,3 +1,6 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Populates $out_module_list with all subdirectories that have a CMakeLists.txt file
|
||||
function(qt_internal_find_modules out_module_list)
|
||||
set(module_list "")
|
||||
@ -15,7 +18,7 @@ endfunction()
|
||||
# poor man's yaml parser, populating $out_dependencies with all dependencies
|
||||
# in the $depends_file
|
||||
# Each entry will be in the format dependency/sha1/required
|
||||
function(qt_internal_parse_dependencies depends_file out_dependencies)
|
||||
function(qt_internal_parse_dependencies_yaml depends_file out_dependencies)
|
||||
file(STRINGS "${depends_file}" lines)
|
||||
set(eof_marker "---EOF---")
|
||||
list(APPEND lines "${eof_marker}")
|
||||
@ -48,7 +51,7 @@ function(qt_internal_parse_dependencies depends_file out_dependencies)
|
||||
endif()
|
||||
endforeach()
|
||||
message(DEBUG
|
||||
"qt_internal_parse_dependencies for ${depends_file}\n dependencies: ${dependencies}")
|
||||
"qt_internal_parse_dependencies_yaml for ${depends_file}\n dependencies: ${dependencies}")
|
||||
set(${out_dependencies} "${dependencies}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@ -99,8 +102,22 @@ endfunction()
|
||||
# Keyword arguments:
|
||||
#
|
||||
# PARSED_DEPENDENCIES is a list of dependencies of module in the format that
|
||||
# qt_internal_parse_dependencies returns. If this argument is not provided, dependencies.yaml of the
|
||||
# module is parsed.
|
||||
# qt_internal_parse_dependencies_yaml returns.
|
||||
# If this argument is not provided, either a module's dependencies.yaml or .gitmodules file is
|
||||
# used as the source of dependencies, depending on whether PARSE_GITMODULES option is enabled.
|
||||
#
|
||||
# PARSE_GITMODULES is a boolean that controls whether the .gitmodules or the dependencies.yaml
|
||||
# file of the repo are used for extracting dependencies. Defaults to FALSE, so uses
|
||||
# dependencies.yaml by default.
|
||||
#
|
||||
# EXCLUDE_OPTIONAL_DEPS is a boolean that controls whether optional dependencies are excluded from
|
||||
# the final result.
|
||||
#
|
||||
# GITMODULES_PREFIX_VAR is the prefix of all the variables containing dependencies for the
|
||||
# PARSE_GITMODULES mode.
|
||||
# The function expects the following variables to be set in the parent scope
|
||||
# ${arg_GITMODULES_PREFIX_VAR}_${submodule_name}_depends
|
||||
# ${arg_GITMODULES_PREFIX_VAR}_${submodule_name}_recommends
|
||||
#
|
||||
# IN_RECURSION is an internal option that is set when the function is in recursion.
|
||||
#
|
||||
@ -112,8 +129,9 @@ endfunction()
|
||||
# NORMALIZE_REPO_NAME_IF_NEEDED Will remove 'tqtc-' from the beginning of submodule dependencies
|
||||
# if a tqtc- named directory does not exist.
|
||||
function(qt_internal_resolve_module_dependencies module out_ordered out_revisions)
|
||||
set(options IN_RECURSION NORMALIZE_REPO_NAME_IF_NEEDED)
|
||||
set(oneValueArgs REVISION SKIPPED_VAR)
|
||||
set(options IN_RECURSION NORMALIZE_REPO_NAME_IF_NEEDED PARSE_GITMODULES
|
||||
EXCLUDE_OPTIONAL_DEPS)
|
||||
set(oneValueArgs REVISION SKIPPED_VAR GITMODULES_PREFIX_VAR)
|
||||
set(multiValueArgs PARSED_DEPENDENCIES)
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
@ -141,10 +159,42 @@ function(qt_internal_resolve_module_dependencies module out_ordered out_revision
|
||||
if(DEFINED arg_PARSED_DEPENDENCIES)
|
||||
set(dependencies "${arg_PARSED_DEPENDENCIES}")
|
||||
else()
|
||||
set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
|
||||
set(dependencies "")
|
||||
if(EXISTS "${depends_file}")
|
||||
qt_internal_parse_dependencies("${depends_file}" dependencies)
|
||||
|
||||
if(NOT arg_PARSE_GITMODULES)
|
||||
set(depends_file "${CMAKE_CURRENT_SOURCE_DIR}/${module}/dependencies.yaml")
|
||||
if(EXISTS "${depends_file}")
|
||||
qt_internal_parse_dependencies_yaml("${depends_file}" dependencies)
|
||||
|
||||
if(arg_EXCLUDE_OPTIONAL_DEPS)
|
||||
set(filtered_dependencies "")
|
||||
foreach(dependency IN LISTS dependencies)
|
||||
string(REPLACE "/" ";" dependency_split "${dependency}")
|
||||
list(GET dependency_split 2 required)
|
||||
if(required)
|
||||
list(APPEND filtered_dependencies "${dependency}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(dependencies "${filtered_dependencies}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(depends "${${arg_GITMODULES_PREFIX_VAR}_${dependency}_depends}")
|
||||
foreach(dependency IN LISTS depends)
|
||||
if(dependency)
|
||||
# The HEAD value is not really used, but we need to add something.
|
||||
list(APPEND dependencies "${dependency}/HEAD/TRUE")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(recommends "${${arg_GITMODULES_PREFIX_VAR}_${dependency}_recommends}")
|
||||
if(NOT arg_EXCLUDE_OPTIONAL_DEPS)
|
||||
foreach(dependency IN LISTS recommends)
|
||||
if(dependency)
|
||||
list(APPEND dependencies "${dependency}/HEAD/FALSE")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -171,11 +221,24 @@ function(qt_internal_resolve_module_dependencies module out_ordered out_revision
|
||||
set_property(GLOBAL APPEND PROPERTY QT_REQUIRED_DEPS_FOR_${module} ${dependency})
|
||||
endif()
|
||||
|
||||
set(parse_gitmodules "")
|
||||
if(arg_PARSE_GITMODULES)
|
||||
set(parse_gitmodules "PARSE_GITMODULES")
|
||||
endif()
|
||||
|
||||
set(exclude_optional_deps "")
|
||||
if(arg_EXCLUDE_OPTIONAL_DEPS)
|
||||
set(exclude_optional_deps "EXCLUDE_OPTIONAL_DEPS")
|
||||
endif()
|
||||
|
||||
qt_internal_resolve_module_dependencies(${dependency} dep_ordered dep_revisions
|
||||
REVISION "${revision}"
|
||||
SKIPPED_VAR skipped
|
||||
IN_RECURSION
|
||||
${normalize_arg}
|
||||
${parse_gitmodules}
|
||||
${exclude_optional_deps}
|
||||
GITMODULES_PREFIX_VAR ${arg_GITMODULES_PREFIX_VAR}
|
||||
)
|
||||
if(NOT skipped)
|
||||
list(APPEND ordered ${dep_ordered})
|
||||
@ -197,12 +260,30 @@ endfunction()
|
||||
# Arguments:
|
||||
# modules is the initial list of repos.
|
||||
# out_all_ordered is the variable name where the result is stored.
|
||||
# PARSE_GITMODULES and GITMODULES_PREFIX_VAR are keyowrd arguments that change the
|
||||
# source of dependencies parsing from dependencies.yaml to .gitmodules.
|
||||
# EXCLUDE_OPTIONAL_DEPS is a keyword argument that excludes optional dependencies from the result.
|
||||
# See qt_internal_resolve_module_dependencies for details.
|
||||
#
|
||||
# See qt_internal_resolve_module_dependencies for side effects.
|
||||
function(qt_internal_sort_module_dependencies modules out_all_ordered)
|
||||
set(options PARSE_GITMODULES EXCLUDE_OPTIONAL_DEPS)
|
||||
set(oneValueArgs GITMODULES_PREFIX_VAR)
|
||||
set(multiValueArgs "")
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
set(parse_gitmodules "")
|
||||
if(arg_PARSE_GITMODULES)
|
||||
set(parse_gitmodules "PARSE_GITMODULES")
|
||||
endif()
|
||||
|
||||
set(exclude_optional_deps "")
|
||||
if(arg_EXCLUDE_OPTIONAL_DEPS)
|
||||
set(exclude_optional_deps "EXCLUDE_OPTIONAL_DEPS")
|
||||
endif()
|
||||
|
||||
# Create a fake repository "all_selected_repos" that has all repositories from the input as
|
||||
# required dependency. The format must match what qt_internal_parse_dependencies produces.
|
||||
# required dependency. The format must match what qt_internal_parse_dependencies_yaml produces.
|
||||
set(all_selected_repos_as_parsed_dependencies)
|
||||
foreach(module IN LISTS modules)
|
||||
list(APPEND all_selected_repos_as_parsed_dependencies "${module}/HEAD/FALSE")
|
||||
@ -211,6 +292,9 @@ function(qt_internal_sort_module_dependencies modules out_all_ordered)
|
||||
qt_internal_resolve_module_dependencies(all_selected_repos ordered unused_revisions
|
||||
PARSED_DEPENDENCIES ${all_selected_repos_as_parsed_dependencies}
|
||||
NORMALIZE_REPO_NAME_IF_NEEDED
|
||||
${exclude_optional_deps}
|
||||
${parse_gitmodules}
|
||||
GITMODULES_PREFIX_VAR ${arg_GITMODULES_PREFIX_VAR}
|
||||
)
|
||||
|
||||
# Drop "all_selected_repos" from the output. It depends on all selected repos, thus it must be
|
||||
|
92
cmake/QtWriteArgsFile.cmake
Normal file
92
cmake/QtWriteArgsFile.cmake
Normal file
@ -0,0 +1,92 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# This script writes its arguments to the file determined by OUT_FILE.
|
||||
# Each argument appears on a separate line.
|
||||
# This is used for writing the init-repository.opt file.
|
||||
#
|
||||
# This script takes the following arguments:
|
||||
# IN_FILE: The input file. The whole command line as one string, or one argument per line.
|
||||
# REDO_FILE: A file containing extra commands to be joined with IN_FILE.
|
||||
# OUT_FILE: The output file. One argument per line.
|
||||
# SKIP_ARGS: Number of arguments to skip from the front of the arguments list.
|
||||
# IGNORE_ARGS: List of arguments to be ignored, i.e. that are not written.
|
||||
#
|
||||
# If the REDO_FILE is given, its parameters will be merged with IN_FILE parameters
|
||||
# and be written into the OUT_FILE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# Read arguments from IN_FILE and separate them.
|
||||
file(READ "${IN_FILE}" raw_args)
|
||||
# To catch cases where the path ends with an `\`, e.g., `-prefix "C:\Path\"`
|
||||
string(REPLACE "\\\"" "\"" raw_args "${raw_args}")
|
||||
string(REPLACE ";" "[[;]]" raw_args "${raw_args}")
|
||||
|
||||
separate_arguments(args NATIVE_COMMAND "${raw_args}")
|
||||
|
||||
string(REPLACE "\;" ";" args "${args}")
|
||||
string(REPLACE "[[;]]" "\;" args "${args}")
|
||||
|
||||
if(DEFINED REDO_FILE)
|
||||
file(READ "${REDO_FILE}" raw_redo_args)
|
||||
separate_arguments(redo_args NATIVE_COMMAND "${raw_redo_args}")
|
||||
|
||||
if(args)
|
||||
list(FIND args "--" args_ddash_loc)
|
||||
list(FIND redo_args "--" redo_ddash_loc)
|
||||
if("${redo_ddash_loc}" STREQUAL "-1")
|
||||
if("${args_ddash_loc}" STREQUAL "-1")
|
||||
list(LENGTH args args_ddash_loc)
|
||||
endif()
|
||||
# Avoid adding an empty line for an empty -redo
|
||||
if(NOT "${redo_args}" STREQUAL "")
|
||||
list(INSERT args ${args_ddash_loc} "${redo_args}")
|
||||
endif()
|
||||
else()
|
||||
# Handling redo's configure options
|
||||
list(SUBLIST redo_args 0 ${redo_ddash_loc} redo_config_args)
|
||||
if(redo_config_args)
|
||||
if("${args_ddash_loc}" STREQUAL "-1")
|
||||
list(APPEND args "${redo_config_args}")
|
||||
else()
|
||||
list(INSERT args ${args_ddash_loc} "${redo_config_args}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Handling redo's CMake options
|
||||
list(LENGTH redo_args redo_args_len)
|
||||
math(EXPR redo_ddash_loc "${redo_ddash_loc} + 1")
|
||||
# Catch an unlikely case of -redo being called with an empty --, ie., `-redo --`
|
||||
if(NOT ${redo_ddash_loc} STREQUAL ${redo_args_len})
|
||||
list(SUBLIST redo_args ${redo_ddash_loc} -1 redo_cmake_args)
|
||||
endif()
|
||||
|
||||
if(DEFINED redo_cmake_args)
|
||||
if("${args_ddash_loc}" STREQUAL "-1")
|
||||
list(APPEND args "--")
|
||||
endif()
|
||||
list(APPEND args "${redo_cmake_args}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
list(APPEND args "${redo_args}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Skip arguments if requested
|
||||
if(DEFINED SKIP_ARGS)
|
||||
foreach(i RANGE 1 ${SKIP_ARGS})
|
||||
list(POP_FRONT args)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Write config.opt
|
||||
set(content "")
|
||||
foreach(arg IN LISTS args)
|
||||
if(NOT arg IN_LIST IGNORE_ARGS)
|
||||
string(APPEND content "${arg}\n")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(WRITE "${OUT_FILE}" "${content}")
|
24
init-repository
Executable file
24
init-repository
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
set -eu
|
||||
|
||||
script_dir_path=`dirname $0`
|
||||
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`
|
||||
|
||||
optfile=init-repository.opt
|
||||
opttmpfile=init-repository.opt.in
|
||||
|
||||
# Posix compatible way to truncate file
|
||||
: > "$optfile"
|
||||
: > "$opttmpfile"
|
||||
|
||||
# For consistency, use QtWriteArgsFile.cmake to write the optfile like we do on Windows.
|
||||
# We do the same with the configure script in qtbase.
|
||||
for arg in "$@"; do echo \"$arg\" >> "$opttmpfile"; done
|
||||
|
||||
cmake -DIN_FILE="${opttmpfile}" -DOUT_FILE="${optfile}" -P "${script_dir_path}/cmake/QtWriteArgsFile.cmake"
|
||||
|
||||
cmake_script_path="$script_dir_path/cmake/QtIRScript.cmake"
|
||||
exec cmake -DOPTFILE="${optfile}" -P "$cmake_script_path"
|
23
init-repository.bat
Normal file
23
init-repository.bat
Normal file
@ -0,0 +1,23 @@
|
||||
:: Copyright (C) 2024 The Qt Company Ltd.
|
||||
:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
@echo off
|
||||
setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
|
||||
set script_dir_path=%~dp0
|
||||
set script_dir_path=%script_dir_path:~0,-1%
|
||||
|
||||
set cmake_scripts_dir=%script_dir_path%\cmake
|
||||
:: The '.' in 'echo.%*' ensures we don't print "echo is off" when no arguments are passed
|
||||
:: https://devblogs.microsoft.com/oldnewthing/20170802-00/?p=96735
|
||||
:: The space before the '>' makes sure that when we have a digit at the end of the args, we
|
||||
:: don't accidentally concatenate it with the '>' resulting in '0>' or '2>' which redirects into the
|
||||
:: file from a stream different than stdout, leading to broken or empty content.
|
||||
echo.%* >init-repository.opt.in
|
||||
|
||||
call cmake -DIN_FILE=init-repository.opt.in -DOUT_FILE=init-repository.opt ^
|
||||
-P "%cmake_scripts_dir%\QtWriteArgsFile.cmake"
|
||||
call cmake -DOPTFILE=init-repository.opt ^
|
||||
-P "%cmake_scripts_dir%\QtIRScript.cmake"
|
||||
|
||||
del init-repository.opt.in
|
||||
del init-repository.opt
|
Loading…
x
Reference in New Issue
Block a user