كيفية إعداد CMake لإنشاء تطبيق للآيفون
سؤال
وهذا يرتبط ارتباطا وثيقا بي السؤال السابق, ، والذي كان يدور حول استخدام 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++" إلى العلامات بشكل صريح.