2009-05-04 24 views
24

Esto está estrechamente relacionado con mi previous question, que trata sobre el uso de CMake para crear una biblioteca estática en el iPhone. Lo conseguí para trabajar configurando el CMAKE_OSX_SYSROOT.Cómo configurar CMake para crear una aplicación para el iPhone

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

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

Unas pocas notas:

  • estoy dando explícitamente la opción de vincular -framework porque find_library no funcionó para todos los marcos (que 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é.
  • He añadido 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 enlaces de manera correcta, pero cuando lo ejecuto en el simulador, tengo la temida

Failed to launch simulated application: Unknown error. 

Hay un montón de casos reportados 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, por lo que nada de eso se aplica.

Encontré this thread en la lista de correo de CMake, pero solo informa un éxito en la creación de una biblioteca, y luego se apaga.

Respuesta

41

Finalmente descubrí cómo hacer esto. Esto es lo que mi archivo CMakeLists.txt parece:

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, el cambio mycompany a nombre de su empresa, y cambiar My Name a su nombre. Descubrí que es muy útil agregar el directorio de enlaces \${HOME}/\${SDKROOT}/lib como se indica arriba, de modo que si su aplicación se vincula a una biblioteca estática (especialmente una biblioteca genérica), puede construir bibliotecas separadas de iPhoneOS y iPhoneSimulator y enlazar fácilmente a la derecha uno, en lugar de preocuparse por un binario universal.

Además, parece que Xcode no agrega recursos correctamente cuando construye 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 de 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} 
) 
+0

Encontré su respuesta muy útil - Estaba realmente perdido con CMake y Xcode. Traté de usar una versión ligeramente modificada de tu archivo CMakeLists. Sin embargo, me encontré con algunos problemas extraños. ¿Podrías echar un vistazo a mi pregunta? http://stackoverflow.com/questions/5473448/cmake-and-xcode-cannot-find-interface-declaration-for-nsobject Gracias de antemano :) – Shade

+2

Hay otra forma de recursos ahora, mira aquí: http://cmake.org/gitweb?p=cmake.git;a=blob;f=Tests/iOSNavApp/CMakeLists.txt Sin embargo, esto elimina la jerarquía del directorio, por lo que los nombres de archivos duplicados son un problema ... –

1

recientes versiones CRealice pasan .m y archivos .MM para el compilador de C++, que detecta el idioma a través de la extensión, por lo que no es necesario añadir "-x Objective-C++" a las banderas de forma explícita.

+2

Oh sí, eso es solo incidental al guion De hecho, tengo principalmente archivos .cpp (ya que estoy compilando de forma cruzada), así que lo necesito. –

+0

@JesseBeder: ¿Por qué compila archivos '.cpp' como objetivo-C++? Compilamos archivos '.cpp' como C++ y tenemos un puñado de archivos' .mm' con la funcionalidad específica de la plataforma que necesita interactuar con Cocoa. –

+0

@JanHudec, algunos de mis archivos '.cpp' incluyen condicionalmente Objective-C (con un' # ifdef'), por lo que cuando se compilan para el iPhone, interactúan con Objective-C (por lo que deben considerarse Objective-C++) , pero cuando se compila para PC, no lo hacen (por lo que debe considerarse C++). –

7

Para marcos, me encontré con este mensaje http://www.mail-archive.com/[email protected]/msg24659.html Agarré 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 sí:

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

Esto funciona para OpenGLES también.

+0

Esto parece agregar los marcos en los "Otros Indicadores de Enlazador" AKA OTHER_LDFLAGS pero no agrega nada al encabezado "Rutas de Búsqueda de Encabezado" AKA HEADER_SEARCH_PATHS entonces mi código no puede encontrar UIKit/UIKit.h. Sugerencias? – Emmanuel

Cuestiones relacionadas