I have a cross-platform application for the Win and Mac OSX platforms written in C++, Qt and a little bit of Objective C. After a period of supporting two unrelated platform specific projects (VS 2010 and xCode) we decided to create a single CMake script. We generate a platform specific project and work with it.
After a pretty long delving I have managed to compile and link my application. But there are still plenty problems with creating a proper bundle (without any efforts xCode just creates a binary). After setting a few variables xCode compiles and creates a dummy bundle without a plist file and app’s executable. So I need to copy all required frameworks and resources to the bundle.
I’ve tried a few approaches to create a bundle. The first one was to use SET_SOURCE_FILES_PROPERTIES( ${resourcePath} PROPERTIES MACOSX_PACKAGE_LOCATION ${pathInsideBundle} ) and adding them (frameworks\resources) to ADD_EXECUTABLE like this: ADD_EXECUTABLE( FranchiseTracker MACOSX_BUNDLE ${headers} ${sources} ${form_headers} ${resources_rcc} ${thirdparty_sources} ${BUNDLE_COPY_RESOURCES} ). And it worked out – I’ve managed to copy an icon and the Sparkle framework to the bundle, but the problem was that I couldn’t copy the Qt frameworks, because FIND_PACKAGE left the ${QT_LIBRARIES} variable empty, so I couldn’t get the paths to copy frameworks “manually”.
Now I’m gonna use the “fix_bundle” approach because it promises me to copy all required resources without my intervention. So, here is my code related to fixup_bundle():
# Fixup bundle, copy dynamic libraries into app bundle
SET( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/out )
SET( APPS "\${CMAKE_CURRENT_BINARY_DIR}/out/${APP_NAME}.app" ) # paths to executables
SET( DIRS "${CMAKE_SOURCE_DIR}/osx/FRP/vendors/libraries/lib" ) # directories to search for prerequisites
INSTALL( CODE "
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\")
")
Now I’m stumped by a little refinement. The thing is stubborn xCode persists to generate and write my bundle in ${CMAKE_CURRENT_BINARY_DIR}/out/Debug and thus fixup_bundle can’t find any bundle at all.
My specific question (as in the title): How can I get the correct path (with Debug) in the CMake script? I wanna avoid to hardcode the path with Debug, because that will be wrong in a case of archiving.
My more common question: Is there an easier way of creating bundles for a Qt application with CMake? Maybe the whole my approach is wrong?
P.S. I have posted the full script to Code Review here.
P.P.S. For those who will consider my question as too verbose. The reason I’ve posted the full script and written my attempts (except I want to get it working) is that there is little info on the internet about working with Mac OSX frameworks, bundles, etc in CMake. I had to read a lot of mailing lists because I couldn’t find any structured tutorials or at least a decent documentation. And the only source to learn were other scripts written by other people. So I hope my script and explanations will help someone.
I’ve finished with using only the
macdeployqtutility on the Mac OSX platform. I use xCode to build my application, so I’ve solved the path issue with xCode’s macros${CONFIGURATION}like that:Pay attention to escaping the $ character to prevent
${CONFIGURATION}from being expanded as a CMake variable.P.S. The code I’ve posted to CodeReview is a little bit outdated, so if anybody stumbles the same issue (with creating a bundle on OSX) and wants to see the full working variant, just let me know and I’ll post it somewhere (maybe update my post on CodeReview).