2009-05-04 15 views
24

Ciò è strettamente legato al mio previous question, che stava usando CMake per costruire una libreria statica su iPhone. Ho ottenuto che funzionasse impostando il CMAKE_OSX_SYSROOT.Come impostare CMake per costruire un app per l'iPhone

Tuttavia, questo non funziona per creare un'app. Il mio CMakeLists.txt assomiglia:

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

Alcune note:

  • sto dando esplicitamente il -framework collega opzione perché find_library non ha funzionato per tutti i quadri (ha trovato la maggior parte di loro, ma non OpenGLES). Non capisco perché, poiché sono tutti nella stessa cartella ${SDK}/System/Library/Frameworks. Questo mi porta a credere che stavo facendo qualcosa di sbagliato, ma non so cosa.
  • Ho aggiunto MACOSX_BUNDLE al comando add_executable in modo che il tipo di prodotto generato sia com.apple.product-type.application anziché com.apple.product-type.tool, che a quanto pare non esiste su iPhone.

In ogni caso, l'applicazione compila e collegamenti in modo corretto, ma quando l'eseguo nel simulatore, ottengo la temuta

Failed to launch simulated application: Unknown error. 

Ci sono un sacco di casi segnalati di questo problema su Google e StackOverflow , ma tutte le soluzioni prevedono la pulizia o la creazione di un nuovo progetto e lo spostamento di file; ma sto compilando una nuova copia dopo che CMake fa il suo lavoro, quindi niente di tutto ciò si applica.

Ho trovato this thread nella mailing list di CMake, ma riporta solo un successo nella creazione di una libreria e quindi peters out.

risposta

41

Finalmente ho capito come fare. Ecco quello che il mio file CMakeLists.txt assomiglia:

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

Ovviamente, il cambiamento mycompany per il nome della società, e cambiare My Name al tuo nome. Ho trovato molto utile aggiungere la directory di collegamento \${HOME}/\${SDKROOT}/lib come sopra, in modo che se la tua app si collega a una libreria statica (specialmente una libreria generica (non-iPhone), puoi creare librerie separate per iPhoneOS e iPhoneSimulator e collegare facilmente a destra uno, invece di preoccuparsi di un binario universale.

Inoltre, Xcode non sembra aggiungere correttamente le risorse quando si crea il progetto usando CMake, quindi ho aggiunto questo pezzo al file CMakeLists.txt. Copia l'intera cartella /data nella mia cartella delle risorse (come se avessi aggiunto un collegamento di cartella "blu" in 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

Ho trovato la tua risposta molto utile - Ero davvero perso con CMake e Xcode. Ho provato a utilizzare una versione leggermente modificata del tuo file CMakeLists. Tuttavia, ho incontrato alcuni problemi strani. Potresti forse dare un'occhiata alla mia domanda? http://stackoverflow.com/questions/5473448/cmake-and-xcode-cannot-find-interface-declaration-for-nsobject Grazie in anticipo :) – Shade

+2

Ora c'è un altro modo per le risorse, vedi qui: http://cmake.org/gitweb?p=cmake.git;a=blob;f=Tests/iOSNavApp/CMakeLists.txt Tuttavia, questo rimuove la gerarchia delle directory, quindi i nomi dei file duplicati sono un problema ... –

1

versioni recenti CMake passano file .m .MM e al compilatore C++, che rileva la lingua attraverso l'estensione, in modo che non c'è bisogno di aggiungere "-x Objective-C++" per le bandiere in modo esplicito.

+2

Oh sì, questo è solo un caso alla sceneggiatura. In realtà ho per lo più file .cpp (visto che sto compilando una croce), quindi ne ho bisogno. –

+0

@JesseBeder: Perché compili i file '.cpp' come oggettivo-C++? Compiliamo i file '.cpp' come C++ e abbiamo una manciata di file' .mm' con la funzionalità specifica della piattaforma che deve interagire con Cocoa. –

+0

@JanHudec, alcuni dei miei file '.cpp' includono condizionalmente Objective-C (con un' # ifdef'), quindi quando compilati per l'iPhone, interagiscono con Objective-C (e quindi dovrebbero essere considerati Objective-C++) , ma quando compilati per PC, non lo fanno (quindi dovrebbe essere considerato C++). –

7

Per quadri, ho trovato questo messaggio http://www.mail-archive.com/[email protected]/msg24659.html ho afferrato abbastanza informazioni per questo:

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) 

Invece di impostare CMAKE_EXE_LINKER_FLAGS, ora faccio:

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

Questo funziona per OpenGLES pure.

+0

Questo sembra aggiungere i framework negli "Altri Linker Flags" AKA OTHER_LDFLAGS ma non aggiunge nulla all'intestazione "Header Search Paths" AKA HEADER_SEARCH_PATHS quindi il mio codice non riesce a trovare UIKit/UIKit.h. Suggerimenti? – Emmanuel

Problemi correlati