diff --git a/bin/qt-configure-module.bat.in b/bin/qt-configure-module.bat.in index 26d5c4b0510..aacb4e6aa32 100644 --- a/bin/qt-configure-module.bat.in +++ b/bin/qt-configure-module.bat.in @@ -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 diff --git a/bin/qt-configure-module.in b/bin/qt-configure-module.in index edc28b0b6df..06219436188 100755 --- a/bin/qt-configure-module.in +++ b/bin/qt-configure-module.in @@ -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 < "$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 diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake index 506535de199..065a8291e46 100644 --- a/cmake/QtBuildHelpers.cmake +++ b/cmake/QtBuildHelpers.cmake @@ -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() diff --git a/cmake/QtBuildRepoHelpers.cmake b/cmake/QtBuildRepoHelpers.cmake index abbbed9408c..2a3fa997b37 100644 --- a/cmake/QtBuildRepoHelpers.cmake +++ b/cmake/QtBuildRepoHelpers.cmake @@ -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) diff --git a/cmake/QtWrapperScriptHelpers.cmake b/cmake/QtWrapperScriptHelpers.cmake index 8eb4416e6d0..bcfc358762b 100644 --- a/cmake/QtWrapperScriptHelpers.cmake +++ b/cmake/QtWrapperScriptHelpers.cmake @@ -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() diff --git a/cmake/QtWriteArgsFile.cmake b/cmake/QtWriteArgsFile.cmake index 77a9eb24639..cd1d6351f51 100644 --- a/cmake/QtWriteArgsFile.cmake +++ b/cmake/QtWriteArgsFile.cmake @@ -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) diff --git a/cmake/qt-internal-config.redo.bat.in b/cmake/qt-internal-config.redo.bat.in new file mode 100644 index 00000000000..0befb7d04de --- /dev/null +++ b/cmake/qt-internal-config.redo.bat.in @@ -0,0 +1 @@ +@configure_path@ @repo_path@ -redo %* diff --git a/cmake/qt-internal-config.redo.in b/cmake/qt-internal-config.redo.in new file mode 100755 index 00000000000..d584c190198 --- /dev/null +++ b/cmake/qt-internal-config.redo.in @@ -0,0 +1,2 @@ +#!/bin/sh +@configure_path@ @repo_path@ -redo "$@" diff --git a/libexec/qt-internal-config.redo.bat.in b/libexec/qt-internal-config.redo.bat.in deleted file mode 100644 index d12cf9aae2e..00000000000 --- a/libexec/qt-internal-config.redo.bat.in +++ /dev/null @@ -1 +0,0 @@ -@configure_path@ -redo %* diff --git a/libexec/qt-internal-config.redo.in b/libexec/qt-internal-config.redo.in deleted file mode 100755 index c0427d55381..00000000000 --- a/libexec/qt-internal-config.redo.in +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -@configure_path@ -redo "$@"