So richten Sie CMake ein, um eine App für das iPhone zu erstellen
Frage
Dies ist eng mit meinem verwandt Vorherige Frage, Es ging darum, CMake zu verwenden, um eine statische Bibliothek auf dem iPhone zu erstellen. Ich habe das dazu gebracht, die Einstellung des CMAKE_OSX_SYSROOT
.
Dies funktioniert jedoch nicht, um eine App zu erstellen. Mein CMakeLists.txt
sieht aus wie:
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})
Ein paar Hinweise:
- Ich gebe das ausdrücklich
-framework
Verknüpfungsoption, weilfind_library
arbeitete nicht für alle Frameworks (es fand die meisten von ihnen, aber nichtOpenGLES
). Ich verstehe nicht warum, da sie alle im selben Ordner sind${SDK}/System/Library/Frameworks
. Dies lässt mich glauben, dass ich etwas falsch gemacht habe, aber ich weiß nicht was. - Ich fügte hinzu
MACOSX_BUNDLE
zumadd_executable
Befehl so, dass der generierte Produkttyp wärecom.apple.product-type.application
Anstatt voncom.apple.product-type.tool
, was offenbar nicht auf dem iPhone existiert.
In jedem Fall kompiliert und links die App korrekt, aber wenn ich sie im Simulator ausführe, bekomme ich die gefürchteten
Failed to launch simulated application: Unknown error.
Es gibt viele gemeldete Fälle dieses Problems bei Google und Stackoverflow, aber alle Lösungen beinhalten das Aufräumen oder Erstellen eines neuen Projekts und des Verschiebens von Dateien. Aber ich kompile eine frische Kopie, nachdem CMake seine Arbeit erledigt hat, also gilt nichts davon.
ich fand Dieser Thread Auf der CMAKE -Mailingliste, aber nur einen Erfolg beim Aufbau einer Bibliothek berichtet und dann ausgestattet.
Lösung
Ich habe endlich herausgefunden, wie das geht. Hier ist was mein CMakeLists.txt
Datei sieht aus wie:
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")
Offensichtlich Veränderung mycompany
zu Ihrem Firmennamen und ändern My Name
zu deinem Namen. Ich fand es sehr nützlich, das Linkverzeichnis hinzuzufügen \${HOME}/\${SDKROOT}/lib
Wie oben, wenn Ihre App mit einer statischen Bibliothek (insbesondere einer generischen (nicht iphonischen) Bibliothek) verlinkt, können Sie separate iPhoneS- und iPhoneSimulator-Bibliotheken erstellen und einfach mit dem richtigen Verknüpfung verknüpfen, anstatt sich um eine universelle Binärdatei zu sorgen.
Xcode scheint auch keine Ressourcen hinzuzufügen, wenn Sie das Projekt mit CMAKE erstellen. Deshalb habe ich dieses Stück dem hinzugefügt CMakeLists.txt
Datei. Es kopiert den gesamten Ordner /data
in meinen Ressourcenordner (als hätte ich einen "blauen" Ordnerlink in Xcode hinzugefügt).
# 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}
)
Andere Tipps
Für Frameworks habe ich diese Nachricht gefunden http://www.mail-archive.com/cmake@cmake.org/msg24659.html Ich habe genug Informationen dafür gepackt:
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)
Anstatt cmake_exe_linker_flags festzulegen, mache ich jetzt:
ADD_FRAMEWORK(AudioToolbox MyApp)
ADD_FRAMEWORK(CoreGraphics MyApp)
ADD_FRAMEWORK(QuartzCore MyApp)
ADD_FRAMEWORK(UIKit MyApp)
Dies funktioniert auch für OpenGles.
Neuere CMake-Versionen übergeben .M- und .mm-Dateien an den C ++-Compiler, der die Sprache durch die Erweiterung erkennt, sodass Sie den Flags explizit nicht "-x objective-c ++" hinzufügen müssen.