2009-05-04 8 views
24

Ceci est étroitement lié à mon previous question, qui consistait à utiliser CMake pour construire une bibliothèque statique sur l'iPhone. J'ai réussi à régler le CMAKE_OSX_SYSROOT.Comment configurer CMake pour créer une application pour l'iPhone

Toutefois, cela ne fonctionne pas pour créer une application. Mon CMakeLists.txt ressemble:

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

Quelques notes:

  • Je donne explicitement l'option de liaison -framework parce que find_library ne fonctionne pas pour tous les cadres (il a trouvé la plupart d'entre eux, mais pas OpenGLES). Je ne comprends pas pourquoi, puisqu'ils sont tous dans le même dossier ${SDK}/System/Library/Frameworks. Cela m'amène à croire que je faisais quelque chose de mal, mais je ne sais pas quoi.
  • J'ai ajouté MACOSX_BUNDLE à la commande add_executable pour que le type de produit généré soit com.apple.product-type.application au lieu de com.apple.product-type.tool, ce qui apparemment n'existe pas sur l'iPhone.

Dans tous les cas, l'application compile et liens correctement, mais quand je le lance dans le simulateur, je reçois la redoutée

Failed to launch simulated application: Unknown error. 

Il y a beaucoup de cas signalés de ce problème sur Google et stackoverflow , mais toutes les solutions impliquent le nettoyage ou la création d'un nouveau projet et le déplacement de fichiers; mais je compile une nouvelle copie après que CMake ait fait son travail, donc rien de tout cela ne s'applique.

J'ai trouvé this thread dans la liste de diffusion CMake, mais cela ne signale que le succès de la construction d'une bibliothèque, puis disparaît.

Répondre

41

J'ai finalement compris comment faire. Voici ce que mon fichier CMakeLists.txt ressemble:

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

De toute évidence, le changement mycompany à votre nom de l'entreprise, et changer My Name à votre nom. J'ai trouvé très utile d'ajouter le répertoire de liens \${HOME}/\${SDKROOT}/lib comme ci-dessus, de sorte que si votre application se connecte à une bibliothèque statique (en particulier une bibliothèque générique (non iPhone)), vous pouvez créer des bibliothèques iPhoneOS et iPhoneSimulator séparées et facilement lier vers la droite l'un, au lieu de s'inquiéter d'un binaire universel.

En outre, Xcode ne semble pas ajouter correctement de ressources lorsque vous générez le projet à l'aide de CMake. J'ai donc ajouté cette pièce au fichier CMakeLists.txt. Il copie l'ensemble du dossier /data dans mon dossier de ressources (comme si j'avais ajouté un lien de dossier "bleu" dans 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

J'ai trouvé votre réponse très utile - j'étais vraiment perdu avec CMake et Xcode. J'ai essayé d'utiliser une version légèrement modifiée de votre fichier CMakeLists. Cependant, j'ai rencontré des problèmes étranges. Pourriez-vous peut-être jeter un coup d'oeil à ma question? http://stackoverflow.com/questions/5473448/cmake-and-xcode-cannot-find-interface-declaration-for-nsobject Merci d'avance :) – Shade

+2

Il y a une autre façon pour les ressources maintenant, voir ici: http://cmake.org/gitweb?p=cmake.git;a=blob;f=Tests/iOSNavApp/CMakeLists.txt Cependant, cela supprime la hiérarchie des répertoires, donc les noms de fichiers en double sont un problème ... –

1

versions CMake récentes passent des fichiers .m et .mm au compilateur C++, qui détecte la langue à travers l'extension, de sorte que vous n'avez pas besoin d'ajouter « -x objectif-C++ » aux drapeaux explicitement.

+2

Oh ouais, c'est juste accessoire au script. En fait, j'ai surtout des fichiers .cpp (depuis que je compile), j'ai donc besoin de ça. –

+0

@JesseBeder: Pourquoi compilez-vous des fichiers '.cpp' comme objectif-C++? Nous compilons des fichiers '.cpp' en C++ et avons une poignée de fichiers' .mm' avec la fonctionnalité spécifique à la plate-forme qui doit interagir avec Cocoa. –

+0

@JanHudec, certains de mes fichiers '.cpp' incluent conditionnellement Objective-C (avec un # ifdef), donc lorsqu'ils sont compilés pour l'iPhone, ils interagissent avec Objective-C (et devraient donc être considérés comme Objective-C++) , mais quand compilé pour PC, ils ne le font pas (ainsi devrait être considéré C++). –

7

Pour les cadres, je trouve ce message http://www.mail-archive.com/[email protected]/msg24659.html Je saisis assez d'informations pour cela:

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) 

Au lieu de mettre CMAKE_EXE_LINKER_FLAGS, maintenant je fais:

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

Cela fonctionne pour OpenGLES aussi bien.

+0

Cela semble ajouter les cadres dans les "Autres liens de liaison" AKA OTHER_LDFLAGS mais il n'ajoute rien à l'en-tête "Header Search Paths" AKA HEADER_SEARCH_PATHS donc mon code ne peut pas trouver UIKit/UIKit.h. Suggestions? – Emmanuel

Questions connexes