Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-93471

Darwin linker warns about global weak symbols when linking an executable against a static Qt

    XMLWordPrintable

    Details

    • Platform/s:
      iOS/tvOS/watchOS, macOS

      Description

      When linking an executable against a Qt 6 static build (either with CMake or qmake) you get the following kind of warnings (this is from the qtbase/examples/widgets/widgets/tetrix)

      # static Qt dev + qmake tetrix example
      
      
      
      ld: warning: direct access in function 
       
       'QtPrivate::QMetaTypeInterface const* QtPrivate::qMetaTypeInterfaceForType<int>()' from file 
        
         '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Widgets_debug.a(qabstractitemview.cpp.o)' 
      
        to global weak symbol 'QtPrivate::QMetaTypeInterfaceWrapper<int>::metaType' 
      
         from file '.obj/moc_tetrixboard.o' 
      
         means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeForType<int>::getDefaultCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*)::operator void (*)(QtPrivate::QMetaTypeInterface const*, void*)() const' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QtPrivate::QMetaTypeForType<int>::getDefaultCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*)::__invoke(QtPrivate::QMetaTypeInterface const*, void*)' from file '.obj/moc_tetrixboard.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeForType<int>::getCopyCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*, void const*)::operator void (*)(QtPrivate::QMetaTypeInterface const*, void*, void const*)() const' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QtPrivate::QMetaTypeForType<int>::getCopyCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*, void const*)::__invoke(QtPrivate::QMetaTypeInterface const*, void*, void const*)' from file '.obj/moc_tetrixboard.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeForType<int>::getMoveCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*, void*)::operator void (*)(QtPrivate::QMetaTypeInterface const*, void*, void*)() const' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QtPrivate::QMetaTypeForType<int>::getMoveCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*, void*)::__invoke(QtPrivate::QMetaTypeInterface const*, void*, void*)' from file '.obj/moc_tetrixboard.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeForType<int>::getName()' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QMetaTypeId2<int>::nameAsArray' from file '.obj/moc_tetrixboard.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeInterface const* QtMetaTypePrivate::getInterfaceFromType<int>()' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QtPrivate::QMetaTypeInterfaceWrapper<int>::metaType' from file '.obj/moc_tetrixboard.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      makeobj[0]: Leaving directory `/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/one_test_qmake'
      
      
      
      # static Qt dev + cmake tetrix example
      
      
      ld: warning: direct access in function 
       
        'QtPrivate::QMetaTypeInterface const* QtPrivate::qMetaTypeInterfaceForType<int>()' from file 
      
          '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Widgets_debug.a(qabstractitemview.cpp.o)' 
      
       to global weak symbol 
      
         'QtPrivate::QMetaTypeInterfaceWrapper<int>::metaType' 
      
           from file 'CMakeFiles/tetrix.dir/tetrix_autogen/mocs_compilation.cpp.o' 
      
           means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings
      
      
      ld: warning: direct access in function 'QtPrivate::QMetaTypeInterface const* QtMetaTypePrivate::getInterfaceFromType<int>()' from file '/Volumes/T3/Dev/qt/qt5_cmake/builds/dev-mac-static/qtbase/lib/libQt6Core_debug.a(qmetatype.cpp.o)' to global weak symbol 'QtPrivate::QMetaTypeInterfaceWrapper<int>::metaType' from file 'CMakeFiles/tetrix.dir/tetrix_autogen/mocs_compilation.cpp.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
      

      In Qt5 + qmake land we set visibility == hidden only for qt apps / executables, not public project executables as demonstrated by this change
      https://codereview.qt-project.org/c/qt/qtbase/+/287931

      This was replicated in Qt6 CMake land with https://codereview.qt-project.org/c/qt/qtbase/+/305616

      in the mean time Qt added QMetaTypeInterfaceWrapper template types in https://codereview.qt-project.org/c/qt/qtbase/+/316919 which were not present in Qt 5 times.

      Now when a user project links against a static Qt, you get the visibility warnings above

      Qt itself is compiled with -fvisibility=hidden flags, but the public project executables don't get the -fvisibility=hidden flags.

      It appears we instantiate the above templates in the in the moc generated files ( so in the user project that doesn't get the visibility == hidden flags), and we get a visbility mismatch.

      I'm not sure how this is supposed to be solved.

      Perhaps by adding visibility=hidden C++ attributes to the template types source files / headers? e.g. _attribute_ ((visibility ("hidden")))

      We might also want to add an auto test, so this doesn't regress again if we find how to fix it.

        Attachments

          Issue Links

          For Gerrit Dashboard: QTBUG-93471
          # Subject Branch Project Status CR V

            Activity

              People

              Assignee:
              fabiankosmale Fabian Kosmale
              Reporter:
              alexandru.croitor Alexandru Croitor
              Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:

                  Gerrit Reviews

                  There are no open Gerrit changes