Question

Ceci est étroitement lié à mon La question précédente portait sur l’utilisation de CMake pour créer une bibliothèque statique sur l’iPhone. Cela a fonctionné en définissant le CMAKE_OSX_SYSROOT .

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 car find_library n'a pas fonctionné pour tous les frameworks (il en a trouvé la plupart, mais pas OpenGLES ). Je ne comprends pas pourquoi, car ils sont tous dans le même dossier $ {SDK} / Système / Bibliothèque / Frameworks . Cela me porte à croire que je faisais quelque chose de mal, mais je ne sais pas quoi.
  • J'ai ajouté MACOSX_BUNDLE à la commande add_executable afin que le type de produit généré soit com.apple.product-type.application au lieu de com.apple.product-type.tool , qui n'existe apparemment pas sur l'iPhone.

Dans tous les cas, l'application est correctement compilée et liée, mais lorsque je l'exécute dans le simulateur, je reçois le redouté

Failed to launch simulated application: Unknown error.

Il existe de nombreuses instances signalées 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 suis en train de compiler une nouvelle copie après que CMake a fait son travail, donc rien de tout cela ne s'applique.

J'ai trouvé ce fil sur la liste de diffusion de CMake , mais il ne fait que signaler un succès dans la construction d’une bibliothèque, puis s’efface.

Était-ce utile?

La solution

J'ai enfin compris comment faire cela. Voici à quoi ressemble mon fichier 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")

Évidemment, remplacez mycompany par le nom de votre société et remplacez Mon nom par 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 est liée à une bibliothèque statique (en particulier une bibliothèque générique (non iPhone)), vous pouvez créer des bibliothèques séparées iPhoneOS et iPhoneSimulator et créer facilement un lien vers la bonne, au lieu de vous soucier d’un binaire universel.

De plus, Xcode ne semble pas ajouter correctement de ressources lorsque vous construisez le projet avec CMake. J'ai donc ajouté cette pièce au fichier CMakeLists.txt . Il copie l'intégralité 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}
)

Autres conseils

Pour les frameworks, j'ai trouvé ce message http: //www.mail -archive.com/cmake@cmake.org/msg24659.html J'ai récupéré suffisamment 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 définir CMAKE_EXE_LINKER_FLAGS, je le fais maintenant:

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

Cela fonctionne également pour OpenGLES.

Les versions récentes de CMake transmettent les fichiers .m et .mm au compilateur C ++, qui détecte le langage par le biais de l'extension. Vous n'avez donc pas besoin d'ajouter "-x objective-c ++". aux drapeaux explicitement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top