[CMake] CMake 2.8.1 + Qt/Cocoa + OS X Problem -- qt_menu.nib not getting copied
Michael Wild
themiwi at gmail.com
Fri Apr 16 11:03:19 EDT 2010
The way BundleUtilities (that is, GetPrerequisites is actually doing the work here) is designed so far is to check for run-time dependencies using otool and similar utilities. However, CMake can't possibly detect that qt_menu.nib is required since this file is loaded dynamically at run-time, so someone has to put that information into GetPrerequisites. Since qt_menu.nib is a rather recent addition to Qt, and most people use their own scripts to accomplish this, it hasn't happened so far. Also, there's the issue of whether one actually wants to hard-code such specific information into a general tool like GetPrerequisites... The danger of creating a huge number of unmaintainable special cases is quite big there...
Perhaps one could devise a way for FindXXX/XXConfig modules to communicate such requirements to GetPrerequisites using properties. This approach would be much more modular and wouldn't require GetPrerequisites to be updated every time a module changes.
Michael
On 16. Apr, 2010, at 16:36 , Michael Jackson wrote:
> Lets take a deeper look at what is needed for an OS X bundle, cmake and Qt.
>
> The issues with making an OS X app bundle "relocatable" are well known (those following along at home can Google search..). If you are including libraries into the bundle then the "install_name" of those libraries/frameworks need to be something like "@executable_path...." and placed correctly into the app bundle. This is what "BundleUtilities.cmake" does for you. Nothing More.
>
> The nib file that Qt-Cocoa needs is particular to Qt-Cocoa builds. It has NOTHING to do with CMake at all. I, like everyone else, has a shell script template and CMake template file that they use to create their Qt/Cocoa bundles and we forget that BundleUtilities does NOT actually take care of some of this for us. Now, CMake _could_ offer a bit better support for Qt/Cocoa by maybe explicitly offering a "DeployQtApplication" cmake function that would "do the right thing" based on the type of Qt being used (Carbon vs Cocoa), copying plugins, copying the nib file, creating a qt.conf file if needed. That would be an excellent feature request to submit to the bug tracker.
>
> If you are interested you are welcome to pull some apps from my git repo and take a look at how I am generating the app bundle.
>
> So, I agree with your philosophical concerns that CMake _could_ offer some convenience functions to more explicitly deal with Qt/Cocoa.
>
> Hope that helps.
> ___________________________________________________________
> Mike Jackson www.bluequartz.net
> Principal Software Engineer mike.jackson at bluequartz.net
> BlueQuartz Software Dayton, Ohio
>
>
> On Apr 16, 2010, at 10:13 AM, kent williams wrote:
>
>> If you have the URL of this example, I'd love to look at it. I have
>> been poring over the CMake wiki without finding anything.
>>
>> But that's not what I was concerned about. What bothers me is that:
>>
>> 1, If you build against Qt-Carbon, this isn't a problem.
>> 2. if qtmenu.nib is needed, and it isn't being fixed by
>> BundleUtilities::fixup_bundle, then fixup_bundle isn't actually fixing
>> up the bundle.
>>
>> The bug 10000 I found in the CMake bug tracker actually is
>> specifically about working around this problem in the specific case of
>> building the Qt CMake client.
>>
>> My broader philosophical concern is that actually making a proper OS X
>> bundle with CMake is a process with too many moving parts. The whole
>> point of CMake is to eliminate boilerplate by dealing with the build
>> process at a higher level, and this strikes me as definitely something
>> that has to happen every time you build a bundle for OSX
>>
>> On Thu, Apr 15, 2010 at 9:07 PM, Mike Jackson
>> <mike.jackson at bluequartz.net> wrote:
>>> I do not see any where in your code commands to actually copy the nib
>>> file from the qtgui framework into your app bundle. I know thatbthe
>>> way I set up my installation code I explicitly put a command to copy
>>> the nib file. I believe there is a qt example on the cmake wiki that
>>> shows how to do that.
>>>
>>> -----
>>> Mike Jackson www.bluequartz.net
>>> Principal Software Engineer mike.jackson at bluequartz.net
>>> BlueQuartz Software Dayton, Ohio
>>>
>>>
>>> On Apr 15, 2010, at 17:06, kent williams <nkwmailinglists at gmail.com>
>>> wrote:
>>>
>>>> I'll include my CMakeLists.txt at the end of this message, but the
>>>> long and the short of it is this: My ApplicationBundle crashes when I
>>>> try and open it with this classic error message:
>>>>
>>>> Qt internal error: qt_menu.nib could not be loaded. The .nib file
>>>> should be placed in QtGui.framework/Versions/Current/Resources/ or in
>>>> the resources directory of your application bundle.
>>>>
>>>> This is supposed to be fixed, as documented in this bug:
>>>>
>>>> http://public.kitware.com/Bug/view.php?id=10000
>>>>
>>>> I checked out the latest GIT CMake and verified that the file in
>>>> question is the same in 2.8.1 and current GIT trunk.
>>>>
>>>> So is there some magical extra step I need to get my bundle properly
>>>> fixed up?
>>>>
>>>> project( BRAINSTracerQT )
>>>> cmake_minimum_required(VERSION 2.8)
>>>> cmake_policy(VERSION 2.8)
>>>>
>>>> find_package( VTK REQUIRED )
>>>> include(${VTK_USE_FILE})
>>>>
>>>> find_package( ITK REQUIRED )
>>>> include(${ITK_USE_FILE})
>>>>
>>>> find_package( Qt4 REQUIRED )
>>>> if(QT_USE_FILE)
>>>> include(${QT_USE_FILE})
>>>> set(QT_USE_QTXML 1)
>>>> else(QT_USE_FILE)
>>>> set( QT_LIBRARIES ${QT_QT_LIBRARY})
>>>> endif(QT_USE_FILE)
>>>>
>>>> find_package(ModuledescriptionParser REQUIRED)
>>>> include(${ModuleDescriptionParser_USE_FILE})
>>>>
>>>> find_package(TCL REQUIRED)
>>>>
>>>> find_package( VTK REQUIRED )
>>>> include(${VTK_USE_FILE})
>>>>
>>>> find_package( ITK REQUIRED )
>>>> include(${ITK_USE_FILE})
>>>> include_directories(
>>>> ${BRAINSTracerQT_SOURCE_DIR}
>>>> ${BRAINSTracerQT_BINARY_DIR}
>>>> )
>>>>
>>>> configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ExecutablePath.h.in
>>>> ${CMAKE_BINARY_DIR}/ExecutablePath.h IMMEDIATE @ONLY)
>>>>
>>>> add_subdirectory(vtkRenderingAddOn)
>>>> include_directories(${BRAINSTracerQT_SOURCE_DIR}/vtkRenderingAddOn)
>>>>
>>>> set(BRAINSTracerQT_SRCS
>>>> main.cxx
>>>> BTMainWindow.cxx
>>>> vtkKWImage.cxx
>>>> vtkKWImage2D.cxx
>>>> QVtkImageViewer.cxx
>>>> vtkMultiWidgetBase.cxx
>>>> vtkMultiContourWidget.cxx
>>>> vtkBTPointSetWidget.cxx
>>>> vtkBTPointWidget.cxx
>>>> PolyDataUtils.cxx
>>>> BTContour.cxx
>>>> BTPolygon.cxx
>>>> DiscreteParticleFilter.cxx
>>>> PolygonFill.cxx
>>>> LoadMaskImage.cxx
>>>> qtcolorpicker.cxx
>>>> QVtkPropertyDialog.cxx
>>>> QModuleParameterWidget.cxx
>>>> QImageParameterWidget.cxx
>>>> QFileBrowserParameterWidget.cxx
>>>> )
>>>>
>>>> set(BRAINSTracerQT_HDRS
>>>> BTMainWindow.h
>>>> QVtkImageViewer.h
>>>> qtcolorpicker.h
>>>> QVtkPropertyDialog.h
>>>> QModuleParameterWidget.h
>>>> QImageParameterWidget.h
>>>> QFileBrowserParameterWidget.h
>>>> )
>>>>
>>>> set(BRAINSTracerQT_RCCS
>>>> BRAINSTracerQT.qrc)
>>>>
>>>> set(BRAINSTracerQT_UIS
>>>> qvtkpropertydialog.ui)
>>>>
>>>> QT4_WRAP_CPP( MOCSrcs ${BRAINSTracerQT_HDRS} )
>>>>
>>>> QT4_ADD_RESOURCES(RCC_SRCS ${BRAINSTracerQT_RCCS})
>>>>
>>>> QT4_WRAP_UI(UIHeaders ${BRAINSTracerQT_UIS} )
>>>>
>>>> set_source_files_properties(${BRAINSTracerQT_SRCS}
>>>> PROPERTIES OBJECT_DEPENDS ${UIHeaders})
>>>>
>>>> add_definitions(-DQT_GUI_LIBS -DQT_CORE_LIB -DQT3_SUPPORT)
>>>>
>>>> #set_source_files_properties(${BRAINSTracerQT_SRCS} PROPERTIES
>>>> # OBJECT_DEPENDS "${UIHeaders}")
>>>>
>>>> add_executable( BRAINSTracerQT
>>>> MACOSX_BUNDLE
>>>> WIN32
>>>> ${BRAINSTracerQT_SRCS}
>>>> ${MOCSrcs}
>>>> ${RCC_SRCS}
>>>> )
>>>> target_link_libraries( BRAINSTracerQT
>>>> QVTK
>>>> ${QT_LIBRARIES}
>>>> ${ITK_LIBRARIES}
>>>> vtkRenderingAddOn
>>>> vtkRendering
>>>> vtkFiltering
>>>> vtkVolumeRendering
>>>> ${TCL_LIBRARY}
>>>> ModuleDescriptionParser
>>>> )
>>>>
>>>> GET_TARget_property(TARGET_EXEC_DIR BRAINSTracerQT
>>>> RUNTIME_OUTPUT_DIRECTORY)
>>>> set(TARGET_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
>>>>
>>>> set(DEFAULT_MODULE_SEARCH_PATH
>>>> "${TARGET_EXEC_DIR}/Modules")
>>>>
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> # Now the installation stuff below
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> SET(plugin_dest_dir bin)
>>>> SET(qtconf_dest_dir bin)
>>>> SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/BRAINSTracerQT")
>>>> IF(APPLE)
>>>> SET(plugin_dest_dir BRAINSTracerQT.app/Contents/MacOS)
>>>> SET(qtconf_dest_dir BRAINSTracerQT.app/Contents/Resources)
>>>> SET(APPS "\${CMAKE_INSTALL_PREFIX}/BRAINSTracerQT.app")
>>>> ENDIF(APPLE)
>>>> IF(WIN32)
>>>> SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/BRAINSTracerQT.exe")
>>>> ENDIF(WIN32)
>>>>
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> # Install the BRAINSTracerQT application, on Apple, the bundle is at
>>>> the root of the
>>>> # install tree, and on other platforms it'll go into the bin
>>>> directory.
>>>> INSTALL(TARGETS BRAINSTracerQT
>>>> BUNDLE DESTINATION . COMPONENT Runtime
>>>> RUNTIME DESTINATION bin COMPONENT Runtime
>>>> )
>>>>
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> # Install needed Qt plugins by copying directories from the qt
>>>> installation
>>>> # One can cull what gets copied by using 'REGEX "..." EXCLUDE'
>>>> INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION
>>>> ${plugin_dest_dir}/plugins COMPONENT Runtime)
>>>>
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> # install a qt.conf file
>>>> # this inserts some cmake code into the install script to write the
>>>> file
>>>> INSTALL(CODE "
>>>> file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf
>>>> \" \"\")
>>>> " COMPONENT Runtime)
>>>>
>>>>
>>>> #--
>>>> ---
>>>> ---
>>>> ---
>>>> ---------------------------------------------------------------------
>>>> # Use BundleUtilities to get all other dependencies for the
>>>> application to work.
>>>> # It takes a bundle or executable along with possible plugins and
>>>> inspects it
>>>> # for dependencies. If they are not system dependencies, they are
>>>> copied.
>>>>
>>>> # directories to look for dependencies
>>>> SET(DIRS
>>>> ${QT_LIBRARY_DIRS}
>>>> ${ITK_DIR}
>>>> ${VTK_DIR}
>>>> ${CMAKE_INSTALL_PREFIX}/lib
>>>> ${ModuledescriptionParser_DIR}
>>>> ${BRAINSTracerQT_BINARY_DIR}/lib
>>>> )
>>>> MESSAGE(status QT_LIBRARY_DIRS ${QT_LIBRARY_DIRS} ${QT_PLUGINS_DIR})
>>>> # Now the work of copying dependencies into the bundle/package
>>>> # The quotes are escaped and variables to use at install time have
>>>> their $ escaped
>>>> # An alternative is the do a configure_file() on a script and use
>>>> install(SCRIPT ...).
>>>> # Note that the image plugins depend on QtSvg and QtXml, and it got
>>>> those copied
>>>> # over.
>>>> INSTALL(CODE "
>>>> file(GLOB_RECURSE QTPLUGINS
>>>> \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*$
>>>> {CMAKE_SHARED_LIBRARY_SUFFIX}\")
>>>> include(BundleUtilities)
>>>> fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
>>>> " COMPONENT Runtime)
>>>>
>>>>
>>>> # To Create a package, one can run "cpack -G DragNDrop
>>>> CPackConfig.cmake" on Mac OS X
>>>> # where CPackConfig.cmake is created by including CPack
>>>> # And then there's ways to customize this as well
>>>> set(CPACK_BINARY_DRAGNDROP ON)
>>>> include(CPack)
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.cmake.org/mailman/listinfo/cmake
>>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.cmake.org/mailman/listinfo/cmake
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
More information about the CMake
mailing list