Pergunta

Isso está intimamente relacionado ao meu pergunta anterior, que se tratava de usar o CMake para construir uma biblioteca estática no iPhone. Eu tenho isso para funcionar definindo o CMAKE_OSX_SYSROOT.

No entanto, isso não funciona para criar um aplicativo. Meu CMakeLists.txt parece:

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

Algumas notas:

  • Estou dando explicitamente o -framework opção de vincular porque find_library não funcionou para todas as estruturas (encontrou a maioria delas, mas não OpenGLES). Eu não entendo por que, já que eles estão todos na mesma pasta ${SDK}/System/Library/Frameworks. Isso me leva a acreditar que eu estava fazendo algo errado, mas não sei o quê.
  • Eu adicionei MACOSX_BUNDLE para o add_executable comando para que o tipo de produto gerado seja com.apple.product-type.application ao invés de com.apple.product-type.tool, que aparentemente não existe no iPhone.

De qualquer forma, o aplicativo compila e vincula corretamente, mas quando eu o executo no simulador, eu recebo o temido

Failed to launch simulated application: Unknown error.

Existem muitas instâncias relatadas desse problema no Google e Stackoverflow, mas todas as soluções envolvem limpar ou criar um novo projeto e mover arquivos; Mas estou compilando uma cópia nova depois que o CMake faz seu trabalho, então nada disso se aplica.

eu encontrei este tópico Na lista de discussão do CMake, mas apenas relata um sucesso na construção de uma biblioteca e depois Peters.

Foi útil?

Solução

Finalmente descobri como fazer isso. Aqui está o que meu CMakeLists.txt O arquivo parece:

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

Obviamente, mude mycompany para o nome da sua empresa e mudança My Name para o seu nome. Achei muito útil adicionar o diretório de links \${HOME}/\${SDKROOT}/lib Como acima, de modo que, se o seu aplicativo vincular a uma biblioteca estática (especialmente uma biblioteca genérica (não-iphone)), você poderá criar bibliotecas separadas para iPhoneos e iPhonesimulator e facilmente vincular ao certo, em vez de se preocupar com um binário universal.

Além disso, o Xcode não parece adicionar recursos corretamente quando você constrói o projeto usando cmake, então eu adicionei esta peça ao CMakeLists.txt Arquivo. Copia a pasta inteira /data na minha pasta de recursos (como se eu tivesse adicionado um link de pasta "azul" no 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}
)

Outras dicas

Para estruturas, encontrei esta mensagem http://www.mail-archive.com/cmake@cmake.org/msg24659.html Peguei informações suficientes para isso:

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)

Em vez de definir cmake_exe_linker_flags, agora eu faço:

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

Isso funciona para o OpenGles também.

As versões CMake recentes passam arquivos .m e .mm para o compilador C ++, que detecta o idioma através da extensão, para que você não precise adicionar "-x Objective-C ++" aos sinalizadores explicitamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top