qt5base-lts/cmake/QtPlatformTargetHelpers.cmake

79 lines
3.1 KiB
CMake
Raw Normal View History

# Defines the public Qt::Platform target, which serves as a dependency for all internal Qt target
# as well as user projects consuming Qt.
function(qt_internal_setup_public_platform_target)
qt_internal_get_platform_definition_include_dir(
install_interface_definition_dir
build_interface_definition_dir
)
## QtPlatform Target:
add_library(Platform INTERFACE)
add_library(Qt::Platform ALIAS Platform)
add_library(${INSTALL_CMAKE_NAMESPACE}::Platform ALIAS Platform)
target_include_directories(Platform
INTERFACE
$<BUILD_INTERFACE:${build_interface_definition_dir}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${install_interface_definition_dir}>
$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}>
)
target_compile_definitions(Platform INTERFACE ${QT_PLATFORM_DEFINITIONS})
# When building on android we need to link against the logging library
# in order to satisfy linker dependencies. Both of these libraries are part of
# the NDK.
if (ANDROID)
target_link_libraries(Platform INTERFACE log)
endif()
if (QT_FEATURE_stdlib_libcpp)
target_compile_options(Platform INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>")
set(libc_link_option "-stdlib=libc++")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")
set(libc_link_option "$<$<LINK_LANGUAGE:CXX>:-stdlib=libc++>")
endif()
target_link_options(Platform INTERFACE "${libc_link_option}")
endif()
Enable -mno-direct-extern-access and ELF protected visibility The -mno-direct-extern-access tells the compiler and linker that references to symbols outside this ELF module mustn't be direct and must instead always go through the GOT or PLT (the PLT can additionally be disabled with -fno-plt). The ELF protected visibility tells the compiler and linker that this symbol is present in the dynamic symbol table as an export, but it cannot be interposed by another ELF module. This option is required for user code to link properly to Qt, otherwise they will get linker errors (assuming GNU binutils >= 2.39) or runtime failures (glibc >= 2.35). Both versions of glibc and binutils are older than GCC 12, so it's a safe assumption they are in use and downgrading the toolchain or libc is not supported. Adding this option to the compilation is assured for CMake and qmake-based projects. For example, all accessess to QCoreApplication::self in QtCore, after this change and with GCC 12 are relocation-free and direct: 000000000013ebf0 <QCoreApplicationPrivate::checkInstance(char const*)>: 13ebf0: cmpq $0x0,0x4f73d0(%rip) # 635fc8 <QCoreApplication::self> 13ebf8: setne %al 13ebfb: je a90fe <QCoreApplicationPrivate::checkInstance(char const*) [clone .cold]> 13ec01: ret Meanwhile, accesses to the same variable in other modules are indirect via the GOT: 66650: mov 0x876e1(%rip),%rax # edd38 <QCoreApplication::self@Qt_6> 66657: cmpq $0x0,(%rax) This replaces the -Bsymbolic and -Bsymbolic-functions (broken) functionality that Qt has been using or attempting to use since ~2006. See https://gitlab.com/x86-psABIs/x86-64-ABI/-/issues/8#note_606975128 Change-Id: Iad4b0a3e5c06570b9f5f571b26ed564aa0811e47 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2012-01-23 13:46:58 +00:00
if (QT_FEATURE_no_extern_direct_access)
target_compile_options(Platform INTERFACE "-mno-direct-extern-access")
endif()
qt_set_msvc_cplusplus_options(Platform INTERFACE)
# Propagate minimum C++ 17 via Platform to Qt consumers (apps), after the global features
# are computed.
qt_set_language_standards_interface_compile_features(Platform)
# By default enable utf8 sources for both Qt and Qt consumers. Can be opted out.
qt_enable_utf8_sources(Platform)
# By default enable unicode on WIN32 platforms for both Qt and Qt consumers. Can be opted out.
qt_internal_enable_unicode_defines(Platform)
# Generate a pkgconfig for Qt::Platform.
qt_internal_generate_pkg_config_file(Platform)
endfunction()
function(qt_internal_get_platform_definition_include_dir install_interface build_interface)
# Used by consumers of prefix builds via INSTALL_INTERFACE (relative path).
set(${install_interface} "${INSTALL_MKSPECSDIR}/${QT_QMAKE_TARGET_MKSPEC}" PARENT_SCOPE)
# Used by qtbase in prefix builds via BUILD_INTERFACE
set(build_interface_base_dir
"${CMAKE_CURRENT_LIST_DIR}/../mkspecs"
)
# Used by qtbase and consumers in non-prefix builds via BUILD_INTERFACE
if(NOT QT_WILL_INSTALL)
set(build_interface_base_dir
"${QT_BUILD_DIR}/${INSTALL_MKSPECSDIR}"
)
endif()
get_filename_component(build_interface_dir
"${build_interface_base_dir}/${QT_QMAKE_TARGET_MKSPEC}"
ABSOLUTE
)
set(${build_interface} "${build_interface_dir}" PARENT_SCOPE)
endfunction()