سلام!

جلسه ی پیش با فایل هایی با پسوند o (مثل Point.o) آشنا شدیم. حالا می خواهیم برنامه ای بنویسیم که خودش به صورت خودکار تمامی کد ها را کامپایل کند. برای این کار باید ابتدا برنامه ای به نام make را نصب کنیم. برای نصب این برنامه در Ubuntu باید دستور زیر را در Terminal وارد کنید؛

sudo apt-get install make

حالا باید برنامه ای سازگار با این برنامه بنویسیم. بعد از این که این کار را انجام دادیم، دیگر لازم نیست همه ی دستور های لازم را برای کامپایل بنویسیم بلکه تنها وارد Folder برنامه ها شده و در Terminal می نویسیم:

make

همین برای کامپایل کامل برنامه کافی خواهد بود. حال بیایید به طرز نوشتن فایل Makefile بپردازیم.

فرض کنید شما class های Point و Rectangle را پیاده سازی کرده اید و در Rectangle از Point استفاده کرده اید و در main.cpp تنها Rectangle.h را include کرده اید. برای کامپایل کامل برنامه ی نوشته شده دستور های زیر لازم است؛

g++ -c Point.cpp
g++ -c Rectangle.cpp
g++ -c main.cpp
g++ -o MAIN main.o Point.o Rectangle.o

همان طور که می دانید، فایل نهایی (MAIN) به فایل های main.o، Point.o و Rectangle.o وابسته است. فایل main.o به فایل های main.cpp، Rectangle.h و Point.h وابسته است (و همچنین فایل های cpp فایل های یاد شده).

خب، حالا در Folder پروژه ی خود یک فایل جدید درست کنید به نام Makefile (اسم makefile هم قابل قبول است). makefile ما در آخر شبیه نوشته ی زیر خواهد شد، آن را نگاه کنید تا در ادامه آن را توضیح دهیم.

MAIN: main.o Rectangle.o Point.o
	g++ -o MAIN main.o Rectangle.o Point.o
main.o: main.cpp Rectangle.o Point.o
	g++ -c main.cpp
Rectangle.o: Rectangle.h Rectangle.cpp Point.o
	g++ -c Rectangle.cpp
Point.o: Point.h Point.cpp
	g++ -c Point.cpp
clean:
	rm -rf *.o MAIN

وقتی که دستور make را در Terminal وارد کنیم، خروجی برنامه (کد هایی که اجرا می شوند به ترتیب) به این صورت خواهد بود:

g++ -c main.cpp
g++ -c Rectangle.cpp
g++ -c Point.cpp
g++ -o MAIN main.o Rectangle.o Point.o

در واقع ابتدا به Target (در فایلی که نوشته ام به MAIN، main.o، Rectangle.o و ... Target می گویند) اوّل رجوع می شود. جلوی همین Target اسم چند Target دیگر نوشته شده است. به ترتیب به همه ی این Target ها رجوع می شود. جلوی Target های رجوع شده اسم یک یا چند فایل نوشته شده است. برنامه چک می کند که آیا این فایل ها نسبت به بار آخر تغییر کرده اند یا نه. اگر تغییر کرده بودند دستوری که زیر Target نوشته شده است (همان g++ ...) را اجرا می کند.

در Terminal به جای این که بنویسید make بنویسید make clean، خود برنامه دنبال یک Target به نام clean می گردد. این Target صرفا جهت تمیزکاری نوشته شده است.

توجّه: تمامی Tab هایی که در makefile استفاده شده اند ضروری هستند.

این مبحث کمی سخت است بنابراین چند مثال دیگر می زنم و آن ها را حل می کنم.

یک class داریم به نام ‌Board. در این class از دو class دیگر به نام Color و Piece استفاده شده است. makefile آن به صورت زیر خواهد بود.

MAIN: main.o board.o color.o piece.o
	g++ main.o Board.o Color.o Piece.o -o MAIN
main.o: main.cpp board.o color.o piece.o
	g++ -c main.cpp
board.o: board.h board.cpp color.o piece.o
	g++ -c board.cpp
color.o: color.h color.cpp
	g++ -c color.cpp
piece.o: piece.h piece.cpp
	g++ -c piece.h
clean: 
	rm -rf *.o MAIN

یک class داریم به نام City. در این class از class های Adam و Car استفاده شده است. در Car از یک class دیگر به نام Color استفاده شده است. makefile مربوط به آن به صورت زیر خواهد بود.

MAIN: main.o City.o Color.o Car.o Adam.o
	g++ main.o City.o Color.o Car.o Adam.o -o MAIN
main.o: main.cpp City.o Color.o Car.o Adam.o
	g++ -c main.cpp
City.o: City.h City.cpp Car.o Adam.o Color.o
	g++ -c City.cpp
Color.o: Color.h Color.cpp
	g++ -c Color.cpp
Car.o: Car.h Car.cpp Color.o
	g++ -c Car.cpp
Adam.o: Adam.h Adam.cpp
	g++ -c Adam.cpp
clean: 
	rm -rf *.o MAIN

برای این که به این مبحث مسلّط بشوید، چند مثال برای خودتان طرح کرده و حل کنید. اگر در پاسخ هایتان شک داشتید آن ها را در قسمت نظرات مطرح کنید.