【问题标题】:How to set up CMake to build an app for the iPhone如何设置 CMake 为 iPhone 构建应用程序
【发布时间】:2009-05-04 22:28:54
【问题描述】:

这与我的previous question 密切相关,是关于使用 CMake 在 iPhone 上构建静态库的。我可以设置CMAKE_OSX_SYSROOT

但是,这不适用于构建应用程序。我的CMakeLists.txt 看起来像:

project(TEST)

set(CMAKE_OSX_SYSROOT iphoneos2.2.1)
set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_BIT)")
set(CMAKE_EXE_LINKER_FLAGS
"-framework Foundation -framework OpenGLES -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework UIKit -framework OpenAL"
)

set(SRC --my files--)

add_executable(iphone-test MACOSX_BUNDLE ${SRC})

几点说明:

  • 我明确给出了-framework 链接选项,因为find_library 不适用于所有框架(它找到了大多数框架,但不是OpenGLES)。我不明白为什么,因为它们都在同一个文件夹${SDK}/System/Library/Frameworks 中。这让我相信我做错了什么,但我不知道是什么。
  • 我在add_executable 命令中添加了MACOSX_BUNDLE,这样生成的产品类型将是com.apple.product-type.application,而不是com.apple.product-type.tool,这在iPhone 上显然不存在。

无论如何,应用程序编译和链接正确,但是当我在模拟器中运行它时,我感到很害怕

Failed to launch simulated application: Unknown error.

在 google 和 stackoverflow 上有很多关于此问题的报告实例,但所有解决方案都涉及清理或创建新项目和移动文件;但我在 CMake 完成工作后编译了一个新副本,所以这些都不适用。

我在 CMake 邮件列表中找到了this thread,但它只报告构建库成功,然后逐渐消失。

【问题讨论】:

    标签: iphone xcode cmake


    【解决方案1】:

    我终于想出了如何做到这一点。这是我的CMakeLists.txt 文件的样子:

    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 signing
    set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer: My Name")
    

    显然,将mycompany 更改为您的公司名称,并将My Name 更改为您的名称。我发现像上面一样添加链接目录\${HOME}/\${SDKROOT}/lib 非常有用,这样如果您的应用程序链接到静态库(尤其是通用(非 iPhone)库),您可以构建单独的 iPhoneOS 和 iPhoneSimulator 库并轻松链接到正确的,而不是担心通用二进制文件。

    此外,当您使用 CMake 构建项目时,Xcode 似乎没有正确添加资源,因此我将这部分添加到 CMakeLists.txt 文件中。它将整个文件夹 /data 复制到我的资源文件夹中(好像我在 Xcode 中添加了一个“蓝色”文件夹链接)。

    # copy resource phase
    
    set(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}
    )
    

    【讨论】:

    【解决方案2】:

    对于框架,我发现了这条消息http://www.mail-archive.com/cmake@cmake.org/msg24659.html 我为此获取了足够的信息:

    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)
    

    现在我不设置 CMAKE_EXE_LINKER_FLAGS,而是这样做:

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

    这也适用于 OpenGLES。

    【讨论】:

    • 这似乎在“其他链接器标志”AKA OTHER_LDFLAGS 中添加了框架,但它没有向标题“标题搜索路径”AKA HEADER_SEARCH_PATHS 添加任何内容,因此我的代码找不到 UIKit/UIKit 。H。建议?
    【解决方案3】:

    最近的 CMake 版本将 .m 和 .mm 文件传递​​给 C++ 编译器,C++ 编译器通过扩展检测语言,因此您无需在标志中显式添加“-x objective-c++”。

    【讨论】:

    • 哦,是的,这只是脚本的附带问题。我实际上大部分是 .cpp 文件(因为我正在交叉编译),所以我确实需要它。
    • @JesseBeder:为什么要将.cpp 文件编译为objective-C++?我们将 .cpp 文件编译为 C++,并有一些 .mm 文件具有需要与 Cocoa 交互的平台特定功能。
    • @JanHudec,我的一些.cpp 文件有条件地包含了Objective-C(带有#ifdef),因此当为iPhone 编译时,它们确实与Objective-C 交互(因此应该是被认为是 Objective-C++),但是当为 PC 编译时,它们不会(因此应该被认为是 C++)。
    猜你喜欢
    • 1970-01-01
    • 2016-03-25
    • 2013-04-09
    • 2011-06-23
    • 1970-01-01
    • 2010-12-01
    • 2011-04-07
    • 1970-01-01
    • 2013-07-09
    相关资源
    最近更新 更多