CMake: Generate a config.redo script in per-repo build dirs

Before we only generated a 'config.redo' script in the build dir of
qtbase or a top-level build. After this change, we will also generate
one when configuring repos in a per-repo build of qt.

This allows quick fresh reconfiguration of a repo, without having to
remember how it was configured before.

To make that happen, we need to duplicate parts of the '-redo' code
that was initially added in configure, into qt-configure-module, both
for the Unix and Windows scripts.

Slight adjustments had to be made to account for the source repo path
argument, that needs to be skipped from being added into the
config.opt.in file.

We also need to modify the code that generates the config.redo file to
do it at the start of each repo configuration, rather than just when
configuring qtbase.

Amends 8ffb6ce64cb0183bf6805497b398463549c1ed8d

Change-Id: I76cd5296ea23ca5bfef6b8975c82416b628bc5d1
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Alexandru Croitor 2024-07-26 16:44:40 +02:00
parent 98847d2153
commit 85f37700e8
10 changed files with 200 additions and 24 deletions

View File

@ -1,5 +1,6 @@
@echo off
setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
set ARGS=%*
set script_dir_path=%~dp0
set script_dir_path=%script_dir_path:~0,-1%
@ -18,10 +19,69 @@ if not exist "%module_root%\CMakeLists.txt" (
)
set cmake_scripts_dir=%script_dir_path%\@__relative_path_to_cmake_scripts_dir@
echo %*>config.opt.in
call "%script_dir_path%\qt-cmake.bat" -DSKIP_ARGS=1 -DIN_FILE=config.opt.in -DOUT_FILE=config.opt ^
-P "%cmake_scripts_dir%\QtWriteArgsFile.cmake"
call "%script_dir_path%\qt-cmake-private.bat" -DOPTFILE=config.opt -DMODULE_ROOT="%module_root%" ^
set TOPQTDIR=%CD%
call :doargs %ARGS%
if errorlevel 1 exit /b
goto doneargs
:doargs
if "%~1" == "" exit /b
if /i "%~1" == "-redo" goto redo
if /i "%~1" == "--redo" goto redo
:nextarg
shift
goto doargs
:redo
if not exist "%TOPQTDIR%\config.opt" goto redoerr
echo %ARGS% > %TOPQTDIR%\config.redo.in
set redoing=""
goto nextarg
:redoerr
echo No config.opt present - cannot redo configuration. >&2
exit /b 1
:doneargs
rem Write config.opt if we're not currently -redo'ing
set OPT_FILE_PATH=%TOPQTDIR%\config.opt
set OPT_TMP_FILE_PATH=%TOPQTDIR%\config.opt.in
set REDO_FILE_PATH=%TOPQTDIR%\config.redo.last
set REDO_TMP_FILE_PATH=%TOPQTDIR%\config.redo.in
set FRESH_REQUESTED_ARG=
if not defined redoing (
rem "The '.' in 'echo.%*' ensures we don't print "echo is off" when no arguments are passed"
rem "https://devblogs.microsoft.com/oldnewthing/20170802-00/?p=96735"
rem "The space before the '>' makes sure that when we have a digit at the end of the args, we"
rem "don't accidentally concatenate it with the '>' resulting in '0>' or '2>' which redirects"
rem "into the file from a stream different than stdout, leading to broken or empty content."
echo.%* >"%OPT_TMP_FILE_PATH%"
rem "The SKIP_ARGS option makes sure not to write the repo path into the config.opt file"
call "%script_dir_path%\qt-cmake-private.bat" -DSKIP_ARGS=1 -DIN_FILE="%OPT_TMP_FILE_PATH%" ^
-DOUT_FILE="%OPT_FILE_PATH%" -P "%cmake_scripts_dir%\QtWriteArgsFile.cmake"
) else (
echo. 2> "%OPT_TMP_FILE_PATH%"
for /F "usebackq tokens=*" %%A in ("%OPT_FILE_PATH%") do echo "%%A" >> "%OPT_TMP_FILE_PATH%"
rem "The SKIP_REDO_FILE_ARGS option makes sure to remove the repo path read from the"
rem "config.redo.in file"
call "%script_dir_path%\qt-cmake-private.bat" -DSKIP_REDO_FILE_ARGS=1 ^
-DIN_FILE="%OPT_TMP_FILE_PATH%" -DREDO_FILE="%REDO_TMP_FILE_PATH%" ^
-DOUT_FILE="%REDO_FILE_PATH%" -DIGNORE_ARGS="-redo;--redo" ^
-P "%cmake_scripts_dir%\QtWriteArgsFile.cmake"
set OPT_FILE_PATH=%REDO_FILE_PATH%
set FRESH_REQUESTED_ARG=-DFRESH_REQUESTED=TRUE
)
rem Launch CMake-based configure
call "%script_dir_path%\qt-cmake-private.bat" -DOPTFILE="%OPT_FILE_PATH%" %FRESH_REQUESTED_ARG% ^
-DMODULE_ROOT="%module_root%" ^
-DCMAKE_COMMAND="%script_dir_path%\qt-cmake-private.bat" ^
-P "%cmake_scripts_dir%\QtProcessConfigureArgs.cmake"
goto :eof

View File

@ -4,6 +4,39 @@ set -eu
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; pwd)`
# the current directory is the "build tree" or "object tree"
outpath=`pwd`
outpathPrefix=$outpath
SAVED_IFS=$IFS
IFS='
'
optfile=""
determineOptFilePath()
{
> "${outpathPrefix}/config.redo.in"
set -f # suppress globbing in for loop
for i in "$@"; do
if [ x"$i" = x"-top-level" ]; then
continue
fi
case $i in
-redo|--redo)
optfile=${outpathPrefix}/config.opt
if ! test -f "$optfile"; then
echo >&2 "No config.opt present - cannot redo configuration."
exit 1
fi
;;
*)
# If redo-ing, write the rest of parameters into the config.redo.in file
echo \"$i\" >> "${outpathPrefix}/config.redo.in"
;;
esac
done
}
printUsage()
{
cat <<EOF
@ -19,6 +52,7 @@ if [ "$#" -lt 1 ]; then
exit 1
fi
module_root=$1
# This ensures the repo path does not end up in the config.opt file.
shift
if [ ! -f "$module_root/CMakeLists.txt" ]; then
@ -27,12 +61,40 @@ if [ ! -f "$module_root/CMakeLists.txt" ]; then
exit 1
fi
optfile=config.opt
echo > "$optfile"
for arg in "$@"; do
echo "$arg" >> "$optfile"
done
determineOptFilePath "$@"
optfilepath=${outpathPrefix}/config.opt
opttmpfilepath=${outpathPrefix}/config.opt.in
redofilepath=${outpathPrefix}/config.redo.last
redotmpfilepath=${outpathPrefix}/config.redo.in
qt_cmake_private_path="$script_dir_path/../libexec"
fresh_requested_arg=
if [ -z "$optfile" ]; then # only write optfile if not currently redoing
> "$opttmpfilepath"
> "$redotmpfilepath"
for arg in "$@"; do echo \"$arg\" >> "$opttmpfilepath"; done
"$qt_cmake_private_path/qt-cmake-private" -DIN_FILE="${opttmpfilepath}" \
-DOUT_FILE="${optfilepath}" \
-P "$script_dir_path/@__relative_path_to_cmake_scripts_dir@/QtWriteArgsFile.cmake"
else
# Rewriting config.opt into config.opt.in anyway. Allows for direct manipulation of config.opt
> "$opttmpfilepath"
for arg in `cat $optfile`; do echo \"$arg\" >> "$opttmpfilepath"; done
"$qt_cmake_private_path/qt-cmake-private" -DIN_FILE="${opttmpfilepath}" \
-DREDO_FILE="${redotmpfilepath}" -DOUT_FILE="${redofilepath}" \
-P "$script_dir_path/@__relative_path_to_cmake_scripts_dir@/QtWriteArgsFile.cmake"
optfilepath=${redofilepath}
fresh_requested_arg=-DFRESH_REQUESTED=TRUE
fi
cmake_script_path="$script_dir_path/@__relative_path_to_cmake_scripts_dir@/QtProcessConfigureArgs.cmake"
qt_cmake_private_path="$script_dir_path/../libexec"
"$qt_cmake_private_path/qt-cmake-private" -DOPTFILE=$optfile -DMODULE_ROOT="$module_root" -DCMAKE_COMMAND="$qt_cmake_private_path/qt-cmake-private" -P "$cmake_script_path"
"$qt_cmake_private_path/qt-cmake-private" -DOPTFILE=$optfilepath -DMODULE_ROOT="$module_root" \
-DCMAKE_COMMAND="$qt_cmake_private_path/qt-cmake-private" -P "$cmake_script_path"
IFS=$SAVED_IFS

View File

@ -264,6 +264,8 @@ function(qt_internal_get_qt_build_private_files_to_install out_var)
QtWriteArgsFile.cmake
modulecppexports.h.in
qbatchedtestrunner.in.cpp
qt-internal-config.redo.in
qt-internal-config.redo.bat.in
PARENT_SCOPE
)
endfunction()

View File

@ -197,6 +197,7 @@ macro(qt_build_repo_begin)
qt_enable_cmake_languages()
qt_internal_generate_binary_strip_wrapper()
qt_internal_create_qt_configure_redo_script()
# Add global docs targets that will work both for per-repo builds, and super builds.
if(NOT TARGET docs)

View File

@ -235,7 +235,6 @@ export CMAKE_GENERATOR=Xcode
qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_TESTS")
qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_EXAMPLES")
qt_internal_create_qt_configure_redo_script()
endfunction()
function(qt_internal_create_qt_configure_part_wrapper_script component)
@ -302,32 +301,78 @@ endfunction()
# The script is created in the root of the build dir and is called config.redo
# It has the same contents as the 'config.status' script we created in qt 5.
function(qt_internal_create_qt_configure_redo_script)
set(input_script_name "qt-internal-config.redo")
set(input_script_path "${CMAKE_CURRENT_SOURCE_DIR}/libexec/${input_script_name}")
# Protect against creating the script once per repo in a top level build. Only one file should
# be created.
get_cmake_property(script_created _qt_configure_redo_script_created)
if(script_created)
return()
endif()
set(wrapper_extension "")
if(NOT CMAKE_HOST_UNIX)
set(wrapper_extension ".bat")
endif()
set(script_name "qt-internal-config.redo")
set(wrapper_rel_path "${script_name}${wrapper_extension}.in")
# Need to find the input file depending whether the qtbase sources are available.
# This mirrors the logic in qt_set_up_build_internals_paths.
# TODO: Clean this up, together with qt_set_up_build_internals_paths to only use the
# the qtbase sources when building qtbase. And perhaps also when doing a non-prefix
# developer-build.
set(qtbase_in_path "${QT_SOURCE_TREE}/cmake/${wrapper_rel_path}")
set(installed_in_path
"${_qt_cmake_dir}/${QT_CMAKE_EXPORT_NAMESPACE}/${wrapper_rel_path}")
# qtbase sources available, always use them, regardless of prefix or non-prefix builds.
if(EXISTS "${qtbase_in_path}")
set(input_script_path "${qtbase_in_path}")
# qtbase sources unavailable, use installed files.
elseif(EXISTS "${installed_in_path}")
set(input_script_path "${installed_in_path}")
else()
message(FATAL_ERROR "Can't find ${script_name}${wrapper_extension}.in file.")
endif()
# We don't use QT_BUILD_DIR because we want the file in the root of the build dir in a top-level
# build.
set(output_script_name "config.redo")
set(output_path "${CMAKE_BINARY_DIR}/${output_script_name}")
set(output_path "${CMAKE_BINARY_DIR}/${output_script_name}${wrapper_extension}")
set(repo_path "")
if(QT_SUPERBUILD)
set(configure_script_path "${Qt_SOURCE_DIR}")
set(configure_script_path "${Qt_SOURCE_DIR}/configure")
elseif(QtBase_SOURCE_DIR)
set(configure_script_path "${QtBase_SOURCE_DIR}/configure")
else()
set(configure_script_path "${QtBase_SOURCE_DIR}")
if(QT_WILL_INSTALL)
set(configure_script_path "${QT_STAGING_PREFIX}")
else()
set(configure_script_path "${QT_BUILD_DIR}")
endif()
string(APPEND configure_script_path
"/${INSTALL_BINDIR}/qt-configure-module${wrapper_extension}")
# When configuring a repo other than qtbase, we also need to provide the location
# to the repo sources.
set(repo_path "${CMAKE_SOURCE_DIR}")
endif()
string(APPEND configure_script_path "/configure")
# Used in the file contents.
file(TO_NATIVE_PATH "${configure_script_path}" configure_path)
if(CMAKE_HOST_UNIX)
string(APPEND input_script_path ".in")
set(newline_style "LF")
else()
string(APPEND input_script_path ".bat.in")
string(APPEND output_path ".bat")
set(newline_style "CRLF")
endif()
configure_file("${input_script_path}" "${output_path}" @ONLY NEWLINE_STYLE ${newline_style})
set_property(GLOBAL PROPERTY _qt_configure_redo_script_created TRUE)
endfunction()

View File

@ -10,6 +10,7 @@
# 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.
# SKIP_REDO_FILE_ARGS: Number of arguments to skip from the front of the redo file 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
@ -31,6 +32,11 @@ 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(DEFINED SKIP_REDO_FILE_ARGS)
foreach(i RANGE 1 ${SKIP_REDO_FILE_ARGS})
list(POP_FRONT redo_args)
endforeach()
endif()
if(args)
list(FIND args "--" args_ddash_loc)

View File

@ -0,0 +1 @@
@configure_path@ @repo_path@ -redo %*

View File

@ -0,0 +1,2 @@
#!/bin/sh
@configure_path@ @repo_path@ -redo "$@"

View File

@ -1 +0,0 @@
@configure_path@ -redo %*

View File

@ -1,2 +0,0 @@
#!/bin/sh
@configure_path@ -redo "$@"