Details
-
Suggestion
-
Resolution: Won't Do
-
Not Evaluated
-
None
-
5.12.0 Beta 3
-
None
-
Qt 5.12x
Android
macOS, iOS
or any other with -fvisibility-inlines-hidden cflag
Description
The QV4::FunctionObject::isBinding() function is declared as inline function in 5.12, and can not be linked properly any more.
The windows (msvc) or Qt < 5.12 works without this issue.
In 5.12, the compiler will report the following error:
..\..\..\Qt\5.12.0\android_armv7\include\QtQml\5.12.0\QtQml\private/qqmlbuiltinfunctions_p.h:0: error: undefined reference to 'QV4::QQmlBindingFunction::static_vtbl'
It appears -fvisibility-inlines-hidden will cause inline function not exported normally, and need to be inline when compiling. It is fine as long as the inline function does not reference other non-exported function. But in QV4::FunctionObject::isBinding() case, it will cause the linking error, and there is no way to fix the issue without heavy hack. e.g.
static bool isBinding(QObject* obj, QV4::FunctionObject* func) { #if defined(QT_STATIC) || QT_VERSION < QT_VERSION_CHECK(5, 12, 0) return func && func->isBinding(); #else // due to QV4::FunctionObject::isBinding() become inline function and not exported from shared library // we can't get it linked properly any more, thus need to reproduce the function here // the gotcha is to get vtable of binding and compare it with func->vtable() static const void* _vtable_binding = nullptr; if (!_vtable_binding) { auto engine = qmlEngine(obj); auto expr = engine->evaluate("Qt.binding(function() { return Qt.application.active; })"); auto& value = *QJSValuePrivate::getValue(&expr); auto binding = value.as<QV4::FunctionObject>(); _vtable_binding = binding->vtable(); } return func && func->vtable() == _vtable_binding; #endif }
It would be great if there is some kind of helper function for external linking, like
bool qt_FunctionObject_isBinding(QV4::FunctionObject* func);
or revert the function to non-inline.