عربيالفرنسيةالإسبانية

Ad


OnWorks فافيكون

makepp_cookbook - عبر الإنترنت في السحابة

قم بتشغيل makepp_cookbook في مزود استضافة OnWorks المجاني عبر Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

هذا هو الأمر makepp_cookbook الذي يمكن تشغيله في مزود الاستضافة المجانية OnWorks باستخدام إحدى محطات العمل المجانية المتعددة على الإنترنت مثل Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

برنامج:

اسم


makepp_cookbook - أفضل طريقة لإعداد ملفات makefiles لمواقف مختلفة

الوصف


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

ابني المكتبات
Do لصحتك! في الحقيقة حاجة a مكتبة؟

لقد رأيت عددًا من البرامج الكبيرة التي تتكون من عدد كبير من الوحدات ، كل منها
الذي يعيش في الدليل الخاص به. بشكل عام ، يتم وضع كل دليل في مكتبته الخاصة ،
ثم يرتبط البرنامج النهائي بجميع المكتبات.

في كثير من الحالات ، أعتقد أنه بدلاً من استخدام المكتبة ، هناك نهج أفضل. مكتبات
ليست الحل الصحيح حقًا إذا كان كل وحدة لا يمكن إعادة استخدامها أو لن يتم إعادة استخدامها في أي وحدة أخرى
البرنامج ، لأنك ستحصل بعد ذلك على جميع عيوب المكتبات ولن تحصل على أي من عيوب
مزايا. المكتبات مفيدة في الحالات التالية:

1. عندما يكون لديك مجموعة من الإجراءات الفرعية التي يجب أن تكون مرتبطة بعدة طرق مختلفة
البرامج ، ولا يستخدم أي برنامج فعليًا 100٪ من الإجراءات الفرعية - يستخدم كل برنامج ملف
مجموعة فرعية مختلفة. في هذه الحالة ، من الأفضل استخدام مكتبة ثابتة (a
.a ملف ، أو ملف أرشيف).

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

3. عندما يكون وقت الارتباط طويلاً للغاية ، فإن استخدام المكتبات المشتركة لأجزاء كبيرة من ملفات
يمكن للبرنامج تسريع الارتباط بشكل كبير.

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

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

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

إليك كيفية القيام بذلك على Linux:

my_module.o: $ (filter_out my_module.o، $ (wildcard * .o))
ld -r -o $ (إخراج) $ (مدخلات)

ما سيفعله هذا هو إنشاء آخر .o دعا ملف my_module.o، والتي ستتألف من
كل من .o الملفات الموجودة في هذا الدليل الفرعي. سيحل الرابط أكبر عدد ممكن من ملفات
المراجع قدر الإمكان ، وستترك المراجع المتبقية ليتم حلها في ملف
المرحلة اللاحقة من الربط. في المستوى الأعلى ، عندما تنشئ برنامجك أخيرًا ،
بدلاً من الارتباط بـ libmy_module.a or libmy_module.so، يمكنك ببساطة الارتباط بـ
my_module.o. عندما تقوم بالربط .o من الملفات ، ليس لديك مشاكل مع تبعية الطلب في ملف
سطر الأوامر رابط.

السماح لل com.makepp الشكل خارج التي مكتبة نماذج . بحاجة

حتى لو كان لديك مكتبة حقيقية ، حيث يحتاج برنامج معين فقط إلى ملفات قليلة منها
(بدلاً من كل وحدة مفردة) ، قد يكون makepp قادرًا على معرفة الوحدات النمطية
المطلوبة من المكتبة وتضمين فقط من هم في المبنى. هذا يمكن أن يوفر الترجمة
الوقت إذا كنت تقوم بتطوير المكتبة مع برنامج ، لأنك لا تهتم بذلك
تجميع وحدات المكتبة غير المطلوبة لبرنامج معين تعمل عليه.

إذا كانت مكتبتك تلتزم بدقة بالاتفاقية التي تم الإعلان عنها في جميع الوظائف أو الفئات
ملف xyz.h يتم تنفيذها بالكامل في ملف مصدر يتم تجميعه إلى xyz.o (أي أنت
لا تقسم التنفيذ إلى xyz1.o و xyz2.o) ، ثم يمكنك استخدام ملف
وظيفة "$ (infer_objects)" لإخبار makepp بسحب الوحدات ذات الصلة فقط من
مكتبة. يمكن أن يعمل هذا بشكل جيد بشكل مدهش للمكتبات التي تحتوي على العشرات من الملفات المضمنة.
بشكل أساسي ، يفحص "$ (infer_objects)" قائمة .h الملفات التي تم تضمينها ، والمظهر
للمقابلة .o الملفات. إذا كنت تطور مكتبة وبرنامجًا بسرعة
معًا ، يمكن أن يوفر هذا وقت التجميع ، لأنك لا تهتم أبدًا بتجميع وحدات
المكتبة التي لا يستخدمها البرنامج.

إليك مثال على طريقة استخدامها:

my_program: $ (infer_objects * .o، $ (LIB1) / *. o $ (LIB2) / *. o)
$ (CXX) $ (المدخلات) -o $ (المخرجات) $ (SYSTEM_LIBRARIES)

ترجع الدالة "$ (infer_objects)" وسيطتها الأولى (بعد عمل حرف البدل
التوسيع عليه) ، ويبحث أيضًا في قائمة الملفات في وسيطتها الثانية ، لـ
الملفات التي يكون اسمها مطابقًا لاسم أي ملف .h من الملفات التي يتضمنها أي ملف في ملفه الأول
دعوى. إذا تم العثور على أي من هذه الملفات ، تتم إضافتها إلى القائمة.

ابني a ساكن مكتبة

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

LIBRARY_FILES = abcde

libmine.a: $ (LIBRARY_FILES) .o
& rm -f $ (الإخراج)
$ (AR) cr $ (الإخراج) $ (المدخلات)
ranlib $ (output) # قد لا يكون ضروريًا ، اعتمادًا على نظام التشغيل الخاص بك.

& rm هو الأمر "rm" المدمج لـ makepp. إذا كنت معتادًا على كتابة ملفات makefiles ، فقد تكون كذلك
قليلا مندهش من هذا الأمر. قد تكون معتادًا على شيء مثل هذا:

libmine.a: $ (LIBRARY_FILES) .o
$ (AR) ru $ @ $؟ # لا ينصح!!!!!!!
ranlib $ (الإخراج)

اين $؟ (المعروف أيضًا باسم "$ (selected_inputs)") هو متغير تلقائي يعني أي ملفات
التي تغيرت منذ آخر مرة تم فيها إنشاء المكتبة ، و $ @ هو نفسه تقريبًا
كـ "$ (output)".

لا ينصح بهذا الأسلوب لعدة أسباب:

لنفترض أنك قمت بإزالة ملف مصدر من الدليل الحالي. لا يزال في
مكتبة ، لأنك لم تعيد بناء المكتبة من الصفر. نتيجة لذلك ، أي شيء
التي ترتبط بهذه المكتبة ستكون قديمة .o ملف ، ويمكن أن يؤدي ذلك إلى إفساد ملف
يبني. (ذات مرة شعرت بالارتباك الشديد بسبب هذا عندما كنت أحاول إزالة الشفرة الميتة
من مشروع: ظللت أحذف الملفات وما زالت مرتبطة ، لذلك اعتقدت أن الكود كان
ميت. ومع ذلك ، عندما أعاد شخص آخر بناء المشروع من البداية ، لم يربط أيًا منه
أكثر! كانت المشكلة أن القديم .o الملفات كانت لا تزال في الأرشيف.)

أيضًا ، اعتمادًا على خياراتك لـ "ar" وتنفيذك لـ "ar" (على سبيل المثال ، إذا كنت
استخدم الخيار "q" بدلاً من "r") ، يمكنك الحصول على عدة إصدارات من ملف
نفسه .o داخل .a ملف. إذا كانت الإصدارات المختلفة تحدد جلوبالس مختلفة ، فإن ملف
رابط قد يحاول سحب كل منهما. ربما هذا شيء سيء.

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

إحدى الطرق التي تحاول بها makepp ضمان البنيات الصحيحة هي أنها ستفعل ذلك
إعادة البناء تلقائيًا إذا تغير سطر الأوامر لبناء هدف معين. لكن
باستخدام $؟ متغير يمكن أن يسبب مشاكل ، لأنه في كل مرة يتم تحديث المكتبة ،
أمر البناء مختلف. (يمكنك قمع هذا باستخدام
": build_check ignore_action" ؛ انظر makepp_build_check للحصول على التفاصيل.)

· تحديث الأرشيف بدلاً من إعادة بنائه سيجعل من المستحيل القيام به
ضع الملف بشكل صحيح في ذاكرة التخزين المؤقت للبناء (انظر makepp_build_cache للحصول على التفاصيل).

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

libmine.a: $ (only_targets * .o)
& rm $ (الإخراج)
$ (AR) cr $ (الإخراج) $ (المدخلات)

هذا يضع كل .o الملفات الموجودة في الدليل الحالي في المكتبة. البدل
يطابق أي .o موجود أو يمكن بناؤه ، لذلك سيعمل حتى لو لم تكن الملفات
موجودة حتى الان.

تُستخدم وظيفة "only_targets" للاستبعاد .o الملفات التي ليس لها مقابل
ملفات المصدر بعد الآن. افترض أن لديك ملفًا يسمى xyz.c التي اعتدت وضعها في
مكتبة. هذا يعني أن هناك ملف xyz.o ملف الكذب. أنت الآن تحذف xyz.c
لأنه قديم ، لكنك نسيت حذفه xyz.o. بدون "only_targets"
وظيفة، xyz.o ستظل مدرجة في قائمة .o الملفات المضمنة في المكتبة.

ابني a ديناميكي مكتبة

تعتمد عملية بناء مكتبات ديناميكية كليًا على النظام. سأكون عاليا
نوصي باستخدام libtool لبناء مكتبة ديناميكية (انظر
<http://www.gnu.org/software/libtool/>) ، لذلك ليس عليك معرفة كيفية القيام بذلك
النظام الأساسي الخاص بك ، وحتى يستمر ملف makefile في العمل حتى عند التبديل إلى ملف
نظام تشغيل مختلف. راجع وثائق libtool للحصول على التفاصيل. إليك نموذج Makefile:

ليبتول: = ليبتول

libflick.la: $ (only_targets * .lo)
$ (LIBTOOL) - الوضع = link $ (CC) $ (المدخلات) -o $ (المخرجات)

٪ .lo:٪ .c
$ (LIBTOOL) --mode = تجميع $ (CC) $ (CFLAGS) $ (يشمل) -c $ (المدخلات) -o $ (المخرجات)

ابني on عدة مختلف آلات or الشبكات
واحدة من أكثر المشاكل المزعجة مع makefiles هي أنها لا تعمل أبدًا عندما تقوم أنت بذلك
قم بالتبديل إلى جهاز مختلف أو شبكة مختلفة. إذا كان يجب أن تعمل ملفات makefiles الخاصة بك
كل آلة ممكنة على هذا الكوكب ، فربما تحتاج إلى نوع من التكوين
النصي. ولكن إذا كان عليك العمل على عدد قليل من الأجهزة المختلفة ، فهناك عدة طرق
يمكنك التعامل مع هذه المشكلة:

استعمل a مختلف تتضمن ملف in من جميع ال البيئات

في بداية كل ملف makefile ، يمكنك تضمين سطر مثل هذا:

تشمل system_defs.mk

الملف system_defs.mk ستقع عادةً في مكان مختلف لكل منها
بيئة. إذا كنت تريد أن تكون أدلة البناء الخاصة بك متطابقة على جميع الأجهزة ، فضع
system_defs.mk في دليل أعلى مجلدات البناء ، أو قم بتوفير مسار التضمين
لإجراء ذلك باستخدام خيار سطر الأوامر "-I".

عادة ما يكون هذا مؤلمًا نوعًا ما ، لكنه يعمل بشكل جيد إذا كان هناك عدد كبير من
اختلافات.

استعمل if البيانات

هذه أبشع طريقة للقيام بذلك ، لكنها عادة ما تنجح.

افسيس i386
CC: = دول مجلس التعاون الخليجي
آخر ifsys sun4u
CC: = سم مكعب
آخر ifsys hpux11
سي سي = ج89
ENDIF

إذا كان كل ما عليك فعله هو العثور على بعض البرامج أو المكتبات أو تضمين ملفات مختلفة
الأماكن ، قد تكون هناك طرق أفضل (انظر أدناه).

find_program، متاح أولا، إيجاد ملف

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

CXX ؛ = $ (find_program g ++ c ++ pg ++ cxx CC aCC)
# اختر أول مترجم C ++ متوفر في PATH.
# (بالمناسبة ، إذا لم تحدد CXX على الإطلاق ، فهذا
# هي الطريقة التي يتم تعريفها بها.)
TCL_INCLUDE؛ = -I $ (dir_noslash $ (findfile tcl.h، \
/usr/local/stow/tcl-8.4.5-nothread/include \
/usr/include/tcl8.4 / usr / include / tcl \
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))
# $ (findfile) يبحث عن tcl.h في كل ملف
# الدلائل وإرجاع المسار الكامل. هذا إذن
# تم تحويلها إلى خيار تجميع عن طريق تجريد ملف
# filename (مغادرة الدليل) والبادئة بـ -I.
٪ .o:٪ .cpp
$ (CXX) $ (CXXFLAGS) $ (TCL_INCLUDE) $ (المدخلات) -o $ (المخرجات)

TCL_LIB ؛ = $ ((first_available
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so
/net/na1/tcl8.4a3/lib/libtcl8.4.a
/net/na1/tcl8.4a3/lib/libtcl8.4.sl))
# ابحث عن مكان مكتبة Tcl. ثم هذا صراحة
# مدرج في أمر الارتباط:
my_program: * .o
$ (CXX) $ (CXXFLAGS) $ (المدخلات) -o $ (المخرجات) $ (TCL_LIB)

أخذ ميزة of بيرلس التكوين معلومات

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

يجعل البرنامج النصي للتكوين التلقائي لـ Perl جميع معلومات التكوين الخاصة به متاحة من خلال
٪ التكوين التجزئة. لا توجد صيغة للوصول إلى تجزئة Perl مباشرة في makepp ، لكن يمكنك ذلك
انتقل إلى Perl وقم بتعيين المتغيرات العددية ، والتي يمكن الوصول إليها مباشرة من makepp:

بيرل_بداية
# إحضار القيم من تجزئة التكوين.
استخدام التكوين ؛
CC = $ Config {'cc'}؛ # C المترجم الذي استخدمه بيرل ؛
$ byteorder_flags = "-DBYTEORDER = $ Config {'byteorder'}"؛
$ longdouble_defined = $ Config {'d_longdbl'} eq 'تعريف'؛
CFLAGS_for_shared_libs = $ Config {'cccdlflags'}؛
$ LDFLAGS_for_shared_libs = $ Config {'ccdlflags'}؛
perl_end

أيضًا ، بمجرد الانتهاء من "استخدام التكوين" ، يمكنك استخدام العبارة "$ (perl)" ، مثل
هذه:

SHARED_LIB_EXTENSION: = $ (perl $ Config {'dlext'})

اكتب "perldoc Config" لمعرفة المعلومات المتاحة عبر تجزئة٪ Config.

يعد إعداد Perl مكانًا جيدًا للحصول على أشياء مثل معلومات حول أنواع الأعداد الصحيحة ، البايت
النظام ، والأشياء الأخرى التي تتطلب عادةً نصًا برمجيًا للتكوين منفصلًا لتحديد موقعه. بعض
قد لا تكون معلوماته التي تتعلق بوجود أشياء في نظام الملفات
صالح. على سبيل المثال ، يشير $ Config {'cc'} إلى مترجم C الذي تم إنشاء perl به ،
والذي قد لا يكون نفس مترجم لغة سي الذي تريد استخدامه. في الواقع ، قد لا يكون موجودًا حتى
على نظامك ، حيث من المحتمل أنك قمت بتثبيت Perl عبر حزمة ثنائية.

تنويهات For استخدام البدل
مطابقة من جميع ملفات إلا a معين فرعية

لا تملك أحرف البدل الخاصة بـ Makepp أي طريقة في الوقت الحالي لمطابقة جميع الملفات إلا معين
مجموعة ، ولكن يمكنك القيام بذلك من خلال مجموعة من الوظائف.

على سبيل المثال ، افترض أن لديك برنامج اختبار لكل وحدة في مكتبة ، لكنك لا تملك ذلك
تريد تضمين برامج الاختبار في المكتبة. إذا كانت جميع برامج الاختبار تبدأ بـ
تجربه بالعربي، ثم يمكنك استبعادهم على النحو التالي:

libproduction.a: $ (filter_out test *، $ (wildcard * .o))

تعد الوظائف "$ (filter)" و "$ (filter_out)" مجموعة قوية جدًا من المرشحات للقيام بها
جميع أنواع عمليات التقاطع والاختلاف المحددة. على سبيل المثال،

SUBDIRS؛ = $ (filter_out * test * * $ (ARCH) *، $ (shell find. -type d -print))
# إرجاع جميع الدلائل الفرعية التي لا تحتوي على
# "test" أو $ (ARCH) فيها.

$ (مرشح $ (patsubst test_dir / test _٪. o،٪ .o، $ (wildcard test_dir / *. o)) ، \
$ (wildcard * .o))
# إرجاع قائمة بملفات .o في الوقت الحالي
# دليل يوجد له مقابل
# test _ *. o ملف في الدليل الفرعي test_dir.
$ (filter_out $ (patsubst man / man3 /٪. 3،٪ .o، $ (wildcard man / man3 / *. 3)) ، \
$ (wildcard * .o))
# إرجاع قائمة بملفات .o في الوقت الحالي
# دليل لا توجد به صفحة دليل
# بنفس اسم الملف في الدليل الفرعي man / man3.

باستخدام ال "$ (only_targets )" وظيفة إلى القضاء قديمة .o ملفات

افترض أنك تبني برنامجًا أو مكتبة باستخدام أمر build مثل هذا:

البرنامج: * .o
$ (CC) $ (المدخلات) -o $ (المخرجات)

افترض أنك قمت الآن بحذف ملف مصدر. إذا نسيت حذف المطابق .o ملف،
سيظل مرتبطًا به على الرغم من عدم وجود طريقة لبنائه بعد الآن. في ال
في المستقبل ، من المحتمل أن يتعرف makepp على هذا الموقف تلقائيًا ويستبعده من
قائمة أحرف البدل ، ولكن في الوقت الحالي ، عليك إخبارها باستبعادها يدويًا:

البرنامج: $ (only_targets * .o)
$ (CC) $ (المدخلات) -o $ (المخرجات)

Makepp لا يعرف بأي طريقة لبناء التي لا معنى لها .o الملف بعد الآن هو ملف المصدر الخاص به
ذهب ، لذلك ستستبعده الوظيفة "$ (only_targets)" من قائمة التبعيات.

تنويهات For متعدد الدلائل
كان أحد الأسباب الرئيسية لكتابة makepp هو تبسيط معالجة المضاعفات
الدلائل. Makepp قادر على الجمع بين أوامر البناء من ملفات makefiles متعددة ، لذلك يمكنه ذلك
التعامل بشكل صحيح مع قاعدة في ملف makefile واحد يعتمد على ملف تم إنشاؤه بواسطة ملف
makefile مختلفة.

ابحث عن إلى do in مكان of العودية جعل

يدعم Makepp التكرار العودي للتوافق مع الإصدارات السابقة ، لكن يوصى به بشدة
يمكنك أن ليس استخدمه. إذا كنت لا تعرف ما هو ، فهذا جيد.

راجع "نظام أفضل للبنيات الهرمية" في makepp للحصول على تفاصيل حول سبب عدم رغبتك في ذلك
استخدم الأمر العودي ، أو ابحث على الويب عن "التكرار العودي يعتبر ضارًا".

بدلاً من القيام بعمل تكراري لجعل الهدف "الكل" في كل ملف makefile ، فهو كذلك
عادةً ما يكون من الأسهل السماح لـ makepp بمعرفة الأهداف التي ستحتاج بالفعل إلى البناء.
علاوة على ذلك ، إذا وضعت كل ملفات .o وملفات المكتبة في نفس الدليل مثل ملف
makefiles ، فسوف يكتشف makepp تلقائيًا ملفات makefiles المطلوبة أيضًا - ملف
الشيء الوحيد المطلوب هو أن يجعل المستوى الأعلى لديك قائمة بالملفات المطلوبة
لخطوة الربط النهائية. انظر الأمثلة أدناه.

واحد MAKEFILE For كل دليل: مع ضمني جار التحميل

الطريقة الأكثر شيوعًا للتعامل مع الدلائل المتعددة هي وضع makefile في كل دليل
الذي يصف كيفية بناء كل شيء في هذا الدليل أو منه. إذا وضعت .o الملفات في
نفس الدليل مثل الملفات المصدر ، ثم التحميل الضمني (راجع "التحميل الضمني" في
makepp_build_algorithm) سيجد تلقائيًا جميع ملفات makefiles. إذا قمت بوضع ملف .o
الملفات في دليل مختلف (على سبيل المثال ، في دليل فرعي يعتمد على البنية) ، ثم أنت
من المحتمل أن تضطر إلى تحميل جميع ملفات makefiles ذات الصلة باستخدام العبارة "load_makefile".

فيما يلي نموذج لملف makefile عالي المستوى للتسلسل الهرمي للدليل الذي يستخدم التحميل الضمني
لإنشاء برنامج يتكون من العديد من المكتبات المشتركة (ولكن انظر "هل أنت حقًا بحاجة إلى ملف
مكتبة؟ "في makepp_cookbook ، لأن إنشاء برنامج من مجموعة من المكتبات المشتركة
ليست بالضرورة فكرة جيدة):

# makefile المستوى الأعلى:
البرنامج: main.o ** / *. la # رابط في المكتبات المشتركة من جميع الأدلة الفرعية.
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) $ (المدخلات) -o $ (المخرجات) $ (LIBS)

هذا إلى حد كبير كل ما تحتاجه في makefile المستوى الأعلى. في كل دليل فرعي ، أنت
ربما يفعل شيئًا كهذا:

# Makefile في كل دليل فرعي:
تضمين standard_defs.mk # عمليات البحث. ، .. ، ../ ..، وما إلى ذلك حتى ذلك
# يجد ملف التضمين المشار إليه.
# تجاوز بعض التعريفات المتغيرة هنا
SPECIAL_FLAGS: = -افعل_شيء مختلف

من المحتمل أن يكون كل ملف makefile هو نفسه إلى حد كبير إذا كانت الأوامر لبناء الأهداف
متشابهة تمامًا.

أخيرًا ، ستضع ما يلي في ملف معيار_defs.mk ملف (والذي من المحتمل أن يكون
أن يكون موجودًا في دليل المستوى الأعلى):

# إعدادات المتغيرات المشتركة وبناء قواعد لجميع الدلائل.
CFLAGS: = -g -O2
INCLUDE_DIR: = $ (يتضمن find_upwards)
# عمليات البحث. ، .. ، ../ ..، وما إلى ذلك لملف أو
# دليل يسمى يشمل ، لذلك إذا وضعت
# كل ما تبذلونه من تضمين الملفات هناك ، هذا الإرادة
# اعثر عليهم.
يشمل: = -I $ (INCLUDE_DIR)

٪ .lo:٪ .c
$ (LIBTOOL) --mode = تجميع $ (CC) $ (CFLAGS) $ (يشمل) -c $ (المدخلات) -o $ (المخرجات)

lib $ (dynamic_to.، ..). la: $ (only_targets * .lo)
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) -o $ (المخرجات) $ (المدخلات)
# $ (dynamic_to.، ..) تسترجع اسم التيار
# دليل فرعي نسبة إلى المستوى العلوي
# دليل فرعي. لذلك إذا كان هذا الملف makefile هو xyz / Makefile ،
# هذه القاعدة ستبني xyz / libxyz.la.

# نشر عام تضمين الملفات في المستوى الأعلى تشمل الدليل:
$ (INCLUDE_DIR) / public _٪. h: public _٪. h
: build_check symlnk
& ln -fr $ (إدخال) $ (إخراج)

واحد MAKEFILE For كل دليل: صريح جار التحميل

إذا كنت تريد أن تضع كل ما تبذلونه من ملفات .o الملفات إلى دليل فرعي يعتمد على البنية ، إذن
يجب تعديل المثال أعلاه ليكون شيئًا كالتالي:

# makefile المستوى الأعلى:
MAKEFILES: = $ (wildcard ** / Makeppfile) # قائمة بجميع الدلائل الفرعية لـ
# الحصول على ملفات makefiles من.

load_makefile $ (MAKEFILES) # قم بتحميلهم جميعًا.

include Standard_defs.mk # احصل على أمر الترجمة لـ main.o.

البرنامج: $ (ARCH) /main.o * / ** / $ (ARCH) / *. la
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) $ (المدخلات) -o $ (المخرجات) $ (LIBS)
# * / ** / $ (ARCH) يستثني الدليل الفرعي
# $ (ARCH) ، حيث لا نريد البناء
# مكتبة مشتركة.

سيكون كل ملف makefile هو نفسه تمامًا كما كان من قبل:

# Makefile في كل دليل فرعي:
تشمل standard_defs.mk
# ... تجاوزات متغيرة هنا

وأخيرا، معيار_defs.mk سيحتوي على شيء مثل ما يلي:

# إعدادات المتغيرات المشتركة وبناء قواعد لجميع الدلائل.
ARCH ؛ = $ (shell uname -s) - $ (shell uname -m) - $ (shell uname -r)
# في بعض الأحيان يستخدم الناس $ (shell uname -m) فقط ، لكن
# سيكون هذا هو نفسه بالنسبة إلى FreeBSD و Linux
# إلى x86. إن -r ليس مفيدًا حقًا على Linux ،
# لكنه مهم لأنظمة تشغيل أخرى: الثنائيات لـ
# لن يعمل SunOS 5.8 عادةً على SunOS 5.7.
& mkdir -p $ (ARCH) # تأكد من وجود دليل الإخراج.
CFLAGS: = -g -O2
INCLUDE_DIR: = $ (يتضمن find_upwards)
# عمليات البحث. ، .. ، ../ ..، وما إلى ذلك لملف أو
# دليل يسمى يشمل ، لذلك إذا وضعت
# كل ما تبذلونه من تضمين الملفات هناك ، هذا الإرادة
# اعثر عليهم.
يشمل: = -I $ (INCLUDE_DIR)

$ (قوس) /٪. lo:٪ .c
$ (LIBTOOL) --mode = تجميع $ (CC) $ (CFLAGS) $ (يشمل) -c $ (المدخلات) -o $ (المخرجات)

$ (قوس)/ ليب$ (dynamic_to.، ..). la: $ (only_targets * .lo)
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) -o $ (المخرجات) $ (المدخلات)
# $ (dynamic_to.، ..) تسترجع اسم التيار
# دليل فرعي نسبة إلى المستوى العلوي
# دليل فرعي. لذلك إذا كان هذا الملف makefile هو xyz / Makefile ،
# ستؤدي هذه القاعدة إلى إنشاء xyz / $ (ARCH) /libxyz.la.

# Copy public قم بتضمين الملفات في المستوى الأعلى include directory:
$ (INCLUDE_DIR) / public _٪. h: public _٪. h
& cp $ (إدخال) $ (إخراج)

تلقائيا يصنعون ال com.makefiles

إذا كانت ملفات makefiles كلها متشابهة للغاية (كما في المثال أعلاه) ، فيمكنك إخبار Makepp
لبنائها تلقائيًا إذا لم تكن موجودة. ما عليك سوى إضافة ما يلي إلى المستوى الأعلى
ملف تعريف:

SUBDIRS: = $ (filter_out unsanted_dir1 unsanted_dir2، $ (wildcard * / **))
$ (foreach) / Makeppfile: foreach $ (SUBDIRS)
& صدى "include standard_defs.mk" -o $ (الإخراج)
& صدى "_include extra_defs.mk" -o >> $ (output)
# إذا كان الملف extra_defs.mk موجودًا ، فحينئذٍ
# سيتم تضمينه ، لكن إذا لم يكن موجودًا ،
# سيتم تجاهل عبارة _include.

الآن سيتم إنشاء ملفات makefiles نفسها تلقائيًا.

واحد MAKEFILE فقط at ال تيشرت مستوى

إذا كانت جميع ملفات makefiles الخاصة بك متطابقة ، فقد تسأل: لماذا يجب أن يكون لدي ملف makefile في كل منها
مستوى؟ لماذا لا تضع كل ذلك في makefile المستوى الأعلى؟

نعم، من الممكن تحقيق ذلك. العيب الرئيسي هو أنه يصبح من الصعب تحديده
خيارات بناء مختلفة لكل دليل فرعي. العيب الثاني هو أن الخاص بك
من المحتمل أن يصبح makefile أصعب قليلاً في القراءة.

إليك مثال على فعل ذلك بالضبط:

# ملف makefile عالي المستوى للتسلسل الهرمي للدليل. يبني البرنامج
# من بين مجموعة من المكتبات المشتركة كمثال. (انظر المحاذير أعلاه
# لماذا قد ترغب في استخدام ارتباط تزايدي أو غيره
# نهج بدلاً من المكتبات المشتركة.)
makepp_percent_subdirs: = 1 # اسمح٪ لمطابقة أدلة متعددة.
SUBDIRS: = $ (filter_out * CVS * other-unsanted_dirs $ (wildcard **))
CFLAGS: = -g -O2
يشمل: = -يشمل

٪ .lo:٪ .c
$ (LIBTOOL) - الوضع = تجميع $ (CC) $ (يشمل) $ (CFLAGS) -c $ (المدخلات) -o $ (المخرجات)

$ (foreach)/ ليب$ (notdir $ (foreach)). la: $ (foreach) / *. lo: foreach $ (SUBDIRS)
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) -o $ (المخرجات) $ (المدخلات)
# حكم لجعل جميع المكتبات.

البرنامج: main.o ** / *. la
$ (LIBTOOL) - الوضع = link $ (CC) $ (CFLAGS) -o $ (المخرجات) $ (المدخلات)

يشمل / $ (notdir $ (foreach)): $ (foreach): foreach ** / public _ *. h
& cp $ (إدخال) $ (إخراج)
# نموذج حكم لنسخ علانية
يمكن الوصول إلى # ملفات .h في المكان الصحيح.

A نظيف الهدف

تحتوي ملفات makefiles التقليدية على هدف نظيف ، والذي يسمح بإزالة كل ما كان
مبني. هناك ثلاثة أسباب لعدم القيام بذلك باستخدام makepp:

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

2. سيحاول الأشخاص أحيانًا توفير الوقت عن طريق القيام بأمرين متناقضين في وقت واحد:
"تنظيف كل شيء". يمكن أن يؤدي هذا إلى إرباك نظام أحرف البدل الذكي الخاص بـ makepp ، لأنه سيفعل ذلك
احصل على الحقائق أولاً قبل القيام بأي شيء. ثم يأتي العمل النظيف ، الذي يفعل
لا تخبر makepp بما تفعله (في الواقع لا يمكنها ذلك ، لأنها تفسد شيئًا ما - ال
على عكس الغرض من أداة البناء). ثم يأتي "الكل" ، ولكن الملفات المحدثة ،
التي في ظروف غامضة.

3. هناك الأمر "makeppclean" ، الذي يقوم بنفس الشيء ، وبكفاءة أكبر.

ومع ذلك ، فإننا نحتفظ بهذا القسم التاريخي ، لأنه يخبرك بشيء عن
طريقة عمل makepp: الهدف المزيف الذي يسمى "نظيف" هو مجرد اسم لمجموعة من الأوامر
إزالة جميع الملفات الناتجة عن عملية الصنع. عادة ما يبدو الهدف النظيف
شيء من هذا القبيل:

$ (فوني كلين):
& rm -fm $ (wildcard * .o .makepp_log)
يتخلص # -m و .makepp_log من جميع ملفات makepp غير المرغوب فيها.

بدلاً من سرد الملفات التي تريد حذفها بشكل صريح ، يمكنك أيضًا إخبار makepp
أزل كل شيء يعرف كيف يبني ، مثل هذا:

$ (فوني كلين):
& rm -fm .makepp_log $ (only_targets *)

هذا له ميزة أنه إذا كان يمكن إنشاء أي من ملفات المصدر الخاصة بك من ملفات أخرى ،
سيتم حذفها أيضًا ؛ من ناحية أخرى ، قديمة .o الملفات (الملفات التي اعتادت أن تكون
قابل للبناء ولكن تم حذف ملف المصدر الخاص به منذ ذلك الحين).

إذا كان لديك تصميم يتضمن makefiles في عدة أدلة مختلفة ،
المستوى makefile قد يشير إلى الهدف "النظيف" (أو أي هدف زائف آخر) في مختلف
ملف تعريف:

# makefile المستوى الأعلى
SUBDIRS: = sub1 sub2

# بناء القواعد هنا

# تنظيف بعد البناء:
$ (تنظيف زائف): $ (SUBDIRS) / نظيف
& rm -fm .makepp_log $ (only_targets *)

بدلاً من ذلك ، يمكنك وضع هدفك "النظيف" فقط في ملف makefile ذي المستوى الأعلى ، والحصول عليه
معالجة كافة الدلائل ، مثل هذا:

$ (فوني كلين):
& rm -fm $ (only_targets ** / *)

باستخدام كيو تي وزارة الخارجية المعالج
يعرض هذا المثال ملف makefile لأداة تستخدم مكتبة Nokia Qt GUI (انظر
<http://qt.nokia.com>). الشيء الوحيد غير المعتاد في هذا الأمر هو أنك أنت
يجب تشغيل معالج أولي يسمى "moc" على معظم ملفات ".h" التي تحتوي على تعريفات عناصر واجهة المستخدم ،
لكنك لا تريد تشغيل "moc" على أي ملفات ".h" لا تستخدم الماكرو "Q_OBJECT".

تلقائيا تحديد التي ملفات حاجة وزارة الخارجية ملفات

يمكنك بالطبع سرد كافة ملفات ".h" التي تحتاج إلى تشغيل "moc" عليها.
ومع ذلك ، إذا كنت تقوم بتطوير أدوات جديدة بسرعة ، فقد يكون ذلك أمرًا مزعجًا
استمر في تحديث القائمة في ملف makefile. يمكنك الالتفاف حول الحاجة إلى قائمة moc
الوحدات صراحةً بشيء مثل هذا:

MOC: = $ (QTDIR) / bin / moc
الوحدات: = أيًا كانت الوحدات النمطية التي لديك في برنامجك
MOC_MODULES: = $ (patsubst٪ .h، moc_٪، $ (& grep -l / Q_OBJECT / * .h))
# يمسح جميع ملفات .h لماكرو Q_OBJECT.

my_program: $ (وحدات) .o $ (MOC_MODULES) .o
$ (CXX) $ (المدخلات) -o $ (المخرجات)

moc _٪. cxx:٪ .h # يصنع ملفات moc من ملفات .h.
$ (MOC) $ (إدخال) -o $ (إخراج)

٪ .o:٪ .cxx
$ (CXX) $ (CXXFLAGS) -c $ (إدخال) -o $ (إخراج)

هذا النهج يمسح كل من الخاص بك .h في كل مرة يتم فيها تشغيل makepp ، يبحث عن ملف
ماكرو "Q_OBJECT". هذا يبدو باهظ الثمن ، ولكن ربما لن يستغرق وقتًا طويلاً على الإطلاق. (ال .h
سيتعين تحميل جميع الملفات من القرص على أي حال من خلال عملية الترجمة ، لذلك سيتم تحميلها
يتم تخزينها مؤقتًا.)

تتضمن # ال .moc ملف

هناك طريقة أخرى تتمثل في "# تضمين" الإخراج من المعالج الأولي "moc" في عنصر واجهة المستخدم الخاص بك
ملف التنفيذ. هذا يعني أنه عليك أن تتذكر أن تكتب "#include" ، لكنها كذلك
ميزة أن هناك عددًا أقل من الوحدات المراد تجميعها ، وبالتالي يصبح التجميع أسرع.
(بالنسبة لمعظم عمليات التحويل البرمجي لـ C ++ ، يتم قضاء معظم الوقت في قراءة ملفات الرأس ، وملفات
يحتاج الإخراج من المعالج المسبق إلى تضمين العديد من الملفات تقريبًا مثل عنصر واجهة المستخدم الخاص بك
على أي حال.) على سبيل المثال:

// my_widget.h
فئة MyWidget: QWidget العامة {
Q_OBJECT
// ...
}

// my_widget.cpp

# تضمين "my_widget.h"
#include "my_widget.moc" // my_widget.moc هو الناتج من ملف
// المعالج الأولي moc.
// أشياء تنفيذية أخرى هنا.
MyWidget :: MyWidget (QWidget * parent، const char * name):
QWidget (الأصل ، الاسم)
{
// ...
}

أنت الآن بحاجة إلى قاعدة في ملف makefile الخاص بك لإنشاء جميع ملفات ".moc" ، مثل هذا:

MOC: = $ (QTDIR) / bin / moc
# القاعدة لإنشاء ملفات .moc:
٪ .moc:٪ .h
$ (MOC) $ (إدخال) -o $ (إخراج)

Makepp ذكي بما يكفي ليدرك أنه يحتاج إلى إنشاء "my_widget.moc" إذا لم يكن كذلك
موجودة بالفعل ، أو إذا كانت قديمة.

هذا النهج الثاني هو الذي أستخدمه عادةً لأنه يسرع عملية التجميع.

بدلاء For إهمال جعل التعابير
أهداف ماككمد

في بعض الأحيان يكون لدى الأشخاص قواعد في ملفهم الصحيح تعتمد على الهدف الذي يقومون ببنائه ،
باستخدام المتغير الخاص "MAKECMDGOALS". على سبيل المثال ، يرى المرء أحيانًا أشياء مثل
هذه:

ifneq ($ (مرشح إنتاج ، $ (MAKECMDGOALS)) ،)
CFLAGS: = -O2
آخر
CFLAGS: = -g
ENDIF

هذا سوف يعمل بشكل جيد مع makepp. ومع ذلك ، أوصي بعدم استخدام "MAKECMDGOALS" لمثل هذا
(وكذلك يفعل غنو يدويًا). أنت أفضل حالا وضع الخاص بك الأمثل و
تجميع التصحيح .o الملفات في دلائل منفصلة ، أو منحها بادئات أو
اللواحق ، أو استخدام المستودعات ، لإبقائها منفصلة.

ربما يكون الوقت الوحيد الذي قد ترغب فيه بالفعل في الإشارة إلى "MAKECMDGOALS" هو إذا كان كذلك
يستغرق وقتًا طويلاً لتحميل ملفات makefiles الخاصة بك ، ولا تحتاج إلى ذلك من أجل هدفك "النظيف"
(لكنك لست بحاجة إلى هدف نظيف). على سبيل المثال،

ifneq ($ (MAKECMDGOALS) ، نظيف)
load_makefile $ (wildcard ** / Makeppfile)
آخر
no_implicit_load. # منع التحميل التلقائي لأي ملفات makefiles أخرى.
ENDIF

$ (فوني كلين):
& rm -f $ (wildcard ** / *. o)

العودية جعل إلى نساعدك في بناء in مختلف الدلائل

انظر "نصائح لأدلة متعددة" في makepp_cookbook.

العودية جعل إلى تغيير قيمنا of a متغير

بعض ملفات makefiles تعيد استدعاء نفسها بقيمة مختلفة لمتغير ، على سبيل المثال ، debug
الهدف في جزء makefile التالي

.PHONY: كل التصحيح

المحسن:
برنامج $ (MAKE) CFLAGS = -O2

تصحيح:
برنامج $ (MAKE) CFLAGS = -g

البرنامج: ao bo
$ (CC) $ (CFLAGS) $ ^ -o $ @

٪ .o:٪ .c
$ (CC) $ (CFLAGS) -c $ <-o $ @

إذا كتب المستخدم "إجراء التصحيح" ، فإنه يبني البرنامج في الوضع الافتراضي مع تمكين التصحيح
بدلاً من التحسين.

أفضل طريقة للقيام بذلك هي بناء برنامجين مختلفين ، بمجموعتين مختلفتين من
ملفات الكائن ، مثل هذا:

CFLAGS: = -O2
DEBUG_FLAGS: = -g
الوحدات: = أب

البرنامج: $ (وحدات) .o
$ (CC) $ (CFLAGS) $ (المدخلات) -o $ (المخرجات)

تصحيح / برنامج: debug / $ (MODULES) .o
$ (CC) $ (DEBUG_FLAGS) $ (المدخلات) -o $ (المخرجات)

٪ .o:٪ .c
$ (CC) $ (CFLAGS) -c $ (إدخال) -o $ (إخراج)

تصحيح /٪. o:٪ .c
$ (CC) $ (DEBUG_FLAGS) -c $ (إدخال) -o $ (إخراج)

$ (التصحيح الزائف): التصحيح / البرنامج

ميزة القيام بذلك بهذه الطريقة هي (أ) أنك لست بحاجة إلى إعادة بناء كل شيء عندما تقوم بذلك
التبديل من التصحيح إلى الأمثل والعودة مرة أخرى ؛ (ب)

يمكن كتابة ما ورد أعلاه بشكل أكثر إيجازًا إلى حد ما باستخدام المستودعات. الأتى
makefile مكافئ تمامًا:

تصحيح المستودع =. # جعل الدليل الفرعي لتصحيح الأخطاء يشبه نسخة من
# الدليل الفرعي الحالي.
load_makefile debug CFLAGS = -g
# تجاوز CFLAGS عند استدعائه في دليل فرعي لتصحيح الأخطاء
CFLAGS: = -O2 # قيمة CFLAGS عند استدعائها في هذا الدليل الفرعي

البرنامج: ao bo
$ (CC) $ (CFLAGS) $ ^ -o $ @

٪ .o:٪ .c
$ (CC) $ (CFLAGS) -c $ <-o $ @

$ (التصحيح الزائف): التصحيح / البرنامج
# إذا كتب المستخدم "makepp debug" ، يبني
# تصحيح / برنامج بدلا من البرنامج.

منوع نصائح
كيفية do I نساعدك في بناء صورة واحدة؟ جزء بشكل مختلف م بمجرد؟

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

makepp DEBUG = 3 عربات التي تجرها الدواب. o # قم ببنائها بخيار آخر.
makepp --dont-build = buggy.o buggy # استخدمه ، بالرغم من خيار الإنشاء "الخاطئ".

كيفية do I جعل بالتأكيد my الناتج الدلائل يوجد؟

يمكنك تحديد قاعدة لبناء دليل الإخراج ، ثم تأكد من أن كل ملف
يذهب في دليل الإخراج يعتمد عليه. لكن عادة ما يكون من الأسهل القيام بشيء مثل
هذه:

# الطريقة الكلاسيكية
وهمي: = $ (shell test -d $ (OUTPUT_DIRECTORY) || mkdir -p $ (OUTPUT_DIRECTORY))
# هذا عادة ما يكون أسهل من جعل جميع الملفات تعتمد على
# $ (OUTPUT_DIRECTORY) ولديها قاعدة لعملها.
# لاحظ أنه يجب عليك استخدام: = بدلاً من = لإجبارها على ذلك
# التنفيذ على الفور.
# طريقة بديلة: استخدام كود Perl ، OUTPUT_DIRECTORY local var
بيرل_بداية
-d $ OUTPUT_DIRECTORY أو mkdir $ OUTPUT_DIRECTORY ؛
perl_end
# الطريقة الحديثة لا تفعل شيئا للأدلة الموجودة
& mkdir -p $ (OUTPUT_DIRECTORY)

يجب أن تكون إحدى هذه العبارات بالقرب من أعلى ملف makefile الخاص بك ، حتى يتم تنفيذها
قبل أي شيء قد يحتاج إلى الدليل.

كيفية do I القوة a أمر إلى تنفيذ on كل يبني؟

أسهل طريقة هي عدم استخدام آلية القواعد على الإطلاق ، ولكن ببساطة تنفيذها ، مثل
هذه:

وهمي: = $ (تاريخ الصدفة> last_build_timestamp)

أو ضعها في قالب بيرل ، مثل هذا:

بيرل_بداية
نظام ("أمر التنفيذ") ؛
perl_end

هذا النهج له عيوب أنه سيتم تنفيذه حتى لو كان هدف غير مرتبط
يجري الجري.

الطريقة الثانية هي إعلان الملف كهدف زائف ، حتى لو كان ملفًا حقيقيًا.
سيؤدي هذا إلى إجبار makepp على إعادة تنفيذ الأمر لبنائه في كل مرة ، ولكن فقط إذا كان كذلك
يظهر في قائمة التبعية لبعض القواعد.

كيفية do I اختصر ال عرض نساعدك في بناء أوامر؟

غالبًا ما يكون هناك العديد من الخيارات لأوامر التجميع التي يتم عرضها في ملف
الشاشة غير قابلة للقراءة. يمكنك تغيير ما يتم عرضه عن طريق منع عرض ملف
الأمر بأكمله ، ثم اطبع الجزء المثير للاهتمام من الأمر بشكل صريح. إنه
من السهل طباعة الجزء ذي الصلة فقط من الأمر باستخدام "$ (filter_out)" ، مثل
هذه:

ALL_CFLAGS = $ (CFLAGS) $ (يشمل) $ (ADDL_CXX_FLAGS) $ (DEBUG_FLAGS)

٪ .o:٪ .c
@ & صدى $ (notdir $ (CC)) ... \
$ (filter_out -I * $ (ADDL_CXX_FLAGS)، $ (ALL_CFLAGS)) \
-c $ (إدخال)
@ $ (CC) $ (ALL_CFLAGS) -c $ (إدخال) -o $ (مخرجات)

(يؤدي الحرف "@" الموجود أمام الأمر إلى منع طباعة الأمر.)

سيسمح لك ذلك بمشاهدة معظم الخيارات الشيقة ولكن لن يعرض كل
تشمل الدلائل (التي غالبًا ما يوجد الكثير منها!). إذا كان الجزء الذي تهتم به
in متجاور في الأمر ، يمكنك أيضًا استخدام وظيفة "print" (التي تضيف ملف
newline ، لذلك لا تريد العديد منهم):

استهداف:
@ ... $ (طباعة جزء ممتع) ...

كيفية do I تحول a ملف إلى التبعيات؟

بالنسبة لبعض تنسيقات الملفات الغامضة ، ليس من المجدي استخدام ماسح ضوئي. في مشروع واحد
لدينا ملفات xml ، على سبيل المثال foobar.xml الذي يحتوي على التبعيات لـ foobar.out:


أ
ب
ج


قررنا الالتزام بهذا التنسيق البسيط ، لذلك لا نحتاج إلى تحليل xml. مع ال
buildin & sed ، إليك ما نفعله بثلاثة استبدالات بسيطة للأنواع الثلاثة من
خطوط:

٪ .d:٪ .xml
& سيد! ! $ (جذع) .out: \\! || س! (. +) ! $$ 1 \\! || س! !# فارغ!' \
$ (إدخال) -o $ (إخراج)

تشمل foobar د

في محاولة لتضمين ذلك ، ينتج "foobar.d" أولاً:

فوبار.خارج: \
أ \
ب \
ج \
# فارغ

يتجنب السطر الفارغ (مجرد تعليق أو فارغ حقًا) القلق بشأن الزائدة
شرطة مائلة للخلف. البديل الذي ينتج قائمة متعددة الأسطر هو:

٪ .d:٪ .xml
& سيد! ! $ (الجذعية) .out: \ $$ ((! || s! !))! || s! <. +؟> !! g '\
$ (إدخال) -o $ (إخراج)

تشمل foobar د

ينتج عن ذلك ما يعادل:

foobar.out: $ ((
a
b
c
))

إذا كان لديك إعادة كتابة أكثر تعقيدًا ، فحدد دالة داخل makefile أو في ملف
الوحدة التي تقوم بتضمينها. على سبيل المثال ، يؤدي تحديد $ _ إلى تخطي سطور الإدخال:

مرشح بلدي الفرعي {
إرجاع undef $ _ إذا /
جذعي $ = f_stem ؛
س! ! $ stem.out: \ $ ((! || s! !))! || s! <. +؟> !! g؛
}

٪ .d:٪ .xml
& سيد! ! $ (الجذعية) .out: \ $$ ((! || s! !))! || s! <. +؟> !! g '\
$ (إدخال) -o $ (إخراج)

تشمل foobar د

استخدم makepp_cookbook عبر الإنترنت باستخدام خدمات onworks.net


خوادم ومحطات عمل مجانية

قم بتنزيل تطبيقات Windows و Linux

  • 1
    نظيفة عميق
    نظيفة عميق
    نص Kotlin الذي يرمي إلى بناء جميع الأسلحة النووية
    مخابئ من مشاريع Gradle / Android.
    مفيد عندما يتيح لك Gradle أو IDE
    تحت. تم اختبار البرنامج النصي على
    macOS ، لكن ...
    تنزيل برنامج Deep-clean
  • 2
    الكسوف Checkstyle المكونات في
    الكسوف Checkstyle المكونات في
    المكون الإضافي Eclipse Checkstyle
    يدمج كود Java Checkstyle
    المدقق في Eclipse IDE. ال
    يوفر المكون الإضافي تعليقات في الوقت الفعلي لـ
    المستخدم عن فيك ...
    قم بتنزيل Eclipse Checkstyle Plug-in
  • 3
    com.AstrOrzPlayer
    com.AstrOrzPlayer
    AstrOrz Player هو مشغل وسائط مجاني
    برنامج ، جزء يعتمد على WMP و VLC. ال
    لاعب بأسلوب بسيط ، مع
    أكثر من عشرة ألوان موضوع ، ويمكن أيضا
    ب ...
    تنزيل AstrOrzPlayer
  • 4
    موفيستارتف
    موفيستارتف
    Kodi Movistar + TV es un ADDON para XBMC /
    Kodi que تسمح لك بتوفير واحد
    فك التشفير دي لوس سيرفيسيوس IPTV دي
    Movistar Integrado en uno de los
    المراكز الطبية أماه ...
    تحميل برنامج Movistartv
  • 5
    كود :: بنات
    كود :: بنات
    Code :: Blocks هو برنامج مجاني ومفتوح المصدر ،
    عبر الأنظمة الأساسية C و C ++ و Fortran IDE
    بني لتلبية الاحتياجات الأكثر إلحاحًا
    من مستخدميها. انها مصممة لتكون جدا
    يمتد ...
    تنزيل Code :: Blocks
  • 6
    وسط
    وسط
    وسط أو واجهة ماين كرافت المتقدمة
    وتتبع البيانات / الهيكل هو أداة ل
    عرض لمحة عامة عن Minecraft
    العالم ، دون إنشائه فعليًا. هو - هي
    علبة ...
    تحميل Amidst
  • أكثر "

أوامر لينكس

Ad