How to set up CMake to build an app for the iPhone How to set up CMake to build an app for the iPhone xcode xcode

How to set up CMake to build an app for the iPhone


I finally figured out how to do this. Here's what my CMakeLists.txt file looks like:

project(test)set(NAME test)file(GLOB headers *.h)file(GLOB sources *.cpp)set(CMAKE_OSX_SYSROOT iphoneos2.2.1)set(CMAKE_OSX_ARCHITECTURES $(ARCHS_STANDARD_32_BIT))set(CMAKE_CXX_FLAGS "-x objective-c++")set(CMAKE_EXE_LINKER_FLAGS    "-framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework UIKit")link_directories(\${HOME}/\${SDKROOT}/lib)set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.mycompany.\${PRODUCT_NAME:identifier}")set(APP_TYPE MACOSX_BUNDLE)add_executable(${NAME}    ${APP_TYPE}    ${headers}    ${sources})target_link_libraries(${NAME}    # other libraries to link)# code signingset_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer: My Name")

Obviously, change mycompany to your company name, and change My Name to your name. I found it's very useful to add the link directory \${HOME}/\${SDKROOT}/lib as above, so that if your app links to a static library (especially a generic (non-iPhone) library), you can build separate iPhoneOS and iPhoneSimulator libraries and easily link to the right one, instead of worrying about a universal binary.

Also, Xcode doesn't seem to properly add resources when you build the project using CMake, so I added this piece to the CMakeLists.txt file. It copies the entire folder /data into my resources folder (as if I had added a "blue" folder link in Xcode).

# copy resource phaseset(APP_NAME \${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME})set(RES_DIR ${test_SOURCE_DIR}/data)add_custom_command(    TARGET ${NAME}    POST_BUILD    COMMAND /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -resolve-src-symlinks ${RES_DIR} ${APP_NAME})


For frameworks, I found this message http://www.mail-archive.com/cmake@cmake.org/msg24659.html I grabbed enough information for this:

SET(TARGETSDK iPhoneOS3.1.2.sdk)SET(CMAKE_OSX_SYSROOT /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/${TARGETSDK})macro(ADD_FRAMEWORK fwname appname)    find_library(FRAMEWORK_${fwname}        NAMES ${fwname}        PATHS ${CMAKE_OSX_SYSROOT}/System/Library        PATH_SUFFIXES Frameworks        NO_DEFAULT_PATH)    if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)        MESSAGE(ERROR ": Framework ${fwname} not found")    else()        TARGET_LINK_LIBRARIES(${appname} ${FRAMEWORK_${fwname}})        MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")    endif()endmacro(ADD_FRAMEWORK)

Instead of setting CMAKE_EXE_LINKER_FLAGS, now I do:

ADD_FRAMEWORK(AudioToolbox MyApp)ADD_FRAMEWORK(CoreGraphics MyApp)ADD_FRAMEWORK(QuartzCore MyApp)ADD_FRAMEWORK(UIKit MyApp)

This does work for OpenGLES as well.


Recent CMake versions pass .m and .mm files to the C++ compiler, which detects the language through the extension, so you don't need to add "-x objective-c++" to the flags explicitly.