2009-05-04 27 views
24

Điều này liên quan chặt chẽ đến previous question của tôi, đó là về việc sử dụng CMake để xây dựng một thư viện tĩnh trên iPhone. Tôi đã làm việc đó để thiết lập số CMAKE_OSX_SYSROOT.Cách thiết lập CMake để xây dựng một ứng dụng cho iPhone

Tuy nhiên, cách này không hiệu quả để xây dựng ứng dụng. CMakeLists.txt của tôi trông giống như:

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

Một vài lưu ý:

  • tôi đưa ra một cách rõ ràng -framework nối tùy chọn vì find_library không làm việc cho tất cả các khuôn khổ (nó tìm thấy hầu hết trong số họ, nhưng không phải OpenGLES). Tôi không hiểu tại sao, vì tất cả chúng đều nằm trong cùng một thư mục ${SDK}/System/Library/Frameworks. Điều này khiến tôi tin rằng tôi đã làm điều gì đó sai, nhưng tôi không biết điều gì.
  • Tôi đã thêm MACOSX_BUNDLE vào lệnh add_executable để loại sản phẩm được tạo sẽ là com.apple.product-type.application thay vì com.apple.product-type.tool, dường như không tồn tại trên iPhone.

Trong mọi trường hợp, ứng dụng biên dịch và liên kết một cách chính xác, nhưng khi tôi chạy nó trong mô phỏng, tôi nhận được sợ hãi

Failed to launch simulated application: Unknown error. 

Có rất nhiều trường hợp báo cáo về vấn đề này trên google và stackoverflow , nhưng tất cả các giải pháp liên quan đến việc dọn dẹp hoặc tạo một dự án mới và di chuyển các tệp; nhưng tôi đang biên soạn một bản sao mới sau khi CMake thực hiện công việc của mình, vì vậy không có tác phẩm nào được áp dụng.

Tôi đã tìm thấy this thread trên danh sách gửi thư của CMake, nhưng nó chỉ báo cáo thành công trong việc xây dựng thư viện và sau đó gửi đi.

Trả lời

41

Cuối cùng tôi đã tìm ra cách thực hiện việc này. Đây là những gì tập tin CMakeLists.txt của tôi trông giống như:

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

Rõ ràng, sự thay đổi mycompany để tên công ty của bạn, và thay đổi My Name tên của bạn. Tôi thấy rất hữu ích khi thêm thư mục liên kết \${HOME}/\${SDKROOT}/lib như trên, để nếu ứng dụng của bạn liên kết đến một thư viện tĩnh (đặc biệt là thư viện chung), bạn có thể xây dựng các thư viện iPhoneOS và iPhoneSimulator riêng biệt và dễ dàng liên kết tới bên phải một, thay vì lo lắng về một nhị phân phổ quát.

Ngoài ra, Xcode dường như không thêm đúng tài nguyên khi bạn xây dựng dự án bằng CMake, vì vậy tôi đã thêm đoạn này vào tệp CMakeLists.txt. Nó sao chép toàn bộ thư mục /data vào thư mục tài nguyên của tôi (như thể tôi đã thêm một liên kết thư mục "màu xanh" trong 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

Tôi thấy câu trả lời của bạn rất hữu ích - tôi đã thực sự bị mất với CMake và Xcode. Tôi đã thử sử dụng phiên bản sửa đổi nhỏ của tệp CMakeLists của bạn. Tuy nhiên, tôi gặp phải một số vấn đề lạ. Có lẽ bạn có thể hãy xem câu hỏi của tôi? http://stackoverflow.com/questions/5473448/cmake-and-xcode-cannot-find-interface-declaration-for-nsobject Cảm ơn trước :) – Shade

+2

Có một cách khác cho tài nguyên ngay bây giờ, xem tại đây: http://cmake.org/gitweb?p=cmake.git;a=blob;f=Tests/iOSNavApp/CMakeLists.txt Tuy nhiên, điều này loại bỏ hệ thống phân cấp thư mục, vì vậy tên tệp trùng lặp là một vấn đề ... –

1

các phiên bản gần đây CMake vượt qua .m và các file .mm đến ++ biên dịch C, trong đó phát hiện ngôn ngữ thông qua việc mở rộng, do đó bạn không cần phải thêm "-x Objective-C++" vào cờ một cách rõ ràng.

+2

Ồ đúng rồi, đó chỉ là ngẫu nhiên vào tập lệnh. Tôi thực sự có các tệp .cpp chủ yếu (vì tôi đang biên dịch chéo), vì vậy tôi cần điều đó. –

+0

@JesseBeder: Tại sao bạn biên dịch các tệp '.cpp' làm mục tiêu-C++? Chúng tôi biên dịch các tệp '.cpp' thành C++ và có một số tệp' .mm' với chức năng nền tảng cụ thể cần tương tác với Cocoa. –

+0

@JanHudec, một số tệp '.cpp' của tôi có điều kiện bao gồm Objective-C (với' # ifdef'), vì vậy khi được biên dịch cho iPhone, chúng tương tác với Objective-C (và vì vậy nên được xem là Objective-C++) , nhưng khi biên dịch cho PC, chúng không (nên được coi là C++). –

7

Đối với các khuôn khổ, tôi thấy thông điệp này http://www.mail-archive.com/[email protected]/msg24659.html Tôi túm lấy đủ thông tin cho việc này:

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) 

Thay vì đặt CMAKE_EXE_LINKER_FLAGS, bây giờ tôi làm:

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

này không làm việc cho OpenGLES là tốt.

+0

Điều này dường như thêm các khuôn khổ trong "Các cờ liên kết khác" AKA OTHER_LDFLAGS nhưng không thêm bất kỳ thứ gì vào tiêu đề "Đường dẫn tìm kiếm tiêu đề" AKA HEADER_SEARCH_PATHS vì vậy mã của tôi không thể tìm thấy UIKit/UIKit.h. Gợi ý? – Emmanuel

Các vấn đề liên quan