qt5base-lts/cmake/QtBaseConfigureTests.cmake
Alexey Rochev d68dbd8b7d Fix version script test
1. Don't reassign different versions to same symbol
2. Define symbols used
This fixes warnings with LLD linker (or errors if -Wl,--fatal-warnings is added by toolchain e.g. with Android NDK)
3. Add -Wl,--version-script to CMAKE_REQUIRED_LINK_OPTIONS instead of CMAKE_REQUIRED_FLAGS to prevent unused argument warning in compilation phase
(there is no need for _SAVE variable because we are inside a function and our CMAKE_REQUIRED_LINK_OPTIONS won't escase its scope)
4. Fix removal of version script file (incorrect file name was used)

Pick-to: 6.2 6.5
Task-number: QTBUG-111514
Change-Id: I0a1548c4268ad511760a0d4aa69ba7a0bdcbb0bc
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2023-05-30 23:25:57 +03:00

282 lines
12 KiB
CMake

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
include(CheckCXXSourceCompiles)
function(qt_run_config_test_architecture)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT
"" CACHE INTERNAL "Test variables that should be exported" FORCE)
# Compile test to find the target architecture and sub-architectures.
set(flags "")
qt_get_platform_try_compile_vars(platform_try_compile_vars)
list(APPEND flags ${platform_try_compile_vars})
list(TRANSFORM flags PREPEND " " OUTPUT_VARIABLE flags_indented)
list(JOIN flags_indented "\n" flags_indented)
message(STATUS
"Building architecture extraction project with the following CMake arguments:")
list(POP_BACK CMAKE_MESSAGE_CONTEXT _context)
message(NOTICE ${flags_indented})
list(APPEND CMAKE_MESSAGE_CONTEXT ${_context})
try_compile(
_arch_result
"${CMAKE_CURRENT_BINARY_DIR}/config.tests/arch"
"${CMAKE_CURRENT_SOURCE_DIR}/config.tests/arch"
arch
CMAKE_FLAGS ${flags}
OUTPUT_VARIABLE arch_test_output
)
if (NOT _arch_result)
message(FATAL_ERROR
"Failed to build architecture extraction project. Build output:\n ${arch_test_output}")
endif()
set(_arch_file_suffix "${CMAKE_EXECUTABLE_SUFFIX}")
# With emscripten the application entry point is a .js file (to be run with node for example),
# but the real "data" is in the .wasm file, so that's where we need to look for the ABI, etc.
# information.
if (WASM)
set(_arch_file_suffix ".wasm")
endif()
set(arch_test_location "config.tests/arch")
if(QT_MULTI_CONFIG_FIRST_CONFIG)
string(APPEND arch_test_location "/${QT_MULTI_CONFIG_FIRST_CONFIG}")
endif()
set(arch_dir "${CMAKE_CURRENT_BINARY_DIR}/${arch_test_location}")
file(GLOB arch_dir_globbed_files RELATIVE "${arch_dir}" "${arch_dir}/*")
list(JOIN arch_dir_globbed_files "\n" arch_dir_globbed_files)
set(_arch_file
"${CMAKE_CURRENT_BINARY_DIR}/${arch_test_location}/architecture_test${_arch_file_suffix}")
if (NOT EXISTS "${_arch_file}")
message(FATAL_ERROR
"Failed to find compiled architecture detection executable at ${_arch_file}. \
The following files were found at: ${arch_dir} \
${arch_dir_globbed_files}")
endif()
message(STATUS "Extracting architecture info from ${_arch_file}.")
file(STRINGS "${_arch_file}" _arch_lines LENGTH_MINIMUM 16 LENGTH_MAXIMUM 1024 ENCODING UTF-8
REGEX "==Qt=magic=Qt==")
foreach (_line ${_arch_lines})
string(LENGTH "${_line}" lineLength)
string(FIND "${_line}" "==Qt=magic=Qt== Architecture:" _pos)
if (_pos GREATER -1)
math(EXPR _pos "${_pos}+29")
string(SUBSTRING "${_line}" ${_pos} -1 _architecture)
endif()
string(FIND "${_line}" "==Qt=magic=Qt== Sub-architecture:" _pos)
if (_pos GREATER -1 AND ${lineLength} GREATER 33)
math(EXPR _pos "${_pos}+34")
string(SUBSTRING "${_line}" ${_pos} -1 _sub_architecture)
string(REPLACE " " ";" _sub_architecture "${_sub_architecture}")
endif()
string(FIND "${_line}" "==Qt=magic=Qt== Build-ABI:" _pos)
if (_pos GREATER -1)
math(EXPR _pos "${_pos}+26")
string(SUBSTRING "${_line}" ${_pos} -1 _build_abi)
endif()
endforeach()
if (NOT _architecture OR NOT _build_abi)
list(SUBLIST _arch_lines 0 5 arch_lines_fewer)
list(JOIN arch_lines_fewer "\n" arch_lines_output)
message(FATAL_ERROR
"Failed to extract architecture data from file. \
Here are the first few lines extracted:\n${arch_lines_output}")
endif()
set(TEST_architecture 1 CACHE INTERNAL "Ran the architecture test")
set(TEST_architecture_arch "${_architecture}" CACHE INTERNAL "Target machine architecture")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_architecture_arch)
set(TEST_subarch 1 CACHE INTERNAL "Ran machine subArchitecture test")
set(TEST_subarch_result "${_sub_architecture}" CACHE INTERNAL "Target sub-architectures")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_subarch_result)
foreach(it ${_sub_architecture})
# Equivalent to qmake's QT_CPU_FEATURES.$arch.
set(TEST_arch_${TEST_architecture_arch}_subarch_${it} 1 CACHE INTERNAL "Target sub architecture result")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_arch_${TEST_architecture_arch}_subarch_${it})
endforeach()
set(TEST_buildAbi "${_build_abi}" CACHE INTERNAL "Target machine buildAbi")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_buildAbi)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT} CACHE INTERNAL "Test variables that should be exported")
list(JOIN _sub_architecture " " subarch_summary)
set_property(GLOBAL PROPERTY qt_configure_subarch_summary "${subarch_summary}")
endfunction()
function(qt_run_linker_version_script_support)
# For some reason the linker command line written by the XCode generator, which is
# subsequently executed by xcodebuild, ignores the linker flag, and thus the test
# seemingly succeeds. Explicitly disable the version script test on darwin platforms.
# Also makes no sense with MSVC-style command-line
if(NOT APPLE AND NOT MSVC)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/version_flag.map" [=[
VERS_1 { global: sym1; };
VERS_2 { global: sym2; } VERS_1;
]=])
set(CMAKE_REQUIRED_LINK_OPTIONS "")
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS
"-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_flag.map")
# Pass the linker that the main project uses to the version script compile test.
qt_internal_get_active_linker_flags(linker_flags)
if(linker_flags)
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${linker_flags})
endif()
check_cxx_source_compiles([=[
int sym1;
int sym2;
int main(void) { return 0; }
]=] HAVE_LD_VERSION_SCRIPT)
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/version_flag.map")
else()
set(HAVE_LD_VERSION_SCRIPT OFF)
endif()
set(TEST_ld_version_script "${HAVE_LD_VERSION_SCRIPT}"
CACHE INTERNAL "linker version script support")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_ld_version_script)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT}
CACHE INTERNAL "Test variables that should be exported")
endfunction()
function(qt_internal_ensure_latest_win_nt_api)
if(NOT WIN32)
return()
endif()
check_cxx_source_compiles([=[
#include <windows.h>
#if !defined(_WIN32_WINNT) && !defined(WINVER)
#error "_WIN32_WINNT and WINVER are not defined"
#endif
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0A00)
#error "_WIN32_WINNT version too low"
#endif
#if defined(WINVER) && (WINVER < 0x0A00)
#error "WINVER version too low"
#endif
int main() { return 0; }
]=] HAVE_WIN10_WIN32_WINNT)
if(NOT HAVE_WIN10_WIN32_WINNT)
list(APPEND QT_PLATFORM_DEFINITIONS _WIN32_WINNT=0x0A00 WINVER=0x0A00)
set(QT_PLATFORM_DEFINITIONS ${QT_PLATFORM_DEFINITIONS}
CACHE STRING "Qt platform specific pre-processor defines" FORCE)
endif()
endfunction()
function(qt_run_qtbase_config_tests)
qt_run_config_test_architecture()
qt_internal_ensure_latest_win_nt_api()
endfunction()
# The qmake build of android does not perform the right architecture tests and
# forcefully disables sse4 on android x86. We have to mimic this behavior
# for now
if (CMAKE_ANDROID_ARCH_ABI STREQUAL x86)
set(QT_FEATURE_sse4_1 OFF CACHE BOOL INTERNAL FORCE)
set(QT_FEATURE_sse4_2 OFF CACHE BOOL INTERNAL FORCE)
set(TEST_subarch_sse4_1 FALSE CACHE BOOL INTERNAL FORCE)
set(TEST_subarch_sse4_2 FALSE CACHE BOOL INTERNAL FORCE)
endif()
qt_run_qtbase_config_tests()
function(qt_internal_print_cmake_darwin_info)
if(APPLE)
if(NOT CMAKE_OSX_ARCHITECTURES)
set(default_osx_arch " (defaults to ${CMAKE_SYSTEM_PROCESSOR})")
endif()
message(STATUS "CMAKE_OSX_ARCHITECTURES: \"${CMAKE_OSX_ARCHITECTURES}\"${default_osx_arch}")
message(STATUS "CMAKE_OSX_SYSROOT: \"${CMAKE_OSX_SYSROOT}\"")
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: \"${CMAKE_OSX_DEPLOYMENT_TARGET}\"")
message(STATUS "QT_MAC_SDK_VERSION: \"${QT_MAC_SDK_VERSION}\"")
message(STATUS "QT_MAC_XCODE_VERSION: \"${QT_MAC_XCODE_VERSION}\"")
if(DEFINED CACHE{QT_IS_MACOS_UNIVERSAL})
message(STATUS "QT_IS_MACOS_UNIVERSAL: \"${QT_IS_MACOS_UNIVERSAL}\"")
endif()
if(QT_UIKIT_SDK)
message(STATUS "QT_UIKIT_SDK: \"${QT_UIKIT_SDK}\"")
endif()
qt_internal_get_first_osx_arch(osx_first_arch)
if(osx_first_arch)
message(STATUS "Configure tests main architecture (in multi-arch build): \"${osx_first_arch}\"")
endif()
endif()
endfunction()
qt_internal_print_cmake_darwin_info()
function(qt_internal_print_cmake_host_and_target_info)
message(STATUS "CMAKE_VERSION: \"${CMAKE_VERSION}\"")
message(STATUS "CMAKE_HOST_SYSTEM: \"${CMAKE_HOST_SYSTEM}\"")
message(STATUS "CMAKE_HOST_SYSTEM_NAME: \"${CMAKE_HOST_SYSTEM_NAME}\"")
message(STATUS "CMAKE_HOST_SYSTEM_VERSION: \"${CMAKE_HOST_SYSTEM_VERSION}\"")
message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR: \"${CMAKE_HOST_SYSTEM_PROCESSOR}\"")
message(STATUS "CMAKE_SYSTEM: \"${CMAKE_SYSTEM_NAME}\"")
message(STATUS "CMAKE_SYSTEM_NAME: \"${CMAKE_SYSTEM_NAME}\"")
message(STATUS "CMAKE_SYSTEM_VERSION: \"${CMAKE_SYSTEM_VERSION}\"")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: \"${CMAKE_SYSTEM_PROCESSOR}\"")
message(STATUS "CMAKE_CROSSCOMPILING: \"${CMAKE_CROSSCOMPILING}\"")
endfunction()
qt_internal_print_cmake_host_and_target_info()
function(qt_internal_print_prefix_info)
message(STATUS "CMAKE_INSTALL_PREFIX: \"${CMAKE_INSTALL_PREFIX}\"")
message(STATUS "CMAKE_STAGING_PREFIX: \"${CMAKE_STAGING_PREFIX}\"")
message(STATUS "QT_BUILD_DIR: \"${QT_BUILD_DIR}\"")
message(STATUS "QT_INSTALL_DIR: \"${QT_INSTALL_DIR}\"")
message(STATUS "QT_WILL_INSTALL: \"${QT_WILL_INSTALL}\"")
endfunction()
qt_internal_print_prefix_info()
function(qt_internal_print_cmake_compiler_info)
message(STATUS "CMAKE_C_COMPILER: \"${CMAKE_C_COMPILER}\" (${CMAKE_C_COMPILER_VERSION})")
message(STATUS "CMAKE_CXX_COMPILER: \"${CMAKE_CXX_COMPILER}\" (${CMAKE_CXX_COMPILER_VERSION})")
if(CMAKE_OBJC_COMPILER)
message(STATUS "CMAKE_OBJC_COMPILER: \"${CMAKE_OBJC_COMPILER}\" (${CMAKE_OBJC_COMPILER_VERSION})")
endif()
if(CMAKE_OBJCXX_COMPILER)
message(STATUS "CMAKE_OBJCXX_COMPILER: \"${CMAKE_OBJCXX_COMPILER}\" (${CMAKE_OBJCXX_COMPILER_VERSION})")
endif()
endfunction()
qt_internal_print_cmake_compiler_info()
function(qt_internal_print_cmake_windows_info)
if(MSVC_VERSION)
message(STATUS "MSVC_VERSION: \"${MSVC_VERSION}\"")
endif()
if(MSVC_TOOLSET_VERSION)
message(STATUS "MSVC_TOOLSET_VERSION: \"${MSVC_TOOLSET_VERSION}\"")
endif()
endfunction()
qt_internal_print_cmake_windows_info()
function(qt_internal_print_cmake_android_info)
if(ANDROID)
message(STATUS "ANDROID_TOOLCHAIN: \"${ANDROID_TOOLCHAIN}\"")
message(STATUS "ANDROID_NDK: \"${ANDROID_NDK}\"")
message(STATUS "ANDROID_ABI: \"${ANDROID_ABI}\"")
message(STATUS "ANDROID_PLATFORM: \"${ANDROID_PLATFORM}\"")
message(STATUS "ANDROID_NATIVE_API_LEVEL: \"${ANDROID_NATIVE_API_LEVEL}\"")
message(STATUS "ANDROID_STL: \"${ANDROID_STL}\"")
message(STATUS "ANDROID_PIE: \"${ANDROID_PIE}\"")
message(STATUS "ANDROID_CPP_FEATURES: \"${ANDROID_CPP_FEATURES}\"")
message(STATUS "ANDROID_ALLOW_UNDEFINED_SYMBOLS: \"${ANDROID_ALLOW_UNDEFINED_SYMBOLS}\"")
message(STATUS "ANDROID_ARM_MODE: \"${ANDROID_ARM_MODE}\"")
message(STATUS "ANDROID_ARM_NEON: \"${ANDROID_ARM_NEON}\"")
message(STATUS "ANDROID_DISABLE_FORMAT_STRING_CHECKS: \"${ANDROID_DISABLE_FORMAT_STRING_CHECKS}\"")
message(STATUS "ANDROID_LLVM_TRIPLE: \"${ANDROID_LLVM_TRIPLE}\"")
endif()
endfunction()
qt_internal_print_cmake_android_info()