تجميع الصليب في عامل ميناء. لم لا؟

ما هو تجميع الصليب؟ ما هي الأدوات اللازمة لإنشاء ملفات ثنائية لنظام التشغيل Windows على نظام Linux ؟ كيفية تكوين حاوية عامل ميناء لهذا كله؟ فيما يلي بعض المشكلات التي سيتم مناقشتها أدناه.


الأدوات


يتيح لك التحويل البرمجي المتقاطع الحصول على تعليمات برمجية قابلة للتنفيذ لمنصة أخرى بخلاف تلك التي تعمل عليها هذه العملية.


في هذه المقالة ، سننظر في الترجمة المتقاطعة لنظام التشغيل Windows الأساسي على نظام Linux .


مثال على برنامج التحويل البرمجي المشترك هو Mingw-w64 . في الواقع ، لا يوفر سوى أداة لإنشاء التطبيق ، ولكن إذا كنت بحاجة إلى مكتبات تابعة لجهات أخرى ليست جزءًا من المحكمة الخاصة بلبنان ، فسوف يتعين عليك جمعها وتوابعها. يمكنك أيضًا استخدام الملفات الثنائية الجاهزة ، كما هو موضح في هذه المقالة .


مشروع mxe ، الذي يوفر ليس فقط الأدوات ، ولكن أيضًا المكتبات ، يبسط إعداد التجميع. يمكن الاطلاع على قائمتهم على الموقع الرسمي. عند تثبيت المكتبات ، يتم استخدام التحكم في التبعية ، أي سيتم تثبيت الحزمة المطلوبة وكل ما هو ضروري لتشغيلها. يتم تسليم الأدوات في تكوين تم تكوينه مسبقًا ، على سبيل المثال ، للتجميع الثابت لتطبيقات 64 بت. هذا يسهل كثيرا التجمع.


يتم نشر بيئة mxe في المجلد المحلي للمستخدم. للقيام بذلك ، ما عليك سوى تثبيت التبعيات من خلال مدير الحزم واستنساخ المستودع. يوجد في جذر المستودع ملف Makefile ، الذي يقوم بتثبيت المكتبات المعينة لهذا الغرض ، ويضيف أدوات للتجميع ، إلخ.


من المهم ملاحظة أن بيئة البناء مترجمة داخل مجلدها ، مما يتيح لك تكوين بيئة فردية لكل تطبيق.


حاوياتها


دعنا نقول أنه تم تكوين إصدار الإصدار لـ Windows على الجهاز المحلي. يتم إصدار الإصدارات في كثير من الأحيان ، في بعض الإصدارات ، تتم إضافة مكتبات جديدة ، ويتم حذف بعضها ، على سبيل المثال. في أحد الأيام الجميلة ، يطالب الرئيس بالتخلص من إصدار الإصدار للمبتدئين. كيف يقوم بتكوين بيئة البناء الخاصة به؟ ما هي المكتبات التي ينبغي أن تؤخذ من مستودع mxe ، ومن أجل أي بناء من المصدر؟


في هذه الحالة ، يمكنك الحصول على البرنامج النصي bash الذي سينشر البيئة بأكملها في مجلد معين. وبعد محاولة تحديث هذا البرنامج النصي. ولكن ، مثل الوثائق الخاصة بالمشروع ، في لحظة حرجة ، يمكن أن تصبح قديمة.


الحل الجيد هو عزل بيئة البناء الخاصة بنا داخل حاوية عامل الميناء . سيحتوي ملف عامل الميناء نفسه على مجموعة من الإرشادات المستقلة لنشر البيئة ، وسيساعد وجود الحاوية على تجنب ازدحام النظام المنزلي باستخدام مكتبات غير ضرورية.


وضع كل ذلك معا


للحصول على عرض توضيحي ، دعنا نأخذ مشروع Qt بسيط - SimpleQtProject . تم بناء هذا المشروع بواسطة الأداة المساعدة qmake ، ويتكون من نموذج واحد. هذا هو ، بطبيعة الحال ، القيام به للبساطة. أيضا في مجلد عامل ميناء هو ملف لبناء الحاوية.


النظر في ملف مشروع عامل ميناء . في الواقع ، يتكون من عدة أجزاء رئيسية:


  • تثبيت التبعيات لنظام البناء
  • تركيب وتكوين نظام التجميع
  • تجميع المشروع ونسخ المصنوعات اليدوية إلى النظام المضيف

يتم النظر إلى الأوامر الأساسية فقط من الملف أدناه ، للحصول على معرفة كاملة ، يُنصح بالرجوع إلى المستودع .

نتخطى النقطة الأولى ونتابع مباشرة إلى تركيب mxe .
استنساخ المستودع:


RUN mkdir /cross \ && cd /cross \ && git clone https://github.com/mxe/mxe.git \ && cd mxe \ && git checkout build-2019-06-02 

في وقت كتابة هذا التقرير ، كان الإصدار الأخير build-2019-06-02 . لا يتم استخدام الفرع الرئيسي هنا لسبب بسيط: مطلوب تكرار التجميع. خلاف ذلك ، عند إضافة تعهدات جديدة للسيد ، قد ينقطع التجميع.


بعد ذلك ، نقوم بتكوين نظام الإنشاء:


 RUN make MXE_TARGETS=x86_64-w64-mingw32.static qtbase -j4 JOBS=4 

سيضيف هذا الأمر أدوات (مثيلات cmake و Mingw-w64 ، إلخ) للتجميع الثابت للمشروع ضمن بنية 64 بت ، ثم تجميع Qt باستخدامها.


الخطوة التالية هي إضافة المسار إلى الملفات القابلة للتنفيذ mxe في PATH :


 ENV PATH="/cross/mxe/usr/bin:${PATH}" 

بعد تهيئة بيئة التصميم ، يمكنك الانتقال مباشرة إلى العنصر الأخير:


 ENTRYPOINT x86_64-w64-mingw32.static-qmake-qt5 /app/src/SimpleQtProject.pro \ && make release \ && cp release/SimpleQtProject.exe /app/res/ 

وهنا بعض النقاط لتوضيح. من المفترض أنه عند بدء تشغيل الحاوية ، سيتم تثبيت المجلد المصدر الذي يحتوي على ملف * .pro في / app / src / folder ، وسيتم تثبيت المكان الذي يجب أن تضاف فيه نتائج التجميع في الدليل / app / res / .


فيما يلي مثال على أمر لإنشاء صورة عامل ميناء ، يجب تشغيله في مجلد عامل ميناء المشروع المعني:


 docker build -t simple-qt-build --file windows.docker . 

يبدأ التجميع هناك:


 docker run --mount type=bind,source=$(pwd)/result/,target=/app/res --mount type=bind,source=$(pwd)/../,target=/app/src simple-qt-build 

قبل تنفيذ الأمر ، تحتاج إلى إنشاء مجلد النتائج في دليل عامل ميناء لنسخ النتائج.


الجمعية التخصيص


بشكل افتراضي ، يوفر mxe إصدار MinGW 5.5.0 (على الأقل هذا صحيح للبناء 2019-06-02 ).


إذا كان المشروع يستخدم ميزات جديدة لـ C ++ 17 ، فهذا يعني أن إصدار المترجم غير مرضٍ. لحسن الحظ ، توفر بيئة الإنشاء إصدارات أحدث كمكونات إضافية منفصلة. لحل مشكلتنا ، نحتاج إلى إضافة تعليمات لاستخدام المكون الإضافي المناسب لفريق بناء المكتبة:


 make MXE_TARGETS=x86_64-w64-mingw32.static MXE_PLUGIN_DIRS=plugins/gcc7 qtbase -j4 JOBS=4 

سيقوم هذا الأمر بإنشاء مجموعة للتجميع الثابت لتطبيقات 64 بت باستخدام برنامج التحويل البرمجي للإصدار السابع ( 7.4.0 ). إذا كانت هذه المجموعة موجودة بالفعل ، فلن يتم تغييرها.


يمكن الاطلاع على قائمة بجميع المكونات الإضافية المتاحة على الصفحة .


يحتوي دليل mxe / src على ملفات * .mk التي تصف معلمات التجميع الخاصة بحزمة معينة. إذا لزم الأمر ، يمكنك إجراء التعديلات اللازمة على حزمة موجودة أو إضافة الخاصة بك. يوصف هيكل الملف هنا - https://github.com/mxe/mxe/wiki/Add-a-New-Package:-Full-Version .


لنسخ التبعيات ، يوفر مشروع mxe الأداة المساعدة copydlldeps.sh . لكن هذه ليست الأداة الوحيدة المفيدة ، يمكن العثور على قوائمهم الكاملة على الصفحة .


CMake ورابط ثابت كيو تي


لقد حدث ذلك في مشروعي الذي استخدمته كيو تي ونظام بناء CMake . عندما تقرر إنشاء مشروع لنظام Windows ، كان الحل الممتاز هو بناء كل شيء باستخدام رابط ثابت لتزويد المستخدمين بثنائي واحد ، دون أي تبعية.


من خلال تحليل جبل من أخطاء الرابط ، كان من الممكن معرفة أن مثل هذا التجمع خارج الصندوق لا يعمل ، في أي مكان آخر. الحقيقة هي أنه عند استخدام الارتباط الثابت ، يقوم qmake بإنشاء ملف * .cpp ، والذي يحتوي على تعليمات لاستيراد المكونات الإضافية ، حول هذا النوع:


 // This file is autogenerated by qmake. It imports static plugin classes for // static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables. #include <QtPlugin> Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QGifPlugin) Q_IMPORT_PLUGIN(QICOPlugin) Q_IMPORT_PLUGIN(QJpegPlugin) 

يتم أيضًا إضافة علامات ومكتبات مرحلة الارتباط في Makefile .


يمكنك تجربة تجربة هذا التصميم في CMakeLists.txt :


 foreach(plugin ${Qt5Gui_PLUGINS}) get_target_property(_loc ${plugin} LOCATION) message("Plugin ${plugin} is at location ${_loc}") set(plugin_libs ${plugin_libs} ${_loc}) endforeach() 

ثم قم بإضافة استخدام plugin_libs . لكن بالنسبة لي ، فإن هذا النهج لم يحقق أي نتائج.


في النهاية ، توصلت إلى قرار ربط جميع المكتبات الخارجية (إن أمكن) ديناميكيًا ونسخها مع الملف القابل للتنفيذ ، باستخدام dlls اللازمة باستخدام copydlldeps.sh . في مزيد من التفاصيل حول النشر ضمن Qt ضمن Windows ، تم توضيح ذلك في المقالة .


في الختام


لقد ظهر أعلاه كيف ، في بضع خطوات بسيطة ، يمكنك تهيئة البيئة لتجميع مشروع ما. ولكن ، لسوء الحظ ، في الظروف الحقيقية ، كل شيء ليس وردياً للغاية.


على الرغم من أن مشروع mxe يوفر قائمة مثيرة للإعجاب بالمكتبات ، إلا أنه قد لا يشمل تلك التي تحتاجها أو يحتوي على إصدارات جديدة للغاية. نعم ، هناك فرصة لإنشاء حزمة بنفسك أو ، في أسوأ الأحوال ، إنشاء مكتبة من المصدر. ولكن لا يمكن بناء كل شيء باستخدام برنامج التحويل البرمجي المتداخل ، لذلك لا يمكنني القيام بذلك باستخدام مشروع cpprestsdk ، لأنه يحتاج إلى vcpkg المثبت.


تعد العديد من المشكلات التي قد تنشأ عند إنشاء مشروع باستخدام برنامج التحويل البرمجي المتقاطع نموذجيًا لتطوير الأنظمة الأساسية المشتركة بشكل عام. على سبيل المثال ، حدث خطأ غريب بسبب عنصر تعداد ERROR . اتضح أنه في أحد ملفات رأس Windows يوجد ماكرو بنفس الاسم. استبدالها كسر كل رمز.


من اختصاص الجميع استخدام الترجمة المتقاطعة أم لا. هذا جلب لي ربح جيد. لقد قمت بتكوين التجميع للعديد من توزيعات Linux و Windows في حاويات ترسية منفصلة لمشروعي SecureDialogues ، أضفت makefile واحدًا لبدء العملية واحدة تلو الأخرى لكل حاوية. بعد ذلك ، قم بإجراء تكوين وبعد فترة أحصل على الملفات الثنائية لنظام التشغيل المطلوب في المجلد المحلي.

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


All Articles