diff options
Diffstat (limited to 'cmake/QtToolchainHelpers.cmake')
-rw-r--r-- | cmake/QtToolchainHelpers.cmake | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/cmake/QtToolchainHelpers.cmake b/cmake/QtToolchainHelpers.cmake new file mode 100644 index 0000000000..a067ef7c0c --- /dev/null +++ b/cmake/QtToolchainHelpers.cmake @@ -0,0 +1,148 @@ +# Create a CMake toolchain file for convenient configuration of both internal Qt builds +# as well as CMake application projects. +# Expects various global variables to be set. +function(qt_internal_create_toolchain_file) + if(QT_HOST_PATH) + # TODO: Figure out how to make these relocatable. + + get_filename_component(__qt_host_path_absolute "${QT_HOST_PATH}" ABSOLUTE) + set(init_qt_host_path " + set(__qt_initial_qt_host_path \"${__qt_host_path_absolute}\") + if(NOT DEFINED QT_HOST_PATH AND EXISTS \"\${__qt_initial_qt_host_path}\") + set(QT_HOST_PATH \"\${__qt_initial_qt_host_path}\" CACHE PATH \"\" FORCE) + endif()") + + get_filename_component(__qt_host_path_cmake_dir_absolute + "${Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR}/.." ABSOLUTE) + set(init_qt_host_path_cmake_dir + " + set(__qt_initial_qt_host_path_cmake_dir \"${__qt_host_path_cmake_dir_absolute}\") + if(NOT DEFINED QT_HOST_PATH_CMAKE_DIR AND EXISTS \"\${__qt_initial_qt_host_path_cmake_dir}\") + set(QT_HOST_PATH_CMAKE_DIR \"\${__qt_initial_qt_host_path_cmake_dir}\" CACHE PATH \"\" FORCE) + endif()") + + set(init_qt_host_path_checks " + if(NOT QT_HOST_PATH OR NOT EXISTS \"\${QT_HOST_PATH}\") + message(FATAL_ERROR \"To use a cross-compiled Qt, please specify a path to a host Qt installation by setting the QT_HOST_PATH cache variable.\") + endif() + if(NOT QT_HOST_PATH_CMAKE_DIR OR NOT EXISTS \"\${QT_HOST_PATH_CMAKE_DIR}\") + message(FATAL_ERROR \"To use a cross-compiled Qt, please specify a path to a host Qt installation CMake directory by setting the QT_HOST_PATH_CMAKE_DIR cache variable.\") + endif()") + endif() + + if(CMAKE_TOOLCHAIN_FILE) + file(TO_CMAKE_PATH "${CMAKE_TOOLCHAIN_FILE}" __qt_chainload_toolchain_file) + set(init_original_toolchain_file + "set(__qt_chainload_toolchain_file \"${__qt_chainload_toolchain_file}\")") + endif() + + if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE) + list(APPEND init_vcpkg + "set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE \"${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}\")") + endif() + + if(VCPKG_TARGET_TRIPLET) + list(APPEND init_vcpkg + "set(VCPKG_TARGET_TRIPLET \"${VCPKG_TARGET_TRIPLET}\" CACHE STRING \"\")") + endif() + + # By default we don't want to allow mixing compilers for building different repositories, so we + # embed the initially chosen compilers into the toolchain. + # This is because on Windows compilers aren't easily mixed. + # We want to avoid that qtbase is built using cl.exe for example, and then for another repo + # gcc is picked up from %PATH%. + # The same goes when using a custom compiler on other platforms, such as ICC. + # + # There are a few exceptions though. + # + # When crosscompiling using Boot2Qt, the environment setup shell script sets up the CXX env var, + # which is used by CMake to determine the initial compiler that should be used. + # Unfortunately, the CXX env var contains not only the compiler name, but also a few required + # arch-specific compiler flags. This means that when building qtsvg, if the Qt created toolchain + # file sets the CMAKE_CXX_COMPILER variable, the CXX env var is ignored and thus the extra + # arch specific compiler flags are not picked up anymore, leading to a configuration failure. + # + # To avoid this issue, disable automatic embedding of the compilers into the qt toolchain when + # cross compiling. This is merely a heuristic, becacuse we don't have enough data to decide + # when to do it or not. + # For example on Linux one might want to allow mixing of clang and gcc (maybe). + # + # To allow such use cases when the default is wrong, one can provide a flag to explicitly opt-in + # or opt-out of the compiler embedding into the Qt toolchain. + # + # Passing -DQT_EMBED_TOOLCHAIN_COMPILER=ON will force embedding of the compilers. + # Passing -DQT_EMBED_TOOLCHAIN_COMPILER=OFF will disable embedding of the compilers. + set(__qt_embed_toolchain_compilers TRUE) + if(CMAKE_CROSSCOMPILING) + set(__qt_embed_toolchain_compilers FALSE) + endif() + if(DEFINED QT_EMBED_TOOLCHAIN_COMPILER) + if(QT_EMBED_TOOLCHAIN_COMPILER) + set(__qt_embed_toolchain_compilers TRUE) + else() + set(__qt_embed_toolchain_compilers FALSE) + endif() + endif() + if(__qt_embed_toolchain_compilers) + list(APPEND init_platform " + set(__qt_initial_c_compiler \"${CMAKE_C_COMPILER}\") + set(__qt_initial_cxx_compiler \"${CMAKE_CXX_COMPILER}\") + if(NOT DEFINED CMAKE_C_COMPILER AND EXISTS \"\${__qt_initial_c_compiler}\") + set(CMAKE_C_COMPILER \"\${__qt_initial_c_compiler}\" CACHE STRING \"\") + endif() + if(NOT DEFINED CMAKE_CXX_COMPILER AND EXISTS \"\${__qt_initial_cxx_compiler}\") + set(CMAKE_CXX_COMPILER \"\${__qt_initial_cxx_compiler}\" CACHE STRING \"\") + endif()") + endif() + + if(APPLE) + # For simulator_and_device build, we should not explicitly set the sysroot. + list(LENGTH CMAKE_OSX_ARCHITECTURES _qt_osx_architectures_count) + if(CMAKE_OSX_SYSROOT AND NOT _qt_osx_architectures_count GREATER 1 AND UIKIT) + list(APPEND init_platform " + set(__qt_initial_cmake_osx_sysroot \"${CMAKE_OSX_SYSROOT}\") + if(NOT DEFINED CMAKE_OSX_SYSROOT AND EXISTS \"\${__qt_initial_cmake_osx_sysroot}\") + set(CMAKE_OSX_SYSROOT \"\${__qt_initial_cmake_osx_sysroot}\" CACHE PATH \"\") + endif()") + endif() + + if(CMAKE_OSX_DEPLOYMENT_TARGET) + list(APPEND init_platform + "set(CMAKE_OSX_DEPLOYMENT_TARGET \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" CACHE STRING \"\")") + endif() + + if(UIKIT) + list(APPEND init_platform + "set(CMAKE_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\" CACHE STRING \"\")") + set(_qt_osx_architectures_escaped "${CMAKE_OSX_ARCHITECTURES}") + string(REPLACE ";" "LITERAL_SEMICOLON" + _qt_osx_architectures_escaped "${_qt_osx_architectures_escaped}") + list(APPEND init_platform + "set(CMAKE_OSX_ARCHITECTURES \"${_qt_osx_architectures_escaped}\" CACHE STRING \"\")") + + list(APPEND init_platform "if(CMAKE_GENERATOR STREQUAL \"Xcode\" AND NOT QT_NO_XCODE_EMIT_EPN)") + list(APPEND init_platform " set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME OFF)") + list(APPEND init_platform "endif()") + endif() + elseif(ANDROID) + list(APPEND init_platform + "set(ANDROID_NATIVE_API_LEVEL \"${ANDROID_NATIVE_API_LEVEL}\" CACHE STRING \"\")") + list(APPEND init_platform "set(ANDROID_STL \"${ANDROID_STL}\" CACHE STRING \"\")") + list(APPEND init_platform "set(ANDROID_ABI \"${ANDROID_ABI}\" CACHE STRING \"\")") + list(APPEND init_platform "if (NOT DEFINED ANDROID_SDK_ROOT)") + file(TO_CMAKE_PATH "${ANDROID_SDK_ROOT}" __qt_android_sdk_root) + list(APPEND init_platform + " set(ANDROID_SDK_ROOT \"${__qt_android_sdk_root}\" CACHE STRING \"\")") + list(APPEND init_platform "endif()") + endif() + + string(REPLACE ";" "\n" init_vcpkg "${init_vcpkg}") + string(REPLACE ";" "\n" init_platform "${init_platform}") + string(REPLACE "LITERAL_SEMICOLON" ";" init_platform "${init_platform}") + qt_compute_relative_path_from_cmake_config_dir_to_prefix() + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt.toolchain.cmake.in" + "${__GlobalConfig_build_dir}/qt.toolchain.cmake" @ONLY) + qt_install(FILES "${__GlobalConfig_build_dir}/qt.toolchain.cmake" + DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel) +endfunction() |