参考原帖地址https://www.cnblogs.com/Zyf2016/p/6337827.html
测试程序如下
main.cpp
#include "print.h"
int main()
{
printHello();
return 0;
}
print.h
#include <iostream>
#include <stdio.h>
using namespace std;
void printHello();
print.cpp
#include "print.h"
void printHello()
{
cout << "HelloWorld!" << endl;
}
首先是基本版的makefile
hello:main.o print.o
#helloworld依赖main.o print.o两个目标文件
g++ -std=c++11 main.o print.o -o hello #编译出helloworld可执行文件。-o表示你指定 的目标文件名。-std=c++11
main.o: main.cpp print.h
g++ -c main.cpp -o main.o
print.o:print.cpp print.h
g++ -c print.cpp -o print.o #create print.o
clean:
rm *.o hello #执行makefile clean 会删除.o文件与生成的hello可执行程序
一个 makefile 主要含有一系列的规则,如下:
A: B
(tab)<command>
(tab)<command>
每个命令行前都必须有tab符号。
第二个是使用变量版
OBJS = main.o print.o
CC = g++
CFLAGS = -Wall -O -g
hello:$(OBJS)
$(CC) $(OBJS) -o hello
main.o:main.cpp print.h
$(CC) $(CFLAGS) -c main.cpp -o main.o
print.o:print.cpp print.h
$(CC) $(CFLAGS) -c print.cpp -o print.o
clean:
rm -rf *o hello
使用变量需要用$(var)引用
-Wall 意思为列出所有警告
-O 为启用优化
-g 为编译debug版本
接下来是函数版本
CC = gcc
XX = g++
CFLAGS = -Wall -O -g
TARGET = ./hello
#compile all .c and .cpp to .o
%.o:%c
$(CC) $(CFLAGS) -c $< -o $@
%.o:%.cpp
$(XX) $(CFLAGS) -c $< -o $@
SOURCES = $(wildcard *.c *.cpp)
OBJS = $(patsubst %.c,%.o, $(patsubst %.cpp,%.o,$(SOURCES)))
$(TARGET):$(OBJS)
$(XX) $(OBJS) -o $(TARGET)
chmod a+x $(TARGET)
clean:
rm -rf *.o hello
其中有两个函数:
1.wildcard: XXX = $(wildcard a b) 表示将所有包含a 和b 的文件生成一个列表,存在变量XXX中
程序中为将所有含有.c 与.cpp 的文件的列表存在变量SOURCES中
2.patsubst: TTT = $(patsubst %a, %b, XXX) 表示将变量XXX中所有的a替换为b,存储在变量TTT中
程序中为将所有.c 与.cpp 替换为.o
3.foreach: XXX = $(foreach VAR, LIST, TEXT) 表示从LIST获取一个以空格分割的单词传给临时变量VAR,然后执行TEXT表达式由其处理,完成后输出,输出结果为TEXT处理完成后以空格为分割的处理结果。
例子如下,结果为返回DIRS内的每个文件夹下包含的.c文件的列表。
DIRS = sub add ./
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
其中有用的内部变量:
1.$@:扩展成当前规则的文件名
2.$<:扩展成依靠 列表中第一个依靠文件
3.$^:扩展成整个依靠的列表(除掉了里面所有重复的文件名)
chmod a+x $(TARGET) 表示将TARGET强制变为可执行文件