CMake: Protect against Qt toolchain file recursive inclusion

Three different people have encountered the issue that calling
calling qt-cmake on a project prints 1000 inclusion lines of the same
qt toolchain file, and then CMake bails out saying can't find the
CMAKE_MAKE_PROGRAM Ninja.

This happened because people accidentally called qt-cmake to configure
qtbase (instead of just cmake), which created a toolchain file that
chainloads itself recursively.

Error out when configuring qtbase, and when using the generated
toolchain file in the case when it would try to include itself.

The solution is to remove the qtbase CMakeCache.txt file, and
configure qtbase again, so it generates a proper qt.toolchain.cmake
file.

If somebody feels enthusiastic, they can move the check into the
qt-cmake and qt-cmake-private shell scripts, and error out before the
qtbase/CMakeCache.txt is polluted with the wrong toolchain file.
That is left for people that feel more comfortable with bash and batch
scripting.

Change-Id: If518c94791fe7c30731e6e462e347f26a5213c64
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2020-06-02 18:06:37 +02:00
parent c254254c55
commit dc26b30acd
4 changed files with 30 additions and 6 deletions

View File

@ -1,8 +1,11 @@
# special case skip regeneration
cmake_minimum_required(VERSION 3.15.0)
# Run auto detection routines
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtAutoDetect.cmake)
# Run auto detection routines, but not when doing stnadalone tests. In that case the detection
# results are takend from either QtBuildInternals or the qt.toolchain.cmake file.
if(NOT QT_BUILD_STANDALONE_TESTS)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtAutoDetect.cmake)
endif()
if (CMAKE_CROSSCOMPILING AND CMAKE_SYSROOT)
# When cross compiling with CMake any calls to pkg_check_modules() will

View File

@ -185,6 +185,16 @@ function(qt_auto_detect_cmake_config)
endif()
endfunction()
function(qt_auto_detect_cyclic_toolchain)
if(CMAKE_TOOLCHAIN_FILE AND CMAKE_TOOLCHAIN_FILE MATCHES "/qt.toolchain.cmake$")
message(FATAL_ERROR
"Woah there! You can't use the Qt generated qt.toolchain.cmake file to configure "
"qtbase, because that will create a toolchain file that includes itself!\n"
"Did you accidentally use qt-cmake to configure qtbase? Make sure to remove the "
"CMakeCache.txt file, and configure qtbase with 'cmake' instead of 'qt-cmake'.")
endif()
endfunction()
function(qt_auto_detect_darwin)
if(APPLE)
# If no CMAKE_OSX_DEPLOYMENT_TARGET is provided, default to a value that Qt defines.
@ -230,6 +240,7 @@ function(qt_auto_detect_pch)
option(BUILD_WITH_PCH "Build Qt using precompiled headers?" "${default_value}")
endfunction()
qt_auto_detect_cyclic_toolchain()
qt_auto_detect_cmake_config()
qt_auto_detect_darwin()
qt_auto_detect_ios()

View File

@ -116,7 +116,7 @@ if(QT_HOST_PATH)
endif()
if(CMAKE_TOOLCHAIN_FILE)
set(init_original_toolchain_file "set(qt_chainload_toolchain_file \"${CMAKE_TOOLCHAIN_FILE}\")")
set(init_original_toolchain_file "set(__qt_chainload_toolchain_file \"${CMAKE_TOOLCHAIN_FILE}\")")
endif()
if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)

View File

@ -6,9 +6,19 @@
@init_vcpkg@
if(qt_chainload_toolchain_file)
include("${qt_chainload_toolchain_file}")
unset(qt_chainload_toolchain_file)
if(__qt_chainload_toolchain_file)
get_filename_component(__qt_chainload_toolchain_file_real_path
"${__qt_chainload_toolchain_file}" REALPATH)
if(__qt_chainload_toolchain_file_real_path STREQUAL CMAKE_CURRENT_LIST_FILE)
message(FATAL_ERROR
"Woah, the Qt toolchain file tried to include itself recusively! '${__qt_chainload_toolchain_file}' "
"Make sure to remove qtbase/CMakeCache.txt and reconfigure qtbase with 'cmake' "
"rather than 'qt-cmake', and then you can reconfigure your own project."
)
else()
include("${__qt_chainload_toolchain_file}")
endif()
unset(__qt_chainload_toolchain_file)
endif()
# Compute dynamically the Qt installation prefix from the location of this file. This allows