Pregunta

Esto está estrechamente relacionado con mi pregunta anterior , que trataba de usar CMake para construir una biblioteca estática en el iPhone. Conseguí que funcione configurando el CMAKE_OSX_SYSROOT .

Sin embargo, esto no funciona para construir una aplicación. Mi CMakeLists.txt se parece a:

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})

Algunas notas:

  • Doy explícitamente la opción de enlace -framework porque find_library no funcionó para todos los marcos (encontró la mayoría de ellos, pero no OpenGLES ). No entiendo por qué, ya que están todos en la misma carpeta $ {SDK} / System / Library / Frameworks . Esto me lleva a creer que estaba haciendo algo mal, pero no sé qué.
  • Agregué MACOSX_BUNDLE al comando add_executable para que el tipo de producto generado sea com.apple.product-type.application en lugar de com.apple.product-type.tool , que aparentemente no existe en el iPhone.

En cualquier caso, la aplicación compila y enlaza correctamente, pero cuando la ejecuto en el simulador, obtengo el temido

Failed to launch simulated application: Unknown error.

Hay muchas instancias reportadas de este problema en google y stackoverflow, pero todas las soluciones implican limpiar o crear un nuevo proyecto y mover archivos; pero estoy compilando una copia nueva después de que CMake haga su trabajo, así que nada de eso se aplica.

Encontré este hilo en la lista de correo de CMake , pero solo informa un éxito en la construcción de una biblioteca y luego desaparece.

¿Fue útil?

Solución

Finalmente me di cuenta de cómo hacer esto. Aquí es cómo se ve mi archivo 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")

Obviamente, cambie mycompany al nombre de su empresa y cambie My Name a su nombre. Descubrí que es muy útil agregar el directorio de enlaces \ $ {HOME} / \ $ {SDKROOT} / lib como se indicó anteriormente, de modo que si su aplicación se vincula a una biblioteca estática (especialmente una genérica iPhone) (biblioteca), puede crear bibliotecas separadas para iPhoneOS y iPhoneSimulator y vincularlas fácilmente a la correcta, en lugar de preocuparse por un binario universal.

Además, Xcode no parece agregar recursos correctamente cuando construyes el proyecto usando CMake, así que agregué esta pieza al archivo CMakeLists.txt . Copia la carpeta completa / data en mi carpeta de recursos (como si hubiera agregado un enlace a la carpeta " azul " en 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}
)

Otros consejos

Para frameworks, encontré este mensaje http: //www.mail -archive.com/cmake@cmake.org/msg24659.html Agarre suficiente información para esto:

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)

En lugar de establecer CMAKE_EXE_LINKER_FLAGS, ahora lo hago:

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

Esto también funciona para OpenGLES.

Las versiones recientes de CMake pasan los archivos .m y .mm al compilador de C ++, que detecta el idioma a través de la extensión, por lo que no es necesario agregar " -x object-c ++ " a las banderas explícitamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top