[CMake] cpack bundle on osx
Yngve Inntjore Levinsen
yngve.levinsen at gmail.com
Fri Jan 21 05:10:41 EST 2011
Thank you so much for your tips and help Michael! My stupid mistake as
you can see it below is that I ran the install target command AFTER the
fixup_bundle. Hence the app did not exist in its location when the
fixup_bundle ran, but when I checked afterwards it all looked as one
would expect.
Last question, anyone have some tip on how to set up a terminal
application in an app bundle? Currently I have to suggest to the user to
open the bundle and go to the MacOS folder and click on the binary file
there. This is of course a minor issue, but would be nicer if a click on
the app bundle itself would have the same behaviour... Something I can
set in the plist file perhaps?
Cheers
Yngve
On 1/20/11 9:02 PM, Michael Jackson wrote:
> There are a lot of different reasons it can fail. I usually end up debugging through the fixup_bundle() code and placing lots of "message(STATUS ....)" commands in order to try and follow what is going on. There are already some through out the cmake code you usually just have to set a cmake variable to "1" to get them to print. You can try posting the complete output from your "make install" run to try and see what is going on.
> --
> Mike Jackson<www.bluequartz.net>
>
> On Jan 20, 2011, at 2:35 PM, Yngve Levinsen wrote:
>
>> Well I do have a folder structure, which looks like this:
>> $ ls -R madx_dev.app/
>> Contents
>>
>> madx_dev.app//Contents:
>> Info.plist MacOS Resources
>>
>> madx_dev.app//Contents/MacOS:
>> madx_dev
>>
>> madx_dev.app//Contents/Resources:
>> MadX.icns
>>
>> But it does not seem that the fixup-command does anything for me with
>> the current configuration. Don't get why.
>>
>> On 20 January 2011 15:40, Michael Jackson<mike.jackson at bluequartz.net> wrote:
>>> If you are creating a command line program then the included fixup_bundle will not work since it looks for a ".app" folder structure to fix. Instead you probably want to pass in the path to the executable located in ${CMAKE_INSTALL_PREFIX}/bin/MyExecutable to BundleUtilities.
>>>
>>> Any library located in /usr/lib or System/Library/* will NOT be copied into your bundle/Folder structure as those are considered system libraries and available on every OS X system.
>>>
>>> --
>>> Mike Jackson<www.bluequartz.net>
>>>
>>> On Jan 20, 2011, at 6:15 AM, Yngve Inntjore Levinsen wrote:
>>>
>>>> Thank you for your kind reply Michael, it got me some bit further and I think I understand a bit more. I could not see any examples of the usage of the BundleUtilities in CMake, but the example given in the Wiki works as expected on my machine.
>>>>
>>>> I forgot to add some significant parts of my CMakeLists.txt file. I have also made some fixes, so the current parts look like this:
>>>> ...
>>>> if (APPLE)
>>>> # So that we get the system X11 libraries if they exist:
>>>> set(CMAKE_LIBRARY_PATH /usr/lib/ /usr/X11/lib/ ${CMAKE_LIBRARY_PATH})
>>>> endif (APPLE)
>>>> ...
>>>> if(APPLE)
>>>> SET(MACOSX_BUNDLE_STARTUP_COMMAND madx${BINARY_POSTFIX})
>>>> SET(MACOSX_BUNDLE_ICON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmakesrc/MadX.icns")
>>>> SET(MACOSX_BUNDLE_LONG_VERSION_STRING "MadX ${BINARY_POSTFIX} version ${madX_MAJOR_VERSION}.${madX_MINOR_VERSION}.${madX_PATCH_LEVEL}")
>>>> SET(MACOSX_BUNDLE_BUNDLE_NAME "MadX${BINARY_POSTFIX}")
>>>> SET(MACOSX_BUNDLE_GUI_IDENTIFIER "MadX${BINARY_POSTFIX}")
>>>> # add icns to the .app/Resources with these TWO commands:
>>>> SET(srcfiles ${srcfiles} ${CMAKE_CURRENT_SOURCE_DIR}/cmakesrc/MadX.icns)
>>>> SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/cmakesrc/MadX.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
>>>> endif(APPLE)
>>>>
>>>> add_executable(madx${BINARY_POSTFIX} MACOSX_BUNDLE ${srcfiles})
>>>> SET_TARGET_PROPERTIES(madx${BINARY_POSTFIX} PROPERTIES LINKER_LANGUAGE Fortran)
>>>> ...
>>>> FIND_PACKAGE(X11)
>>>> IF(X11_FOUND)
>>>> message("Found X11 libraries")
>>>> INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
>>>> TARGET_LINK_LIBRARIES(madx${BINARY_POSTFIX} ${X11_X11_LIB})
>>>> ENDIF(X11_FOUND)
>>>> ...
>>>> target_link_libraries(madx${BINARY_POSTFIX} z)
>>>> target_link_libraries(madx${BINARY_POSTFIX} pthread)
>>>> target_link_libraries(madx${BINARY_POSTFIX} c)
>>>> target_link_libraries(madx${BINARY_POSTFIX} gcc_eh)
>>>> ...
>>>> if(APPLE)
>>>> set(APPS "\${CMAKE_INSTALL_PREFIX}/madx${BINARY_POSTFIX}.app") # paths to executables
>>>> set(DIRS "")
>>>> message("aps: ${APPS}")
>>>> INSTALL(CODE "
>>>> include(BundleUtilities)
>>>> message(\"aps: ${APPS}\")
>>>> fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
>>>> " COMPONENT Runtime)
>>>> INSTALL(TARGETS madx${BINARY_POSTFIX}
>>>> BUNDLE DESTINATION . COMPONENT Runtime
>>>> RUNTIME DESTINATION bin COMPONENT Runtime
>>>> )
>>>> else(APPLE)
>>>> INSTALL(TARGETS madx${BINARY_POSTFIX}
>>>> RUNTIME DESTINATION bin
>>>> LIBRARY DESTINATION lib
>>>> ARCHIVE DESTINATION lib
>>>> )
>>>> endif(APPLE)
>>>> ...
>>>> # so that we can build dragndrop on osx (actually needed?):
>>>> set(CPACK_BINARY_DRAGNDROP ON)
>>>> include (CPack)
>>>> ...
>>>>
>>>>
>>>> What I don't understand is why it does not work on my own project. From what I can see you can actually replace the fixup_bundle() in the example with simply fixup_bundle(\"${APPS}\" \"\" \"\"). This still gives the following result when I check the binary with otools:
>>>> otool -L _CPack_Packages/Darwin/DragNDrop/QtTest-0.1.1-Darwin/QtTest.app/Contents/MacOS/QtTest
>>>> _CPack_Packages/Darwin/DragNDrop/QtTest-0.1.1-Darwin/QtTest.app/Contents/MacOS/QtTest:
>>>> @executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
>>>> @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
>>>> @executable_path/../MacOS/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
>>>> @executable_path/../MacOS/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
>>>> /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
>>>> The original shows:
>>>> otool -L QtTest.app/Contents/MacOS/QtTest
>>>> QtTest.app/Contents/MacOS/QtTest:
>>>> /opt/local/libexec/qt4-mac-devel/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)
>>>> /opt/local/libexec/qt4-mac-devel/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)
>>>> /opt/local/lib/gcc44/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
>>>> /opt/local/lib/gcc44/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
>>>> /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
>>>>
>>>> So it seems that it by itself figured out that libraries in /opt/local should be relinked and added to the bundle, whereas the /usr/lib library can stay as it is. This is great stuff.
>>>>
>>>> Doing the same with mine it fails with the "not a valid bundle" error. I have the following original output from otools:
>>>> otool -L madx_dev.app/Contents/MacOS/madx_dev
>>>> madx_dev.app/Contents/MacOS/madx_dev:
>>>> /usr/X11/lib/libX11.6.dylib (compatibility version 9.0.0, current version 9.0.0)
>>>> /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
>>>> /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
>>>> /opt/local/lib/gcc44/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
>>>> /opt/local/lib/gcc44/libgfortran.3.dylib (compatibility version 4.0.0, current version 4.0.0)
>>>> /opt/local/lib/gcc44/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
>>>>
>>>> In principle the only thing not available in /usr/ is the gfortran library (right), but I guess I should expect that it would copy everything that is linked to a library residing in /opt/local in the same manner as for QtTest. However, the fixup_utilities does not relink any of those libraries. What am I doing wrong? Are there anything you need to set prior to the install(CODE "... command? I have been trying to read through the QtTest example, and I don't see anything that should imply so.
>>>>
>>>> I have too many questions at once I suppose, but there is still one more important: My application is a "terminal app", so it does not come with a GUI. Does this mean that the bundle-concept of osx is not fitted very well to my application? Can I somehow run a script that will open my application in a new Terminal.app window or something of that sort? I realized that other applications work so that if you click on the Name.app you see the GUI only, whereas if you click on the executable Contents/MacOS/Name you first see a terminal that then opens the GUI...? Is e.g. Octave bundled, and how is that done?
>>>>
>>>> Cheers
>>>> Yngve
>>>>
>>>>
>>>>
>>>>
>>>> On 1/19/11 4:42 PM, Michael Jackson wrote:
>>>>> You will need to look into the "BundleUtilities" functionality, specifically the "fixup_bundle()" function. This will copy and fixup dependent dylibs/frameworks needed by your project. There is a short example that uses Qt that you can download.
>>>>>
>>>>> You will also probably need to properly configure a plist that resides in your Application bundle. THere are CMake variables for this that you can set then CMake will create a default plist for you.
>>>>>
>>>>> There are a number of examples, CMake itself is one, that uses the "fixup_bundle()" in its own code.
>>>>>
>>>>> Separate from all of that is all the CPack variables that you probably need to set.
>>>>>
>>>>> Here is a macro that I wrote for one of my own projects:
>>>>>
>>>>> #-------------------------------------------------------------------------------
>>>>> # This macro will set all the variables necessary to have a "good" OS X Application
>>>>> # bundle. The variables are as follows:
>>>>> # PROJECT_NAME - which can be taken from the ${PROJECT_NAME} variable is needed
>>>>> # DEBUG_EXTENSION - The extension used to denote a debug built Application. Typically
>>>>> # this is '_debug'
>>>>> # ICON_FILE_PATH - The complete path to the bundle icon file
>>>>> # VERSION_STRING - The version string that you wish to use for the bundle. For OS X
>>>>> # this string is usually XXXX.YY.ZZ in type. Look at the Apple docs for more info
>>>>> #-------------------------------------------------------------------------------
>>>>> macro(ConfigureMacOSXBundlePlist PROJECT_NAME DEBUG_EXTENSION ICON_FILE_PATH VERSION_STRING)
>>>>> # message(STATUS "ConfigureMacOSXBundlePlist for ${PROJECT_NAME} ")
>>>>> IF(CMAKE_BUILD_TYPE MATCHES "Release")
>>>>> SET(DBG_EXTENSION "")
>>>>> else()
>>>>> set(DBG_EXTENSION ${DEBUG_EXTENSION})
>>>>> endif()
>>>>> get_filename_component(ICON_FILE_NAME "${ICON_FILE_PATH}" NAME)
>>>>>
>>>>> #CFBundleGetInfoString
>>>>> SET(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}${DBG_EXTENSION} Version ${VERSION_STRING}, Copyright 2009 BlueQuartz Software.")
>>>>> SET(MACOSX_BUNDLE_ICON_FILE ${ICON_FILE_NAME})
>>>>> SET(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_NAME}${DBG_EXTENSION}")
>>>>> #CFBundleLongVersionString
>>>>> SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}${DBG_EXTENSION} Version ${VERSION_STRING}")
>>>>> SET(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}${DBG_EXTENSION})
>>>>> SET(MACOSX_BUNDLE_SHORT_VERSION_STRING ${VERSION_STRING})
>>>>> SET(MACOSX_BUNDLE_BUNDLE_VERSION ${VERSION_STRING})
>>>>> SET(MACOSX_BUNDLE_COPYRIGHT "Copyright 2010, BlueQuartz Software. All Rights Reserved.")
>>>>>
>>>>> SET(${PROJECT_NAME}_PROJECT_SRCS ${${PROJECT_NAME}_PROJECT_SRCS} ${ICON_FILE_PATH})
>>>>> SET_SOURCE_FILES_PROPERTIES(${ICON_FILE_PATH} PROPERTIES
>>>>> MACOSX_PACKAGE_LOCATION Resources)
>>>>>
>>>>> endmacro()
>>>>>
>>>>> Hope that helps
>>>>> ___________________________________________________________
>>>>> Mike Jackson www.bluequartz.net
>>>>> Principal Software Engineer mike.jackson at bluequartz.net
>>>>> BlueQuartz Software Dayton, Ohio
>>>>>
>>>>> On Jan 19, 2011, at 7:08 AM, Yngve Inntjore Levinsen wrote:
>>>>>
>>>>>> Dear fellow cmake users,
>>>>>>
>>>>>> I am trying to create a bundle of my project that I build using CMake. I have tried using the DragNDrop generator, which works to some extent. I do manage to create a .app folder which contains the one binary that is the outcome of the project in the Contents/MacOS folder. I do also create a .dmg file. However:
>>>>>> - When clicking the .dmg I am first presented with the license (great!) before the dmg is mounted and I see an empty folder (??)
>>>>>> - When clicking on the<package>.app nothing happens. However, clicking on the binary in Contents/MacOS works as expected.
>>>>>> - I would also like to know how to include the shared libraries (dylib) that I need. I currently depend on stuff that is installed with MacPorts, and I don't want to require that the user have to install all that stuff. Isn't the bundle supposed to be "self-contained"? Ideally I would like the bundle to automatically include the libraries that are listed with the "otools -L<binary>" command...
>>>>>>
>>>>>> Question: Where do I find the DragNDrop documentation/examples? On the wiki ( http://www.paraview.org/Wiki/CMake:CPackPackageGenerators#DragNDrop_.28OSX_only.29 ) there are only two small lines, and my googling skills are apparently not good enough..
>>>>>>
>>>>>> Here is an extraction of the relevant part of my CMakeLists.txt:
>>>>>> ...
>>>>>> if(APPLE)
>>>>>> add_executable(madx${BINARY_POSTFIX} MACOSX_BUNDLE ${srcfiles})
>>>>>> SET_TARGET_PROPERTIES(madx${BINARY_POSTFIX} PROPERTIES CPACK_BUNDLE_STARTUP_COMMAND madx${BINARY_POSTFIX})
>>>>>> SET_TARGET_PROPERTIES(madx${BINARY_POSTFIX} PROPERTIES CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmakesrc/MadX.icns")
>>>>>> else(APPLE)
>>>>>> add_executable(madx${BINARY_POSTFIX} ${srcfiles})
>>>>>> endif(APPLE)
>>>>>> ...
>>>>>>
>>>>>> I also set some CPACK_BUNDLE properties because I earlier on tried to use the BUNDLE generator, but from what I understand this should have nothing to do with the DragNDrop generator?
>>>>>>
>>>>>> Thank you all for reading and thanks in advance for all help you might provide!
>>>>>>
>>>>>> Cheers,
>>>>>> Yngve
>>>>>>
>>>> _______________________________________________
>>>> 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
> _______________________________________________
> 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