لذلك لا يزال ، لماذا تحتاج جعل؟



يبدو أن كل شيء بدأ ، بسؤال بسيط قادني أولاً إلى ذهول - "لماذا أحتاج إلى القيام به؟ لماذا لا يمكنني أن أتماشى مع البرامج النصية للباش ؟". وفكرت - حقا ، لماذا أحتاج إلى صنع؟ (والأهم من ذلك) ما هي المشاكل التي يحلها؟


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



لتجميعها ، قم بتشغيل أمر واحد فقط:


$ gcc main.c -o main 

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



للتجميع ، تحتاج إلى تنفيذ عدد الأوامر التالية بشكل مشروط:


 $ gcc -c src0.c $ gcc -c src1.c $ gcc -c main.c $ gcc -o main main.o src0.o src1.o 

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


 $ ./build.sh 

سافرنا على! المشروع ينمو ، وعدد الملفات المصدر يزداد وهناك المزيد من الخطوط فيها. بدأنا نلاحظ أن وقت التجميع زاد بشكل ملحوظ. نرى هنا خللًا كبيرًا في برنامجنا النصي - فهو يجمع كل ملفاتنا الخمسين مع المصادر ، رغم أننا عدّلنا ملفًا واحدًا فقط.



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


 #!/bin/bash function modification_time { date -r "$1" '+%s' } function check_time { local name=$1 [ ! -e "$name.o" ] && return $? [ "$(modification_time "$name.c")" -gt "$(modification_time "$name.o")" ] && return $? } check_time src0 && gcc -c src0.c check_time src1 && gcc -c src1.c check_time main && gcc -c main.c gcc -o main main.o src0.o src1.o 

والآن فقط تلك المصادر التي تم تعديلها سيتم تجميعها.



ولكن ماذا يحدث عندما يتحول المشروع إلى شيء مثل هذا:



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


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


  • تحليل الطوابع الزمنية للتبعيات والأهداف
  • الحد الأدنى من العمل المطلوب لضمان ملاءمة الملفات المشتقة
  • (حسنا ، + التنفيذ الموازي للأوامر)

ماكيفيلي


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


 <  > : <  ... > <  > ... ... 

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

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


All Articles