25

这与我之前的问题密切相关,即使用 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中。这让我相信我做错了什么,但我不知道是什么。
  • 我添加MACOSX_BUNDLEadd_executable命令中,以便生成的产品类型将com.apple.product-type.application代替com.apple.product-type.tool,这在 iPhone 上显然不存在。

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

Failed to launch simulated application: Unknown error.

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

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

4

3 回答 3

43

我终于想出了如何做到这一点。这是我的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}
)
于 2009-06-09T21:22:59.237 回答
9

对于框架,我发现这条消息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。

于 2009-10-31T00:38:39.173 回答
1

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

于 2009-07-08T02:19:58.057 回答