CMake: Teach configure.bat the -cmake argument

The configure scripts need to translate configure options to CMake
arguments. It is not sensible to implement this translation twice, in
sh and Windows batch language, so we're doing this once, in CMake
language.

The configure scripts write their options into config.opt and call a
CMake script that reads config.opt, does the translation to CMake
arguments and calls CMake to generate the build system.

While we're at it, implement some more translations than the sh
configure provided, like -extprefix, -top-level and -skip.

Fixes: QTBUG-85349
Fixes: QTBUG-85350
Task-number: QTBUG-85373
Change-Id: Ida5d8b2a3c178b9349d41ec76d190c69a9456e74
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Joerg Bornemann 2020-07-02 22:40:28 +02:00
parent ffb8464cef
commit dbd3c75965
3 changed files with 147 additions and 104 deletions

View File

@ -0,0 +1,115 @@
# This script reads Qt configure arguments from config.opt,
# translates the arguments to CMake arguments and calls CMake.
#
# This file is to be used in CMake script mode with the following variables set:
# OPTFILE: A text file containing the options that were passed to configure
# with one option per line.
cmake_policy(SET CMP0007 NEW)
set(cmake_args "")
macro(push)
list(APPEND cmake_args ${ARGN})
endmacro()
macro(calculate_state)
set(state ON)
if(CMAKE_MATCH_1 MATCHES "no-?")
set(state OFF)
endif()
endmacro()
macro(pop_path_argument)
list(POP_FRONT configure_args path)
string(REGEX REPLACE "^\"(.*)\"$" "\\1" path "${path}")
file(TO_CMAKE_PATH "${path}" path)
endmacro()
get_filename_component(source_dir ".." ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
file(STRINGS "${OPTFILE}" configure_args)
list(FILTER configure_args EXCLUDE REGEX "^[ \t]*$")
list(TRANSFORM configure_args STRIP)
set(set_generator TRUE)
while(configure_args)
list(POP_FRONT configure_args arg)
if(arg STREQUAL "-cmake")
# ignore
elseif(arg STREQUAL "-cmake-makefiles")
set(set_generator FALSE)
elseif(arg STREQUAL "-top-level")
get_filename_component(source_dir "../.." ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
elseif(arg STREQUAL "-skip")
list(POP_FRONT configure_args qtrepo)
push("-DBUILD_${qtrepo}=OFF")
elseif(arg STREQUAL "-opensource")
# to be done
elseif(arg STREQUAL "-commercial")
# to be done
elseif(arg STREQUAL "-confirm-license")
# to be done
elseif(arg MATCHES "^-(no)?make")
calculate_state()
list(POP_FRONT configure_args component)
if(component STREQUAL "tests")
push(-DBUILD_TESTING=${state})
elseif(component STREQUAL "examples")
push(-DBUILD_EXAMPLES=${state})
else()
string(TOUPPER "${component}" uc_component)
push(-DQT_NO_MAKE_${uc_component}=${state})
endif()
elseif(arg MATCHES "^-(no-)?feature")
calculate_state()
list(POP_FRONT configure_args feature)
push("-DFEATURE_${feature}=${state}")
elseif(arg MATCHES "^-(no-)pch")
calculate_state()
push("-DBUILD_WITH_PCH=${state}")
elseif(arg MATCHES "^-system-(.*)")
list(POP_FRONT configure_args lib)
push("-DFEATURE_system_${lib}=ON")
elseif(arg MATCHES "^-qt-(.*)")
list(POP_FRONT configure_args lib)
push("-DFEATURE_system_${lib}=OFF")
elseif(arg MATCHES "^-sanitize=(.*)")
push("-DECM_ENABLE_SANITIZERS=${CMAKE_MATCH_1}")
elseif(arg STREQUAL "-ccache")
push(-DQT_USE_CCACHE=ON)
elseif(arg STREQUAL "-developer-build")
push(-DFEATURE_developer_build=ON)
elseif(arg STREQUAL "-prefix")
pop_path_argument()
push("-DCMAKE_INSTALL_PREFIX=${path}")
elseif(arg STREQUAL "-extprefix")
pop_path_argument()
push("-DCMAKE_STAGING_PREFIX=${path}")
elseif(arg STREQUAL "-hostprefix")
message(FATAL_ERROR "${arg} is not supported in the CMake build.")
elseif(arg STREQUAL "-external-hostbindir")
# This points to the bin directory of the Qt installation.
# This can be multiple levels deep and we cannot deduce the QT_HOST_PATH safely.
message(FATAL_ERROR "${arg} is not supported anymore. Use -qt-host-path <dir> instead.")
elseif(arg STREQUAL "-qt-host-path")
pop_path_argument()
push("-DQT_HOST_PATH=${path}")
elseif(arg STREQUAL "--")
# Everything after this argument will be passed to CMake verbatim.
push(${configure_args})
break()
else()
message(FATAL_ERROR "Unknown configure argument: ${arg}")
endif()
endwhile()
if(set_generator)
push(-G Ninja)
endif()
push("${source_dir}")
execute_process(COMMAND "${CMAKE_COMMAND}" ${cmake_args}
COMMAND_ECHO STDOUT
RESULT_VARIABLE exit_code)
if(NOT exit_code EQUAL 0)
message(FATAL_ERROR "CMake exited with code ${exit_code}.")
endif()

114
configure vendored
View File

@ -112,93 +112,6 @@ checkTopLevelBuild()
fi
}
CMAKE_CMDLINE=
getCMakeCmdLine()
{
PASSTHRU=
set -f # suppress globbing in for loop
SAVED_IFS=$IFS
IFS='
'
if [ "$CFG_DEV" = "yes" ]; then
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DFEATURE_developer_build=ON"
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DBUILD_TESTING=ON"
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DBUILD_EXAMPLES=ON"
fi
if [ "$CMAKE_MAKEFILES" = "no" ]; then
CMAKE_CMDLINE="$CMAKE_CMDLINE
-G Ninja"
fi
while [ "$#" -gt 0 ]; do
i="$1"
shift
if [ "$PASSTHRU" = "yes" ]; then
CMAKE_CMDLINE="$CMAKE_CMDLINE
$i"
else
case $i in
-nomake|--nomake)
arg_capitalized=`echo $1 | tr a-z A-Z`
shift
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DQT_NO_MAKE_${arg_capitalized}=ON"
;;
-feature-*|--feature-*)
VAR=`echo $i | sed -E 's/-?-feature-(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DQT_FEATURE_${VAR}=ON"
;;
-no-feature-*|--no-feature-*)
VAR=`echo $i | sed -E 's/-?-no-feature-(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DQT_FEATURE_${VAR}=OFF"
;;
-no-pch|--no-pch)
"$CMAKE_CMDLINE
-DBUILD_WITH_PCH=OFF"
;;
-no-*|--no-*)
VAR=`echo $i | sed -E 's/-?-no-(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DFEATURE_${VAR}=OFF"
;;
-system-*|--system-*)
VAR=`echo $i | sed -E 's/-?-system-(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DFEATURE_system_${VAR}=ON"
;;
-qt-*|--qt-*)
VAR=`echo $i | sed -E 's/-?-qt-(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DFEATURE_system_${VAR}=OFF"
;;
-sanitize=*|--sanitize=*)
VAR=`echo $i | sed -E 's/-?-sanitize=(.*)/\1/'`
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DECM_ENABLE_SANITIZERS=${VAR}"
;;
-ccache|--ccache)
CMAKE_CMDLINE="$CMAKE_CMDLINE
-DQT_USE_CCACHE=ON"
;;
--)
PASSTHRU=yes
;;
*)
;;
esac
fi
done
set +f
IFS=$SAVED_IFS
}
OPT_CMDLINE= # expanded version for the script
QMAKE_CMDLINE= # verbatim version for qmake call
getOptAndQMakeCmdLines()
@ -1002,26 +915,19 @@ else
fi
}
runCMake()
{
# recreate command line for cmake
set -f
SAVED_IFS=$IFS
IFS='
'
for i in $CMAKE_CMDLINE; do
set -- $* "$i"
done
set +f
IFS=$SAVED_IFS
cmake $* "$relpath"
}
parseCommandline "$@"
handleHelp
if [ "$BUILD_WITH_CMAKE" = "yes" ]; then
getCMakeCmdLine $@
runCMake
checkTopLevelBuild "$@"
getOptAndQMakeCmdLines "$@"
if [ -z "$optfile" ]; then # only write optfile if not currently redoing
optfile=${outpathPrefix}config.opt
if [ -f "$optfile" ]; then rm "$optfile"; fi
for arg in "$@"; do
echo $arg >> "$optfile"
done
fi
cmake "-DOPTFILE=$optfile" -P "$relpath/cmake/QtProcessConfigureArgs.cmake"
else
findPerl
findAwk

View File

@ -69,6 +69,7 @@ exit /b 1
set SYNCQT=
set PLATFORM=
set MAKE=
set CMAKE=
call :doargs %ARGS%
if errorlevel 1 exit /b
goto doneargs
@ -96,6 +97,9 @@ goto doneargs
if /i "%~1" == "-make-tool" goto maketool
if /i "%~1" == "--make-tool" goto maketool
if /i "%~1" == "-cmake" goto cmake
if /i "%~1" == "--cmake" goto cmake
:nextarg
shift
goto doargs
@ -144,8 +148,14 @@ goto doneargs
set MAKE=%~1
goto nextarg
:cmake
set CMAKE=true
goto nextarg
:doneargs
if "%CMAKE%" == "true" goto cmake
rem Find various executables
for %%C in (clang-cl.exe clang.exe cl.exe icl.exe g++.exe perl.exe jom.exe) do set %%C=%%~$PATH:C
@ -294,3 +304,15 @@ rem Launch qmake-based configure
cd "%TOPQTDIR%"
"%QTDIR%\bin\qmake.exe" "%TOPQTSRC%" -- %ARGS%
goto :eof
:cmake
rem Write config.opt if we're not currently -redo'ing
if "%rargs%" == "" (
if exist "%TOPQTDIR%\config.opt" del "%TOPQTDIR%\config.opt"
for %%a in (%ARGS%) do echo %%a >> "%TOPQTDIR%\config.opt"
)
rem Launch CMake-based configure
cmake -DOPTFILE="%TOPQTDIR%\config.opt" -P "%QTSRC%\cmake\QtProcessConfigureArgs.cmake"