Remove Qt_6_PRIVATE_API ELF version from a symbol used by QFuture::then()

QFuture::then() uses QtPrivate::Continuation::create(), which in turn
uses private API from an inline function:

    f->d.setContinuation(ContinuationWrapper(std::move(continuation)), fi.d);

f->d is QFutureInterfaceBase (a public class), but its setContinuation()
takes QFutureInterfaceBasePrivate by pointer. Our ELF versioning scripts
mark everything that uses that class as private, resulting in:

 4806: 0000000000287d70    365 FUNC    GLOBAL PROTECTED     16 _ZN20QFutureInterfaceBase15setContinuationESt8functionIFvRKS_EEP27QFutureInterfaceBasePrivate@@Qt_6_PRIVATE_API

This commit adds an exception for this symbol, causing it to go back to
the regular "Qt_6" ELF version:

 5629: 00000000003d6a16    366 FUNC    GLOBAL PROTECTED     16 _ZN20QFutureInterfaceBase15setContinuationESt8functionIFvRKS_EEP27QFutureInterfaceBasePrivate@@Qt_6

This solution can probably be cleaned up a bit by moving the marker into
the header files parsed by syncqt, so they follow code motion without
having to remember to update the CMakeLists.txt. That requires some
surgery with syncqt, so not suitable for cherry-picking.

As a drive-by, fix the target_type check
for the _qt_extra_linker_script_content genex property

Fixes: QTBUG-117514
Pick-to: 6.6
Change-Id: I85599ea5ca7a4b79a8bbfffd178b92e73dbe11de
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Thiago Macieira 2023-10-06 09:53:26 -07:00 committed by Alexandru Croitor
parent 042c38379f
commit 0f0371c830
3 changed files with 44 additions and 2 deletions

View File

@ -1,6 +1,23 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Sets '${var}' to a genex that extracts the target's property.
# Sets 'have_${var}' to a genex that checks that the property has a
# non-empty value.
macro(qt_internal_genex_get_property var target property)
set(${var} "$<TARGET_PROPERTY:${target},${property}>")
set(have_${var} "$<BOOL:${${var}}>")
endmacro()
# Sets '${var}' to a genex that will join the given property values
# using '${glue}' and will surround the entire output with '${prefix}'
# and '${suffix}'.
macro(qt_internal_genex_get_joined_property var target property prefix suffix glue)
qt_internal_genex_get_property("${var}" "${target}" "${property}")
set(${var}
"$<${have_${var}}:${prefix}$<JOIN:${${var}},${glue}>${suffix}>")
endmacro()
# This function generates LD version script for the target and uses it in the target linker line.
# Function has two modes dependending on the specified arguments.
# Arguments:
@ -62,9 +79,21 @@ function(qt_internal_add_linker_version_script target)
endif()
string(APPEND contents "};\n")
set(current "Qt_${PROJECT_VERSION_MAJOR}")
string(APPEND contents "${current} { *; };\n")
string(APPEND contents "${current} {\n *;")
get_target_property(target_type ${target} TYPE)
if(NOT target_type STREQUAL "INTERFACE_LIBRARY")
set(genex_prefix "\n ")
set(genex_glue "$<SEMICOLON>\n ")
set(genex_suffix "$<SEMICOLON>")
qt_internal_genex_get_joined_property(
linker_exports "${target}" _qt_extra_linker_script_exports
"${genex_prefix}" "${genex_suffix}" "${genex_glue}"
)
string(APPEND contents "${linker_exports}")
endif()
string(APPEND contents "\n};\n")
get_target_property(type ${target} TYPE)
if(NOT target_type STREQUAL "INTERFACE_LIBRARY")
set(property_genex "$<TARGET_PROPERTY:${target},_qt_extra_linker_script_content>")
set(check_genex "$<BOOL:${property_genex}>")

View File

@ -16,6 +16,8 @@
# Custom compilation flags.
# EXTRA_LINKER_SCRIPT_CONTENT
# Extra content that should be appended to a target linker script. Applicable for ld only.
# EXTRA_LINKER_SCRIPT_EXPORTS
# Extra content that should be added to export section of the linker script.
# NO_PCH_SOURCES
# Skip the specified source files by PRECOMPILE_HEADERS feature.
function(qt_internal_extend_target target)
@ -51,6 +53,7 @@ function(qt_internal_extend_target target)
CONDITION
CONDITION_INDEPENDENT_SOURCES
COMPILE_FLAGS
EXTRA_LINKER_SCRIPT_EXPORTS
)
cmake_parse_arguments(PARSE_ARGV 1 arg
@ -260,6 +263,10 @@ function(qt_internal_extend_target target)
set_target_properties(${target} PROPERTIES
_qt_extra_linker_script_content "${arg_EXTRA_LINKER_SCRIPT_CONTENT}")
endif()
if(arg_EXTRA_LINKER_SCRIPT_EXPORTS)
set_target_properties(${target} PROPERTIES
_qt_extra_linker_script_exports "${arg_EXTRA_LINKER_SCRIPT_EXPORTS}")
endif()
endfunction()
function(qt_is_imported_target target out_var)

View File

@ -1450,4 +1450,10 @@ foreach(minor_version RANGE ${PROJECT_VERSION_MINOR})
endforeach()
qt_internal_extend_target(Core
EXTRA_LINKER_SCRIPT_CONTENT "${linker_script_contents}"
# Workaround for QTBUG-117514:
# Function called by inline methods taking a pointer to a private class as a parameter
EXTRA_LINKER_SCRIPT_EXPORTS
# QFutureInterfaceBase::setContinuation(std::function<void (QFutureInterfaceBase const&)>, QFutureInterfaceBasePrivate*)
"_ZN20QFutureInterfaceBase15setContinuationE*P27QFutureInterfaceBasePrivate"
)