Domanda

Questo è strettamente correlato al mio domanda precedente , che riguardava l'utilizzo di CMake per creare una libreria statica su iPhone. Ho capito che funziona impostando il CMAKE_OSX_SYSROOT .

Tuttavia, questo non funziona per creare un'app. Il mio CMakeLists.txt è simile 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})

Alcune note:

  • Fornisco esplicitamente l'opzione di collegamento -framework perché find_library non ha funzionato per tutti i framework (ne ha trovati la maggior parte, ma non OpenGLES ). Non capisco perché, poiché sono tutti nella stessa cartella $ {SDK} / Sistema / Libreria / 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 invece di com.apple.product-type.tool , che apparentemente non esiste su iPhone.

In ogni caso, l'app si compila e si collega correttamente, ma quando la eseguo nel simulatore, ottengo il temuto

Failed to launch simulated application: Unknown error.

Esistono molte istanze segnalate di questo problema su Google e StackOverflow, ma tutte le soluzioni prevedono la pulizia o la creazione di un nuovo progetto e lo spostamento dei file; ma sto compilando una nuova copia dopo che CMake ha fatto il suo lavoro, quindi nulla di tutto ciò si applica.

Ho trovato questa discussione nella mailing list di CMake , ma segnala solo un successo nella costruzione di una biblioteca e quindi si protesta.

È stato utile?

Soluzione

Alla fine ho capito come fare. Ecco come appare il mio file 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")

Ovviamente, cambia mycompany nel nome della tua azienda e cambia My Name nel tuo nome. Ho trovato molto utile aggiungere la directory dei collegamenti \ $ {HOME} / \ $ {SDKROOT} / lib come sopra, in modo che se l'app si collega a una libreria statica (in particolare un generico (non- iPhone)), puoi creare librerie iPhoneOS e iPhoneSimulator separate e collegarti facilmente a quella giusta, invece di preoccuparti di un binario universale.

Inoltre, Xcode non sembra aggiungere correttamente le risorse quando costruisci 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 link alla 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}
)

Altri suggerimenti

Per i framework, ho trovato questo messaggio http: //www.mail -archive.com/cmake@cmake.org/msg24659.html Ho preso 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 lo faccio:

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

Questo funziona anche con OpenGLES.

Le versioni recenti di CMake passano i file .m e .mm al compilatore C ++, che rileva la lingua attraverso l'estensione, quindi non è necessario aggiungere " -x goal-c ++ " alle bandiere esplicitamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top