一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,如何更高效率地编译整个工程,需要用到makefile和make命令工具。makefile中会定义一系列的规则,指定哪些文件需要先编译译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大地提高了软件开发的效率。make命令是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make命令,Visual C++的nmake命令,Linux下GNU的make命令等。可见,利用makefile进行编译,已成为了一种在工程方面的常见编译方法。
现在有3个文件file1.cpp,file2.cpp,file1.h如何编写makefile:
//file1.cpp
#include "file1.h"
#include <iostream>
void print1()
{
std::cout<<"Hello, I am in file1!\n";
}
//file1.h
#ifndef file1_H_
#define file1_H_
void print1(void);
#endif
//file2.cpp
#include "file1.h"
//void print1(void);
int main()
{
print1();
return 0;
}
makefile文件如下:
#makefile
test: file1.o file2.o
g++ file1.o file2.o -o test
file2.o: file2.cpp file1.h
g++ -c file2.cpp
file1.o: file1.cpp file1.h
g++ -c file1.cpp
clean:
rm -f *.o test
在大型工程makefile中,我们习惯把.h文件与.cpp文件分开放到不同的文件夹,甚至需要多级的makefile文件。
lib_BCCencode:=./BCCencode/
lib_Process:=./Process/
lib_process_data:=./process_data/
lib_typeDef:=./typeDef/
lib_globalVarINIT:=./VarINIT/
libraries:=$(lib_BCCencode) $(lib_Process) $(lib_process_data)\
$(lib_typeDef) $(lib_globalVarINIT)
CC:=gcc
MV:=-mv -u
.PHONY:all $(libraries)
all:$(libraries) Transmitter
$(libraries):
$(MAKE) --directory=$@
vpath %.o libraries
Objects=mainbfBCC.o test.o $(lib_BCCencode)ccoding_byte.o $(lib_Process)bccInterleaverForSig.o\
$(lib_Process)csdForHeLTF.o $(lib_Process)csdForPreamble.o $(lib_Process)generateBasicSig.o\
$(lib_Process)generateHeLTF_csd.o $(lib_Process)generateLTF_csd.o\
$(lib_Process)generatePreamble_csd.o $(lib_Process)generateSig_csd.o $(lib_Process)generateSTF_csd.o\
$(lib_Process)MapForSig.o $(lib_Process)setSigInfo.o\
$(lib_process_data)mcs_table_for_20M.o $(lib_process_data)process_data.o\
$(lib_process_data)BCC_encoder.o $(lib_process_data)Data_CSD.o $(lib_process_data)GenDataAndScramble.o\
$(lib_process_data)GenInit.o $(lib_process_data)modulate.o $(lib_process_data)PilotAdd_SubcarMap.o\
$(lib_typeDef)commonStructure.o $(lib_globalVarINIT)globalVarINIT.o
Transmitter:$(Objects)
$(CC) -g $(Objects) -lm -o $@
$(MV) $(lib_BCCencode)*.o $(lib_Process)*.o $(lib_process_data)*.o $(lib_typeDef)*.o\
$(lib_globalVarINIT)*.o *.o ./objs
mainbfBCC.o:allHeaders.h
$(CC) -c -g mainbfBCC.c -o $@
test.o:test.c
$(CC) -c $< -o $@
.PHONY:clean
clean:
#-rm *.o
#-rm $(lib_BCCencode)*.o
#-rm $(lib_Process)*.o
#-rm $(lib_process_data)*.o
#-rm $(lib_typeDef)*.o
#-rm $(lib_globalVarINIT)*.o
-rm ./objs/*.o
-rm Transmitter
-rm csd_*.txt
-rm *_csd.txt
该文件中需要注意的几个点:
1.makefile中赋值语句,使用$()操作来调用赋值命令。
lib_BCCencode:=./BCCencode/
lib_Process:=./Process/
lib_process_data:=./process_data/
lib_typeDef:=./typeDef/
lib_globalVarINIT:=./VarINIT/
libraries:=$(lib_BCCencode) $(lib_Process) $(lib_process_data)\
$(lib_typeDef) $(lib_globalVarINIT)
CC:=gcc
MV:=-mv -u
2.PHONY命令和all命令
.PHONY:all $(libraries)#此处是为了防止文件重名而定义的伪目标
all:$(libraries) Transmitter#多个最终目标时,使用all来规范最终目标
3.vpath命令
vpath %.o libraries
#表示当前路径找不到.o文件时,在libraries路径下查找.o文件