ساختن برنامه
اکثر برنامه ها با یک دنباله ساده و دو دستوری ساخته می شوند:
./configure make
./configure make
La پیکربندی برنامه یک اسکریپت پوسته است که با درخت منبع عرضه می شود. وظیفه آن تجزیه و تحلیل است ساخت محیط. بیشتر کد منبع طراحی شده است که باشد قابل حمل. یعنی برای ساخت بیش از یک نوع سیستم یونیکس طراحی شده است. اما برای انجام این کار، کد منبع ممکن است نیاز به تغییرات جزئی در طول ساخت داشته باشد تا تفاوتهای بین سیستمها را برآورده کند. پیکربندی همچنین بررسی می کند که آیا ابزارها و اجزای خارجی لازم نصب شده اند. بریم بدویم پیکربندی. پس از پیکربندی جایی نیست که پوسته معمولاً انتظار دارد برنامه ها قرار گیرند، ما باید به صراحت مکان آن را با قرار دادن دستور با پیشوند به پوسته بگوییم. ./ برای نشان دادن اینکه برنامه در فهرست کاری فعلی قرار دارد:
[me@linuxbox diction-1.11]$ / پیکربندی
[me@linuxbox diction-1.11]$ / پیکربندی
configure هنگام آزمایش و پیکربندی بیلد، پیام های زیادی را خروجی می دهد. وقتی تمام شد، چیزی شبیه به این خواهد شد:
بررسی حضور libintl.h... بله بررسی برای libintl.h... بله
در حال بررسی کتابخانه حاوی gettext... هیچکدام به پیکربندی نیاز ندارند: ایجاد ./config.status
config.status: ایجاد Makefile config.status: ایجاد diction.1 config.status: ایجاد diction.texi config.status: ایجاد diction.spec config.status: ایجاد style.1 config.status: ایجاد test/rundiction config.status: ایجاد config.h [me@linuxbox diction-1.11]$
بررسی حضور libintl.h... بله بررسی برای libintl.h... بله
در حال بررسی کتابخانه حاوی gettext... هیچکدام به پیکربندی نیاز ندارند: ایجاد ./config.status
config.status: ایجاد Makefile config.status: ایجاد diction.1 config.status: ایجاد diction.texi config.status: ایجاد diction.spec config.status: ایجاد style.1 config.status: ایجاد test/rundiction config.status: ایجاد config.h [me@linuxbox diction-1.11]$
آنچه در اینجا مهم است این است که هیچ پیام خطایی وجود ندارد. اگر وجود داشت، پیکربندی ناموفق بود و تا زمانی که خطاها اصلاح نشود، برنامه ساخته نمیشود.
ما را ببینید پیکربندی چندین فایل جدید در فهرست منبع ما ایجاد کرد. مهمترین آنها این است makefile. makefile یک فایل پیکربندی است که دستور می دهد ساخت نحوه ساخت برنامه را دقیقاً برنامه ریزی کنید. بدون آن، ساخت از اجرا امتناع خواهد کرد makefile یک فایل متنی معمولی است، بنابراین می توانیم آن را مشاهده کنیم:
[me@linuxbox diction-1.11]$ کمتر Makefile
[me@linuxbox diction-1.11]$ کمتر Makefile
La ساخت برنامه به عنوان ورودی a تهیه پرونده (که معمولاً نام دارد makefile) که روابط و وابستگی های بین اجزای تشکیل دهنده برنامه تمام شده را توصیف می کند.
قسمت اول makefile متغیرهایی را تعریف می کند که در بخش های بعدی makefile جایگزین می شوند. به عنوان مثال ما این خط را می بینیم:
CC= gcc
CC= gcc
که کامپایلر C را تعریف می کند gcc. بعداً در makefile، نمونهای را میبینیم که از آن استفاده میشود:
واژه:
diction.o جمله.o misc.o getopt.o getopt1.o
$(CC) -o $@ $(LDFLAGS) diction.o جمله.o misc.o \ getopt.o getopt1.o $(LIBS)
واژه:
یک جایگزینی در اینجا انجام می شود و مقدار $ (CC) جایگزین شده است gcc در زمان اجرا
اکثر فایلهای ایجاد شده از خطوطی تشکیل شدهاند که a را تعریف میکنند هدف، در این مورد فایل اجرایی است داستانیو فایل هایی که به آنها وابسته است. خطوط باقیمانده دستور(های) مورد نیاز برای ایجاد هدف از اجزای آن را توصیف می کنند. در این مثال می بینیم که فایل اجرایی داستانی (یکی از محصولات نهایی نهایی) بستگی به وجود دارد diction.o, جمله.o, متفرقه, getopt.oو getopt1.o. بعداً، در makefile، تعاریف هر یک از اینها را به عنوان اهداف می بینیم:
diction.o:
getopt.o: getopt1.o: misc.o:
diction.c config.h getopt.h misc.h جمله.h
getopt.c getopt.h getopt_int.h getopt1.c getopt.h getopt_int.h misc.c config.h misc.h
diction.o:
getopt.o: getopt1.o: misc.o:
جمله.o:
style.o:
جمله.c config.h misc.h جمله.h
style.c config.h getopt.h misc.h جمله.h
جمله.o:
style.o:
با این حال، ما هیچ دستوری را برای آنها مشخص نمیکنیم. این مورد توسط یک هدف کلی، در ابتدای فایل، مدیریت می شود که دستوری را که برای کامپایل کردن هر یک از آنها استفاده می شود، توصیف می کند. .c فایل به a .o فایل:
.co:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $
.co:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $
همه اینها بسیار پیچیده به نظر می رسد. چرا به سادگی تمام مراحل را برای کامپایل کردن قطعات و انجام آن فهرست نمی کنید؟ پاسخ این موضوع در یک لحظه مشخص خواهد شد. در ضمن بیایید فرار کنیم ساخت و برنامه های ما را بسازیم:
[me@linuxbox diction-1.11]$ ساخت
[me@linuxbox diction-1.11]$ ساخت
La ساخت برنامه با استفاده از محتویات اجرا خواهد شد makefile تا اقدامات خود را هدایت کند. پیام های زیادی تولید خواهد کرد.
وقتی تمام شد، خواهیم دید که همه اهداف اکنون در فهرست ما وجود دارند:
[me@linuxbox | diction-1.11]$ ls | |||
config.guess | de.po | en | نصب-ش | جمله.ج |
پیکربندی | داستانی | کنید fa | makefile | جمله.h |
config.h.in | دیکشنری.1 | en_GB.mo | Makefile.in | جمله.o |
config.log | دیکشنری.1.in | en_GB.po | متفرقه | سبک |
config.status | دیکشنری.ج | getopt1.c | متفرقه | سبک.1 |
config.sub | diction.o | getopt1.o | متفرقه | سبک.1.in |
پیکربندی | دیکشنری.گلدان | getopt.c | اخبار | سبک.ج |
پیکربندی | diction.spec | getopt.h | nl | سبک.o |
کپی برداری | diction.spec.in | getopt_int.h | nl.mo | آزمون |
de | diction.texi | getopt.o | nl.po | |
نسخه ی نمایشی | diction.texi.in | نصب | README |
در میان فایل ها می بینیم داستانی و سبک، برنامه هایی که برای ساختن آن ها تصمیم گرفتیم. تبریک به ترتیب است! ما به تازگی اولین برنامه های خود را از کد منبع کامپایل کردیم!
اما فقط از روی کنجکاوی، بیایید فرار کنیم ساخت از نو:
[me@linuxbox diction-1.11]$ ساخت
make: هیچ کاری برای «همه» انجام نمی شود.
[me@linuxbox diction-1.11]$ ساخت
make: هیچ کاری برای «همه» انجام نمی شود.
فقط این پیام عجیب را تولید می کند. چه خبر است؟ چرا دوباره برنامه را نسازد؟ آه، این جادوی است ساخت. به جای ساختن دوباره همه چیز، ساخت فقط چیزی را می سازد که نیاز به ساخت دارد. با وجود تمام اهداف، ساخت مشخص کرد که کاری برای انجام دادن وجود ندارد. میتوانیم این را با حذف یکی از اهداف و اجرای دوباره make نشان دهیم تا ببینیم چه کار میکند. بیایید از شر یکی از اهداف میانی خلاص شویم:
[me@linuxbox diction-1.11]$ rm getopt.o
[me@linuxbox diction-1.11]$ ساخت
[me@linuxbox diction-1.11]$ rm getopt.o
[me@linuxbox diction-1.11]$ ساخت
ما می بینیم که ساخت آن را بازسازی می کند و دوباره آن را پیوند می دهد داستانی و سبک برنامه ها، زیرا به ماژول گم شده بستگی دارند. این رفتار همچنین به یکی دیگر از ویژگی های مهم اشاره می کند ساخت: اهداف را به روز نگه می دارد. ساخت اصرار دارد که اهداف جدیدتر از وابستگی هایشان باشد. این کاملا منطقی است، زیرا یک برنامه نویس اغلب مقداری از کد منبع را به روز می کند و سپس از آن استفاده می کند ساخت برای ساخت نسخه جدیدی از محصول نهایی. ساخت تضمین می کند که هر چیزی که نیاز به ساخت بر اساس کد به روز شده دارد ساخته شده است. اگر از لمس برنامه برای "به روز رسانی" یکی از فایل های کد منبع، ما می توانیم این اتفاق را ببینیم:
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 دیکشنری
-rw-r--r-- 1 me me 33125 2007-03-30 17:45 getopt.c [me@linuxbox diction-1.11]$ getopt.c را لمس کنید
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 دیکشنری
-rw-r--r-- 1 me me 33125 2009-03-05 06:23 getopt.c [me@linuxbox diction-1.11]$ ساخت
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 دیکشنری
-rw-r--r-- 1 me me 33125 2007-03-30 17:45 getopt.c [me@linuxbox diction-1.11]$ getopt.c را لمس کنید
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 دیکشنری
-rw-r--r-- 1 me me 33125 2009-03-05 06:23 getopt.c [me@linuxbox diction-1.11]$ ساخت
پس از ساخت اجرا می شود، می بینیم که هدف را به جدیدتر از وابستگی بازیابی کرده است:
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:24 دیکشنری
-rw-r--r-- 1 me me 33125 2009-03-05 06:23 getopt.c
[me@linuxbox diction-1.11]$ ls -l دیکشن getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:24 دیکشنری
-rw-r--r-- 1 me me 33125 2009-03-05 06:23 getopt.c
توانایی ساخت ساختن هوشمندانه تنها چیزی که نیاز به ساخت دارد، یک مزیت بزرگ برای برنامه نویسان است. در حالی که ممکن است صرفه جویی در زمان با پروژه کوچک ما چندان آشکار نباشد
با پروژه های بزرگتر بسیار مهم است. به یاد داشته باشید، هسته لینوکس (برنامه ای که به طور مداوم در حال اصلاح و بهبود است) حاوی چندین است میلیون خطوط کد