make工具用以简化编译过程,当编译一个包括成百上千个文件的大型项目时,逐个文件编译繁琐且低效,并且当更新某个文件之后,还需要重新再编译一次。makefile文件正是为解决此类问题而诞生的。现在绝大多数IDE,包括Window下的VS等IDE均使用makefile文件,只不过由系统自动生成,编程人员感觉不到而已。
在linux环境下,理解简单的makefile文件,能使用make工具,可以加速开发过程以及编译安装源码文件的痛苦。
通常情况下,如果在某个目录下运行:
make
则自动执行此目录下的makefile文件(或者Makefile文件),如果在此目录下有多个Makefile文件,则运行如下命令可以指定运行的makefile文件
make -f Makefile.linux
编译过程一般包括编译和链接两个过程:
编译:从源文件到.O文件生成;
链接:生成可执行文件
如一个项目包括四个源文件:main.cpp hello.cpp factorial.cpp,最终要生成可执行文件hello,则利用如下命令即可生成:
g++ main.cpp hello.cpp fractorial.cpp -o hello
撰写makefile文件的基本规则是:
target: dependencies
[tab] system command
其中,target表示生成目标,dependencies表示生成目标时依赖的选项,system command表示生成目标所需要的命令,如针对上例中的makefile文件可写为:
all:hello
hello: main.cpp hello.cpp factorial.cpp
g++ main.cpp hello.cpp factorial.cpp -o hello
如果描述依赖关系更准确些,则上例中的makefile文件可写成:
all: hello
hello: main.o hello.o factorial.o
g++ main.o hello.o factorial.o hello
main.o: main.cpp
g++ -c main.cpp
hello.o: hello.cpp
g++ -c hello.cpp
factorial.o: factorial.cpp
g++ -c factorial.cpp
当然,也可以使用变量,如:
CC=g++
CFLAGS=-c -Wall
all: hello hello: main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
factorial.o: factorial.cpp
$(CC) $(CFLAGS) factorial.cpp
hello.o: hello.cpp
$(CC) $(CFLAGS) hello.cpp
clean: rm -rf *o hello #表示删除其中的所有.o文件
下面是更复杂的写法,如果能理解,则对于一般的makefile的阅读应该没什么问题
CC=g++ CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@