سؤال

وهذا يرتبط ارتباطا وثيقا بي السؤال السابق, ، والذي كان يدور حول استخدام CMake لإنشاء مكتبة ثابتة على iPhone.لقد حصلت على ذلك للعمل على إعداد CMAKE_OSX_SYSROOT.

ومع ذلك، هذا لا يعمل لبناء التطبيق.لي CMakeLists.txt يشبه:

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

بعض الملاحظات:

  • أنا أعطي صراحة -framework خيار الربط لأن find_library لم ينجح مع جميع الأطر (وجد معظمها، ولكن لا OpenGLES).لا أفهم لماذا، لأنهم جميعا في نفس المجلد ${SDK}/System/Library/Frameworks.وهذا يقودني إلى الاعتقاد بأنني كنت أفعل شيئًا خاطئًا، لكن لا أعرف ما هو.
  • أضفت MACOSX_BUNDLE إلى add_executable الأمر بحيث يكون نوع المنتج الذي تم إنشاؤه com.apple.product-type.application بدلاً من com.apple.product-type.tool, ، والذي يبدو أنه غير موجود على iPhone.

على أية حال، يتم تجميع التطبيق وربطه بشكل صحيح، ولكن عندما أقوم بتشغيله في جهاز المحاكاة، أشعر بالخوف

Failed to launch simulated application: Unknown error.

هناك الكثير من الحالات التي تم الإبلاغ عنها لهذه المشكلة على Google وStackoverflow، ولكن جميع الحلول تتضمن تنظيف أو إنشاء مشروع جديد ونقل الملفات؛لكنني أقوم بتجميع نسخة جديدة بعد أن يقوم CMake بعمله، لذلك لا ينطبق أي من ذلك.

وجدت هذا الموضوع في القائمة البريدية لـ CMake، ولكنها تشير فقط إلى النجاح في بناء مكتبة، ثم تتلاشى.

هل كانت مفيدة؟

المحلول

لقد اكتشفت أخيرا كيفية القيام بذلك.وهنا ما بلدي 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")

ومن الواضح أن التغيير mycompany إلى اسم شركتك وتغييره My Name الى اسمك.لقد وجدت أنه من المفيد جدًا إضافة دليل الارتباط \${HOME}/\${SDKROOT}/lib كما هو مذكور أعلاه، بحيث إذا كان تطبيقك يرتبط بمكتبة ثابتة (خاصة مكتبة عامة (غير تابعة لـ iPhone)، فيمكنك إنشاء مكتبات iPhoneOS وiPhoneSimulator منفصلة والارتباط بسهولة بالمكتبة الصحيحة، بدلاً من القلق بشأن ثنائي عالمي.

أيضًا، يبدو أن Xcode لا يضيف الموارد بشكل صحيح عند إنشاء المشروع باستخدام CMake، لذلك أضفت هذه القطعة إلى CMakeLists.txt ملف.يقوم بنسخ المجلد بأكمله /data في مجلد الموارد الخاص بي (كما لو كنت قد أضفت رابط المجلد "الأزرق" في 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}
)

نصائح أخرى

بالنسبة للأطر، وجدت هذه الرسالة http://www.mail-archive.com/cmake@cmake.org/msg24659.html لقد حصلت على معلومات كافية لذلك:

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)

بدلاً من تعيين CMAKE_EXE_LINKER_FLAGS، أقوم الآن بما يلي:

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

هذا يعمل مع OpenGLES أيضًا.

تقوم إصدارات CMake الأخيرة بتمرير ملفات .m و.mm إلى برنامج التحويل البرمجي C++، الذي يكتشف اللغة من خلال الامتداد، لذلك لا تحتاج إلى إضافة "-x object-c++" إلى العلامات بشكل صريح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top