ابزار make
فرایند ایجاد برنامه اجرایی از کد منبع را راحت می کند
برنامه
make
که به نام
makefile
نیز شناخته می شود، شامل قواعدی است که نحوه ایجاد برنامه اجرایی از کد منبع را در بر دارد.
برای دیدن پارامتر های این دستور می توانید از دستور
make --help
استفاده کنید. و یا اینکه دستور
man make
را بزنید
اولین
makefile
با یک مثال
کد منبع مثال:
1
2
3
4
5
6
7 |
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
} |
برای ساخت یک
makefile
برای کد بالا
یک فایل با همین نام در پوشه ای که فایل کد بالا قرار دارد ایجاد کنید.
برای فاصله در کد این فایل از تب استفاده می کنیم. (از کلید فاصله استفاده نمی کنیم)
all: hello.exe
hello.exe: hello.o
gcc -o hello.exe hello.o
hello.o: hello.c
gcc -c hello.c
clean:
rm hello.o hello.exe
حال برنامه
make
را در همان پوشه اجرا کنید
> make
gcc -c hello.c
gcc -o hello.exe hello.o
اجرای برنامه
make
بدون هیچ پارامتری باعث می شود تا بخش
all
به صورت پیشفرض اجرا شود.
یک فایل
makefile
از مجموعه قواعدی تشکیل شده است و هر قاعده از سه بخش ساخته شده است
یک هدف یک لیست از پیش نیاز ها و یک دستور
target: pre-req-1 pre-req-2 ...
command
بخش های هدف و پیش نیاز ها با یک دو نقطه از هم جدا نشده اند و برای فاصله از تب استفاده می شود. از کلید فاصله استفاده نمی شود..
وقتی برنامه
make
می خواهد یک قاعده را ارزیابی کند
سعی می کند که فایل های تعریف شده در پیشنیاز ها را پیدا کند و اگر هرکدام از فایل ها خود یک قاعده داشتند اول آنها را بررسی می کند.
در مثال بالا پیشنیاز بخش
all
فایل
hello.exe
است.
این فایل وجود ندارد و بنابراین برنامه به دنبال قاعده ایجاد آن می رود تا آن را ایجاد کند.
در این مثال چون فایل hello.o
نیز وجود ندارد برنامه بدنبال قاعده آن می رود و
چون در قاعده آن فایل
hello.c
را می بیند و این فایل نیز در پوشه جاری برنامه وجود دارد کد مربوط به قاعده
hello.o
را اجرا می کند
یعنی
و حالا که فایل ها ایجاد شد به سراغ فایل
hello.o
رفته و کد آن را اجرا می کند و
و در انتها قاعده
all
کاری برای انجام ندارد.
توجه به این نکته ضروری است که برنامه تنها زمانی به سراغ پیش نیاز ها می رود که فایل هدف وجود نداشته باشد
مثلا اگر دوباره برنامه
make
را اجرا کنیم:
> make
make: Nothing to be done for `all'.
در اینجا برنامه سراغ
all
رفت و وقتی hello.exe
را دید
به سراغ
دستورات بخش
all
رفت و درآنجا چیزی برای انجام نبود
2.2 More on Makefile
Comment & Continuation
A comment begins with a #
and lasts till the end of the line. Long line can be broken and continued in several lines via a back-slash (\
).
Syntax of Rules
A general syntax for the rules is:
target1 [target2 ...]: [pre-req-1 pre-req-2 ...]
[command1
command2
......]
The rules are usually organized in such as way the more general rules come first. The overall rule is often name "all
", which is the default target for make
.
Phony Targets (or Artificial Targets)
A target that does not represent a file is called a phony target. For example, the "clean
" in the above example, which is just a label for a command. If the target is a file, it will be checked against its pre-requisite for out-of-date-ness. Phony target is always out-of-date and its command will be run. The standard phony targets are: all
, clean
, install
.
Variables
A variable begins with a $
and is enclosed within parentheses (...)
or braces {...}
. Single character variables do not need the parentheses. For example,$(CC)
, $(CC_FLAGS)
, $@
, $^
.
Automatic Variables
Automatic variables are set by make after a rule is matched. There include:
$@
: the target filename.$*
: the target filename without the file extension.$<
: the first prerequisite filename.$^
: the filenames of all the prerequisites, separated by spaces, discard duplicates.$+
: similar to $^
, but includes duplicates.$?
: the names of all prerequisites that are newer than the target, separated by spaces.
For example, we can rewrite the earlier makefile as:
all: hello.exe
# $@ matches the target; $< matches the first dependent
hello.exe: hello.o
gcc -o $@ $<
hello.o: hello.c
gcc -c $<
clean:
rm hello.o hello.exe
Virtual Path - VPATH & vpath
You can use VPATH
(uppercase) to specify the directory to search for dependencies and target files. For example,
VPATH = src include
You can also use vpath
(lowercase) to be more precise about the file type and its search directory. For example,
vpath %.c src
vpath %.h include
Pattern Rules
A pattern rule, which uses pattern matching character '%'
as the filename, can be applied to create a target, if there is no explicit rule. For example,
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
Implicit Pattern Rules
Make comes with a huge set of implicit pattern rules. You can list all the rule via --print-data-base
option.
2.3 A Sample Makefile
This sample makefile is extracted from Eclipse's "C/C++ Development Guide -Makefile".
LINK_TARGET = test_me.exe
OBJS = \
Test1.o \
Test2.o \
Main.o
REBUILDABLES = $(OBJS) $(LINK_TARGET)
clean :
rm -f $(REBUILDABLES)
echo Clean done
all : $(LINK_TARGET)
echo All done
$(LINK_TARGET) : $(OBJS)
g++ -g -o $@ $^
%.o : %.cpp
g++ -g -o $@ -c $<
Main.o : Main.h Test1.h Test2.h
Test1.o : Test1.h Test2.h
Test2.o : Test2.h
# %.dep : %.cpp
# g++ -M $(FLAGS) $< > $@
# include $(OBJS:.o=.dep)
2.4 Brief Summary
I have presented the basic make features here so that you can read and understand simple makefiles for building C/C++ applications. Make is actually quite complex, and can be considered as a programming language by itself!!