From 5c40cb0f1a8fad03edb3ef0f97df15e9dd643bdf Mon Sep 17 00:00:00 2001 From: Amir Masoud Abdol Date: Fri, 18 Nov 2022 11:31:02 +0100 Subject: [PATCH] Fix a bug in -redo where -redo was not considering new options In addition to the fix, I've removed some legacy codes in the `configure` file and delegated most of the work to the `QtWriteArgsFile.cmake` which was being used by `configure.bat`. I am not sure how this was supposed to work before since it was not really working, but now, `config.opt` lives in the build directory, together with `config.opt.in` (a template file), and the `config.redo` (and `config.redo.in`) which holds the full redo command. The template files are being used to preserve the quoted variables and to help QtWriteArgFiles process the opt files more consistency. Also fixed an issue on Unix, where ./configure was failing to run if its path contained spaces, e.g., `Qt Src/qt5/configure`. Fixes: QTBUG-108287 Change-Id: I9843b690a1fd3177a93e55e08a3484a4c85ba2e8 Reviewed-by: Alexandru Croitor --- cmake/QtWriteArgsFile.cmake | 53 ++++++++++++- configure | 146 +++++++++--------------------------- configure.bat | 22 ++++-- 3 files changed, 101 insertions(+), 120 deletions(-) diff --git a/cmake/QtWriteArgsFile.cmake b/cmake/QtWriteArgsFile.cmake index aeb83bc9b91..acc771ec3b7 100644 --- a/cmake/QtWriteArgsFile.cmake +++ b/cmake/QtWriteArgsFile.cmake @@ -6,10 +6,14 @@ # This is used for writing the config.opt file. # # This script takes the following arguments: -# IN_FILE: The input file. The whole command line as one string. +# 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) @@ -17,6 +21,53 @@ cmake_minimum_required(VERSION 3.16) file(READ "${IN_FILE}" raw_args) separate_arguments(args NATIVE_COMMAND "${raw_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}) diff --git a/configure b/configure index a2b67a1d46a..cf751ed77f2 100755 --- a/configure +++ b/configure @@ -8,14 +8,18 @@ #------------------------------------------------------------------------------- # the directory of this script is the "source tree" -relpath=`dirname $0` +relpath=`dirname "$0"` relpath=`(cd "$relpath"; /bin/pwd)` # the current directory is the "build tree" or "object tree" outpath=`/bin/pwd` +outpathPrefix=$outpath # do this early so we don't store it in config.status CFG_TOPLEVEL= -outpathPrefix= + +SAVED_IFS=$IFS +IFS=' +' checkTopLevelBuild() { @@ -23,7 +27,7 @@ checkTopLevelBuild() if [ x"$1" = x"-top-level" ]; then CFG_TOPLEVEL=yes relpathMangled=`dirname "$relpath"` - outpathPrefix=../ + outpathPrefix+=/.. else if [ -f ../.qmake.super ]; then echo >&2 "ERROR: You cannot configure qtbase separately within a top-level build." @@ -35,41 +39,26 @@ checkTopLevelBuild() OPT_CMDLINE= # expanded version for the script determineOptFilePath() { +> "${outpathPrefix}/config.redo.in" set -f # suppress globbing in for loop -SAVED_IFS=$IFS -IFS=' -' for i in "$@"; do if [ x"$i" = x"-top-level" ]; then continue fi case $i in -redo|--redo) - optfile=${outpathPrefix}config.opt - if test -n "$CFG_TOPLEVEL" && ! test -f $optfile; then - optfile=config.opt - fi - if ! test -f $optfile; then + optfile=${outpathPrefix}/config.opt + if ! test -f "$optfile"; then echo >&2 "No config.opt present - cannot redo configuration." exit 1 fi - for a in `cat $optfile`; do - OPT_CMDLINE="$OPT_CMDLINE -$a" - done ;; *) - OPT_CMDLINE="$OPT_CMDLINE -$i" + # If redo-ing, write the rest of parameters into the config.redo.in file + echo \"$i\" >> "${outpathPrefix}/config.redo.in" ;; esac done -set -- -for i in $OPT_CMDLINE; do - set -- "$@" "$i" -done -set +f -IFS=$SAVED_IFS } #------------------------------------------------------------------------------- @@ -88,80 +77,10 @@ while [ "$#" -gt 0 ]; do CURRENT_OPT="$1" case "$1" in #Autoconf style options - --enable-*) - VAR=`echo $1 | sed 's,^--enable-\(.*\),\1,'` - VAL=yes - ;; - --disable-*) - VAR=`echo $1 | sed 's,^--disable-\(.*\),\1,'` - VAL=no - ;; - --*=*) - VAR=`echo $1 | sed 's,^--\(.*\)=.*,\1,'` - VAL=`echo $1 | sed 's,^--.*=\(.*\),\1,'` - ;; - --no-*) - VAR=`echo $1 | sed 's,^--no-\(.*\),\1,'` - VAL=no - ;; --*) VAR=`echo $1 | sed 's,^--\(.*\),\1,'` VAL=yes ;; - #Qt plugin options - -no-*-*|-plugin-*-*|-qt-*-*) - VAR=`echo $1 | sed 's,^-[^-]*-\(.*\),\1,'` - VAL=`echo $1 | sed 's,^-\([^-]*\).*,\1,'` - ;; - #Qt style no options - -no-*) - VAR=`echo $1 | sed 's,^-no-\(.*\),\1,'` - VAL=no - ;; - #Qt style options that pass an argument - -prefix| \ - -docdir| \ - -headerdir| \ - -plugindir| \ - -qmldir| \ - -archdatadir| \ - -datadir| \ - -libdir| \ - -bindir| \ - -libexecdir| \ - -translationdir| \ - -sysconfdir| \ - -examplesdir| \ - -testsdir| \ - -hostdatadir| \ - -extprefix| \ - -sysroot| \ - -make| \ - -nomake| \ - -skip| \ - -platform| \ - -xplatform| \ - -device| \ - -device-option| \ - -sdk| \ - -android-sdk| \ - -android-ndk| \ - -android-ndk-platform| \ - -android-arch) - VAR=`echo $1 | sed 's,^-\(.*\),\1,'` - shift - VAL="$1" - ;; - #Qt style complex options in one command - -enable-*|-disable-*) - VAR=`echo $1 | sed 's,^-\([^-]*\)-.*,\1,'` - VAL=`echo $1 | sed 's,^-[^-]*-\(.*\),\1,'` - ;; - #Qt Builtin/System style options - -no-*|-system-*|-qt-*) - VAR=`echo $1 | sed 's,^-[^-]*-\(.*\),\1,'` - VAL=`echo $1 | sed 's,^-\([^-]*\)-.*,\1,'` - ;; #General options, including Qt style yes options -*) VAR=`echo $1 | sed 's,^-\(.*\),\1,'` @@ -176,24 +95,16 @@ while [ "$#" -gt 0 ]; do shift - UNKNOWN_OPT=no case "$VAR" in h|help) if [ "$VAL" = "yes" ]; then OPT_HELP="$VAL" - else - UNKNOWN_OPT=yes fi ;; *) ;; esac - if [ "$UNKNOWN_OPT" = "yes" ]; then - echo "${CURRENT_OPT}: invalid command-line switch" - ERROR=yes - fi done -[ "x$ERROR" = "xyes" ] && exit 1 } #------------------------------------------------------------------------------- @@ -222,18 +133,29 @@ parseCommandline "$@" handleHelp determineOptFilePath "$@" +optfilepath=${outpathPrefix}/config.opt +opttmpfilepath=${outpathPrefix}/config.opt.in + +redofilepath=${outpathPrefix}/config.redo +redotmpfilepath=${outpathPrefix}/config.redo.in + fresh_requested_arg= -optfilename=config.opt if [ -z "$optfile" ]; then # only write optfile if not currently redoing - optfilepath=${outpathPrefix}${optfilename} - > "$optfilepath" - for arg in "$@"; do - if [ "$arg" = "-top-level" ]; then - continue - fi - echo $arg >> "$optfilepath" - done + > "$opttmpfilepath" + > "$redotmpfilepath" + + for arg in "$@"; do echo \"$arg\" >> "$opttmpfilepath"; done + + cmake -DIN_FILE="${opttmpfilepath}" -DOUT_FILE="${optfilepath}" -DIGNORE_ARGS=-top-level -P "${relpath}/cmake/QtWriteArgsFile.cmake" else + # In case config.opt.in is missing for some reason + if [ ! -f "$opttmpfilepath" ]; then + > "$opttmpfilepath" + for arg in `cat $optfile`; do echo \"$arg\" >> "$opttmpfilepath"; done + fi + + cmake -DIN_FILE="${opttmpfilepath}" -DREDO_FILE="${redotmpfilepath}" -DOUT_FILE="${redofilepath}" -DIGNORE_ARGS=-top-level -P "${relpath}/cmake/QtWriteArgsFile.cmake" + optfilepath=${redofilepath} fresh_requested_arg=-DFRESH_REQUESTED=TRUE fi @@ -243,4 +165,6 @@ if [ -n "$CFG_TOPLEVEL" ]; then cd .. fi -cmake "-DOPTFILE=$optfilename" $top_level_arg $fresh_requested_arg -P "$relpath/cmake/QtProcessConfigureArgs.cmake" +cmake "-DOPTFILE=${optfilepath}" ${top_level_arg} ${fresh_requested_arg} -P "${relpath}/cmake/QtProcessConfigureArgs.cmake" + +IFS=$SAVED_IFS diff --git a/configure.bat b/configure.bat index e93e0af318a..f3176d3e7ac 100644 --- a/configure.bat +++ b/configure.bat @@ -65,9 +65,8 @@ goto doneargs :redo if not exist "%TOPQTDIR%\config.opt" goto redoerr - set rargs= - for /f "usebackq delims=" %%i in ("%TOPQTDIR%\config.opt") do set rargs=!rargs! "%%i" - call :doargs %rargs% + echo %ARGS% > %TOPQTDIR%\config.redo.in + set redoing="" goto nextarg :redoerr echo No config.opt present - cannot redo configuration. >&2 @@ -78,15 +77,22 @@ goto doneargs cd "%TOPQTDIR%" 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 +set REDO_TMP_FILE_PATH=%TOPQTDIR%\config.redo.in set FRESH_REQUESTED_ARG= -if "!rargs!" == "" ( - echo.%*>config.opt.in - cmake -DIN_FILE=config.opt.in -DOUT_FILE=config.opt -DIGNORE_ARGS=-top-level -P "%QTSRC%\cmake\QtWriteArgsFile.cmake" -) else if NOT "!rargs!" == "" ( +if not defined redoing ( + echo.%*>"%OPT_TMP_FILE_PATH%" + cmake -DIN_FILE="%OPT_TMP_FILE_PATH%" -DOUT_FILE="%OPT_FILE_PATH%" -DIGNORE_ARGS=-top-level -P "%QTSRC%\cmake\QtWriteArgsFile.cmake" +) else ( + cmake -DIN_FILE="%OPT_TMP_FILE_PATH%" -DREDO_FILE="%REDO_TMP_FILE_PATH%" -DOUT_FILE="%REDO_FILE_PATH%" -DIGNORE_ARGS="-top-level;-redo;--redo" -P "%QTSRC%\cmake\QtWriteArgsFile.cmake" + + set OPT_FILE_PATH=%REDO_FILE_PATH% set FRESH_REQUESTED_ARG=-DFRESH_REQUESTED=TRUE ) rem Launch CMake-based configure set TOP_LEVEL_ARG= if %TOPLEVEL% == true set TOP_LEVEL_ARG=-DTOP_LEVEL=TRUE -cmake -DOPTFILE=config.opt %TOP_LEVEL_ARG% %FRESH_REQUESTED_ARG% -P "%QTSRC%\cmake\QtProcessConfigureArgs.cmake" +cmake -DOPTFILE="%OPT_FILE_PATH%" %TOP_LEVEL_ARG% %FRESH_REQUESTED_ARG% -P "%QTSRC%\cmake\QtProcessConfigureArgs.cmake"