Cmake - मैक ओएस एक्स और विंडोज के लिए पोर्टेबल अनुप्रयोगों का निर्माण

छवि
जल्दी या बाद में, वह क्षण आता है जब हमारी प्रयोगशालाओं में, चमत्कारों, स्वादिष्ट पुस्तकालयों और सुंदर रूपरेखाओं से भरे आवेदन बड़ी दुनिया में, सामान्य लोगों के कंप्यूटर पर पूछना शुरू करते हैं जो जादू में परिष्कृत नहीं हैं। उनके कंप्यूटरों पर, यह नहीं है कि हमारे नए-नए ढांचे और विकास उपकरण वहां खड़े नहीं हैं, आप दिन में आग से एक साधारण संकलक भी नहीं खोज सकते। हमारा आवेदन पुस्तकालयों के बिना नहीं रह सकता है जो जंगली में बहुत दुर्लभ हैं, यह उनके बिना दूर हो जाएगा, इसके लिए कभी भी एक सफेद रोशनी नहीं देखें ...
लेकिन सब कुछ इतना दुखद नहीं है।

आमतौर पर ऐसे मामलों में, डेवलपर्स तथाकथित बंडल बनाते हैं, जिसमें एप्लिकेशन को चलाने के लिए सभी आवश्यक लाइब्रेरी और प्लगइन्स होते हैं। ज्यादातर वे या तो स्क्रिप्ट या आईडीई-निर्भर उपकरणों का उपयोग करके बनाए जाते हैं, या यहां तक ​​कि आपके हाथों से भी।
यदि आपने कभी विजुअल स्टूडियो से क्रॉल नहीं किया है, तो खुशी के लिए आपको ज्यादा जरूरत नहीं है, इंस्टॉलर बनाने के सभी व्यंजनों को लंबे समय से जाना और परखा गया है। लेकिन अगर आप क्रॉस-प्लेटफॉर्म सॉफ्टवेयर के प्रशंसक हैं, तो मुश्किलें शुरू हो जाती हैं। अक्सर यह सब सार्वभौमिकता के किसी भी संकेत के बिना वितरण के लिए तैयार बंडल बनाने के लिए बैसाखी के एक छोटे से ग्रोव की उपस्थिति की ओर जाता है। लेकिन इससे बचने के उपाय हैं।
कई वर्षों के लिए, क्रॉस-प्लेटफ़ॉर्म अनुप्रयोगों के लिए सबसे लोकप्रिय निर्माण विधि सीमेक है, जिसमें प्लेटफार्मों और संकलक के एक समूह के लिए समर्थन है, क्यूटी, इंस्टालर और डीएमजी बना सकते हैं, और बहुत कुछ। बंडलों के क्रॉस-प्लेटफॉर्म निर्माण के बारे में मैं बताना चाहता हूं। ऐसा करने के लिए, cmake 2.8 ने उत्कृष्ट fixup_bundle उपयोगिता पेश की

उपयोगिता विवरण


Fixup_bundle उपयोगिता बाहरी निर्भरता के लिए एप्लिकेशन और पुस्तकालयों (सबसे अधिक बार प्लग-इन) की एक अतिरिक्त सूची का सर्वेक्षण करती है, जिसके बाद यह निर्देशिका सूची में उनके लिए दिखता है जिसे हमने पहले से पुस्तकालयों को तैयार किया और कॉपी किया और RUNHATH मान सेट किया, जहां आवश्यक हो, ताकि एप्लिकेशन और प्लग इन का उपयोग कर सकें का लाभ लें। अंतिम चरण में, उपयोगिता बाहरी निर्भरता के लिए परिणामी बंडल की जांच करती है, अगर सब कुछ खराब है, तो यह एक त्रुटि की रिपोर्ट करता है।

परियोजना की तैयारी


काम करने का सबसे आसान तरीका मेक इंस्टॉल कमांड के परिणाम के साथ है। इस स्थिति में, इंस्टॉलेशन लक्ष्यों के सही निर्माण के साथ, आपको एक अच्छी तरह से संरचित निर्देशिका मिलेगी, जिसके खिलाफ fixup_bundle को सेट करना आसान होगा।
नीचे विभिन्न प्रकार के उद्देश्यों के लिए अधिष्ठापन पथ का मेरा संस्करण है।
if(WIN32)
set(BUNDLE_NAME ${_name}.exe)
set(BINDIR bin)
set(BUNDLE_PATH "${CMAKE_INSTALL_PREFIX}/${BINDIR}/${BUNDLE_NAME}")
set(LIBDIR lib${LIB_SUFFIX})
set(SHAREDIR share)
set(PLUGINSDIR bin)
set(IMPORTSDIR ${BINDIR})
set(RLIBDIR ${BINDIR})
elseif(APPLE)
set(BUNDLE_NAME ${_name}.app)
set(BUNDLE_PATH "${CMAKE_INSTALL_PREFIX}/${BUNDLE_NAME}")
set(BINDIR ${BUNDLE_NAME}/Contents/MacOS)
set(LIBDIR ${BINDIR})
set(RLIBDIR ${BUNDLE_NAME}/Contents/Frameworks)
set(SHAREDIR ${BUNDLE_NAME}/Contents/Resources)
set(PLUGINSDIR ${BUNDLE_NAME}/Contents/PlugIns)
set(IMPORTSDIR ${BINDIR})
else()
set(BUNDLE_NAME ${_name})
set(BINDIR bin)
set(BUNDLE_PATH "${CMAKE_INSTALL_PREFIX}/${BINDIR}/${BUNDLE_NAME}")
set(LIBDIR lib${LIB_SUFFIX})
set(RLIBDIR ${LIBDIR})
set(SHAREDIR share/apps/${_name})
set(PLUGINSDIR ${LIBDIR}/plugins/)
set(IMPORTSDIR ${LIBDIR}/imports)
endif()


उदाहरण का उपयोग करें

install(TARGETS client
RUNTIME DESTINATION ${BINDIR}
LIBRARY DESTINATION ${LIBDIR}
ARCHIVE DESTINATION ${LIBDIR}
BUNDLE DESTINATION .
)


इसी तरह, आपको सभी स्थापित फ़ाइलों और लक्ष्यों को लपेटने की आवश्यकता है ताकि आप एक सरल तरीके से नए प्लेटफार्मों के लिए पथ बदल सकें। इससे प्लेटफ़ॉर्म की सभी विशेषताओं को एनकैप करके बंडल बनाना बहुत आसान हो जाता है।

प्लगइन स्थापना


पुस्तकालयों और बायनेरिज़ के लिए सभी निर्भरताएँ स्वचालित रूप से पंजीकृत और पंजीकृत होंगी, बशर्ते कि वे खोज पथ में हों। लेकिन जब से हम आवेदन का निर्माण करने में कामयाब रहे, यह मानना ​​तर्कसंगत है कि हमारे पास ये सभी तरीके हैं! प्लगइन्स और पुस्तकालयों के साथ अधिक जटिल है जो गतिशील रूप से लोड किए गए हैं। जब तक आप कार्यक्रम शुरू नहीं करते हैं, तब तक आप यह सुनिश्चित नहीं करेंगे कि इसे सही संचालन के लिए और क्या चाहिए। दुर्भाग्य से, यह सबसे अच्छा विकल्प नहीं है। लेकिन हम एप्लिकेशन डेवलपर हैं, और हम जानते हैं कि हमारे एप्लिकेशन द्वारा प्लग-इन का उपयोग क्या किया जाता है जो अभी तक प्रकाशित नहीं हुआ है, इसलिए हम उन्हें खोजने के लिए कोड लिख सकते हैं और उन्हें लगभग निम्नलिखित तरीके से इंस्टॉलेशन उद्देश्य में जोड़ सकते हैं:
macro(DEPLOY_QT_PLUGIN _path)
get_filename_component(_dir ${_path} PATH)
get_filename_component(name ${_path} NAME_WE)
string(TOUPPER ${CMAKE_BUILD_TYPE} _type)
if(${_type} STREQUAL "DEBUG")
set(name "${name}${CMAKE_DEBUG_POSTFIX}")
endif()

set(name "${CMAKE_SHARED_LIBRARY_PREFIX}${name}")
set(PLUGIN "${QT_PLUGINS_DIR}/${_dir}/${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
#trying to search lib with suffix 4
if(NOT EXISTS ${PLUGIN})
set(name "${name}4")
set(PLUGIN "${QT_PLUGINS_DIR}/${_dir}/${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif()

#message(${PLUGIN})
if(EXISTS ${PLUGIN})
message(STATUS "Deployng ${_path} plugin")
install(FILES ${PLUGIN} DESTINATION "${PLUGINSDIR}/${_dir}" COMPONENT Runtime)
else()
message(STATUS "Could not deploy ${_path} plugin")
endif()
endmacro()


तो आप बस उन क्यूटी प्लगइन्स को सूचीबद्ध कर सकते हैं जिनकी वास्तव में आवश्यकता है। और स्थापित करके, वे हमारे लिए सही जगह पर होंगे।

list(APPEND QT_PLUGINS
bearer/qgenericbearer
...
imageformats/qtiff
iconengines/qsvgicon
)


एक अच्छे तरीके से, पैकेज प्रबंधकों के माध्यम से सॉफ्टवेयर वितरित करने के लिए, यह आवश्यक है कि मेक इनस्टॉल के सामान्य काम के दौरान सभी बाहरी लाइब्रेरीज़ को स्पर्श न करें, इसलिए कॉन्फ़िगरेशन में एक अलग विकल्प के रूप में बंडल असेंबली मोड को सक्षम करना सबसे अच्छा है।

option(CREATE_BUNDLE "Create application bundle then install" ON)


चल रहा है fixup_bundle

अगर (CREATE_BUNDLE)
set(APPS ${BUNDLE_PATH})
list(APPEND DIRS
${QT_LIBRARY_DIR}
${CMAKE_INSTALL_PREFIX}/${LIBDIR}
)
...
deploy_qml_modules(${QML_MODULES})
deploy_qt_plugins(${QT_PLUGINS})

INSTALL(CODE "
file(GLOB_RECURSE QTPLUGINS
\"\${CMAKE_INSTALL_PREFIX}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
" COMPONENT Runtime)
endif()


दिए गए टुकड़े के कोड से, यह काफी स्पष्ट है कि कैसे fixup_bundle काम करता है। अंत में, बंडल बनाने के लिए मेक इनस्टॉल कमांड पर्याप्त है। और पैकिंग-आधारित इंस्टॉलर पहले से ही प्रौद्योगिकी का विषय बन जाएगा, लेकिन यह एक और चर्चा का विषय है।

खैर, qml के लिए प्रगति संकेतक के रूप में एक छोटा सा उदाहरण। एप्लिकेशन QtCompords डेस्कटॉप का उपयोग करता है। यदि आप रुचि रखते हैं, तो आप इसे विंडोज या मैक ओएस एक्स लायन पर चलाने की कोशिश कर सकते हैं।
छवि
छवि

नमूना कोड गिथब पर है, सीमेक के लिए मैक्रोज़ का एक सेट भी है, जो बंडल को बेहद सरल और सुविधाजनक बनाता है।

जीत का निर्माण
मैक बिल्ड (केवल शेर)

Source: https://habr.com/ru/post/In132313/


All Articles