Why does a Qt program look wrong when compiled as a macOS bundle but fine as an unbundled executable?

Viewed 103

I build a Qt5-based GUI program on macOS 10.15.7 with CMake. I normally simply build a dynamically-linked executable with add_executable(). It looks fine:

enter image description here

I experimented a bit with CMake's BundleUtilities module and when I finally got something runnable, it launches and runs fine, but the GUI is buggy, i.e. the buttons don't have faces and the scrollbars are kind of invisible.

enter image description here

The app bundle is created so that it is self-contained, and contains the libqcocoa.dylib platform plugin.

What could be the reason for this behaviour?


For reference, this code generates the .app


  set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR})

  set(prefix "myApp.app/Contents")
  set(INSTALL_RUNTIME_DIR "${prefix}/MacOS")
  set(INSTALL_CMAKE_DIR "${prefix}/Resources")
  set(QT_PLUGIN_DIR "${prefix}/PlugIns")

  # based on code from CMakes QtDialog/CMakeLists.txt
  macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix)
      get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
      if(EXISTS "${_qt_plugin_path}")
          get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
          get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
          get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
          set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}")
          install(FILES "${_qt_plugin_path}"
              DESTINATION "${_qt_plugin_dest}")
          set(${_qt_plugins_var}
              "${${_qt_plugins_var}};\$ENV{DEST_DIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
      else()
          message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
      endif()
  endmacro()

  install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS ${prefix})
  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
      "[Paths]\nPlugins = ${QT_PLUGIN_DIR}\n")
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
      DESTINATION "${INSTALL_CMAKE_DIR}")

  # Destination paths below are relative to ${CMAKE_INSTALL_PREFIX}
  install(TARGETS myApp
      BUNDLE DESTINATION . COMPONENT Runtime
      RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime
      )

  # Note Mac specific extension .app
  set(APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/myApp.app")

  # Directories to look for dependencies
  set(DIRS "${CMAKE_BINARY_DIR}")

  # Path used for searching by FIND_XXX(), with appropriate suffixes added
  if(CMAKE_PREFIX_PATH)
      foreach(dir ${CMAKE_PREFIX_PATH})
          list(APPEND DIRS "${dir}/bin" "${dir}/lib")
      endforeach()
  endif()

  # Append Qt's lib folder which is two levels above Qt5Widgets_DIR
  list(APPEND DIRS "${Qt5Widgets_DIR}/../..")

  include(InstallRequiredSystemLibraries)

  message(STATUS "APPS: ${APPS}")
  message(STATUS "QT_PLUGINS: ${QT_PLUGINS}")
  message(STATUS "DIRS: ${DIRS}")

  install(CODE "include(BundleUtilities)
  fixup_bundle(\"${APPS}\" \"${QT_PLUGINS}\" \"${DIRS}\")")
0 Answers
Related