Makefile简单使用
makefile
示例程序:
- 头文件functions.h
#ifndef _FUN_ #define _FUN_ void printhello(); int factorial(int n); #endif
- 文件factorial.cpp
#include "functions.h" int factorial(int n){if(n==1){return 1;}else{return n * factorial(n - 1);} }
- 文件printHello.cpp
#include <iostream> #include "functions.h" using namespace std; void printhello(){int i;cout << "hello world" << endl; }
- 文件main.cpp
#include <iostream> #include "functions.h" using namespace std; int main(){printhello();cout << "The factorial of 5 is:" << factorial(5) << endl;return 0; }
普通编译
g++
main.cpp factorial.cpp printHello.cpp-o
mmm三个文件顺序没区别
可以把-o提前:
g++
-o hello
main.cpp factorial.cpp printHello.cpp
逐个编译
每次-c都是链接成一个-o文件,最后把所有的
.o文件
链接在一起生成main
makefile编译
版本1:
在含有Makefile文件下直接make就可以编译
版本2:
#定义变量 CXX = g++ TARGET = ok OBJ = main.cpp printHello.cpp factorial.cpp #声明的变量用$(变量名)进行访问 $(TARGET):$(OBJ)$(CXX) -o $(TARGET) $(OBJ)
但是一般多文件都是用.o文件来链接的
#定义变量 CXX = g++ TARGET = ok OBJ = main.o printHello.o factorial.o #声明的变量用$(变量名)进行访问 $(TARGET):$(OBJ)$(CXX) -o $(TARGET) $(OBJ) #*.o文件的生成 main.o : main.cpp$(CXX) main.cpp -c #-c的位置无要求 printHello.o : printHello.cpp$(CXX) -c printHello.cpp factorial.o : factorial.cpp $(CXX) -c factorial.cpp
版本3:
$@
代表目标文件$^
代表所有的依赖文件$<
代表第一个依赖文件- 自动变量结合通配符
%
CXX = g++ TARGET = hello OBJ = main.o printHello.o factorial.o #定义编译选项变量 CXXFLAGS = -c -Wall #$@是目标文件即$(TARGET) #$^是所有的编译文件即$(OBJ) $(TARGET):$(OBJ)$(CXX) -o $@ $^ #*.o文件的生成 #$<是第一个编译文件 %.o : %.cpp$(CXX) $(CXXFLAGS) $< -o $@ #-f是强制删除,删除所有.o文件和hello文件 .PHONY : clean clean:rm -f *.o $(TARGET)
版本四
wildcard:显示指定路径下指定文件类型的所有文件
$
(wildcard
指定文件类型)# $(<function> <arguments>) # 函数的调用以$开头,用{}或者()将函数名以及参数包含起来 # <function>为函数名,<arguments>为参数,两者之间以空格分隔 # 若存在多个<arguments>参数,使用,分开 $(subst t,e,maktfilt)
patsubst函数调用原型:
$(patsubst ,,
) patsubst函数返回被替换过后的字符串
# $(patsubst <pattern>,<replacement>,<text>) # patsubst函数判断<text>中字符串是否匹配<pattern>模式 # <replacement>中的这个%将是所返回的字符串#把字符串“x.c.c bar.c”符合模式%.c的单词替换成%.o,返回“x.c.o bar.o”。 $(patsubst %.c,%.o,x.c.c bar.c)
GPP = g++ TARGET = helloworld SRC = $(wildcard *.cpp) OBJ =$(patsubst %.cpp, %.o, $(SRC)) GPPFLAGS = -c $(TARGET):$(OBJ)$(GPP) -o $@ $^%.o:%.cpp$(GPP) $(GPPFLAGS) $< -o $@.PHONY:clean clean:rm -f *.o $(TARGET)
这样增加了cpp文件连makefile都不用修改
程序2
- include文件夹下的base.h
#ifndef __BASE__H #define __BASE__H#define BUFFSIZE 64#endif
- src文件夹下的main.cpp
#include <iostream> #include "base.h"int main(int argc, char *argv[]) {char username[BUFFSIZE] = {0};std::cout << "Hello world" << std::endl;std::cout << "Please Input Your Name :" <<std::endl;std::cin >> username;std::cout << "Hi! " << username << " , Welcome China !" << std::endl;return 0; }
- Makefile
#pwd等linux命令n前面必须加shell pwd=${shell pwd} src_dir=$(pwd)/src/ include_dir=$(pwd)/include/#目标可执行文件 TARGET=TcpServerDemo ########################## src section ################################# #find指令:find 路径 -name 待查找文件 obj_src=${shell find $(src_dir) -name "*.cpp"} #先.cpp再.o,逗号要相邻,隔开会发生错误 OBJS=${patsubst %.cpp,%.o,$(obj_src)} ####################### flag section ######################################## GXX=g++ CFLAGS=-I${include_dir} ############################################################################# $(TARGET): $(OBJS)$(GXX) $(CFLAGS) -o $@ $^ #别忘了-c %.o:%.cpp$(GXX) ${CFLAGS} -c -o $@ $<clean:rm $(TARGET)rm $(OBJS)
执行结果
g++ -I/home/guojiawei/Desktop/TcpDemo/include/ -c -o /home/guojiawei/Desktop/TcpDemo/src/main.o /home/guojiawei/Desktop/TcpDemo/src/main.cpp g++ -I/home/guojiawei/Desktop/TcpDemo/include/ -o TcpServerDemo /home/guojiawei/Desktop/TcpDemo/src/main.o