Makefile学习笔记05|自动推导与伪目标
希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢。
这里是目录
自动推导
自动推导涉及到.o文件。开始之前需要先删除掉之前产生的.o文件和可执行文件first_make。
rm *.o first_make
再修改一下makefile文件。
# ~/make/src/first_make/Makefile
# $^ 依赖 不重复
# $@ 目标
# @ 不显示命令执行
# - 发生错误后继续向后执行
TARGET=first_make
LIBS=-lpthread
# 修改一下上一节的makefile文件,把.cpp改成.o
$(TARGET):first_make.o xdata.o
@#内部注释,加@防止被打印出来
@echo "begin build $(TARGET)"
@$(CXX) $^ -o $@ $(LIBS)
@echo "$(Target) build success!"
执行结果如下:
g++ -c -o first_make.o first_make.cpp
g++ -c -o xdata.o xdata.cpp
begin build first_make
first_make build success!
这里make就进行了自动推导,虽然我们没有明确地告诉make两个.o文件该如何生成,自动还是自动为我们生成了两个.o文件。然而,make的能力也是有限的。为了进一步学习,我们创建一个目录:~/make/src/test_gcc,在此路径下新建文件:test.h。之后让first_make.cpp引用头文件test.h中的内容。
// ~/make/src/test_gcc/test.h
// 对于Makefile文件来讲,相对路径为../test_gcc
// 该头文件没有什么实际的内容,只做一个宏定义
#define CONF_PATH "/usr/local/"
//first_make.cpp
#include <iostream>
#include <thread>
#include "xdata.h"
#include "test.h"
using namespace std;
void ThreadMain()
{
cout<<"Thread Main"<<endl;
}
int main(int argc, char *argv[])
{
thread th(ThreadMain);
cout <<"test make "<<endl;
th.join();
XData d;
return 0;
}
这时我们再编译就会出现问题:fatal error: test.h: No such file or directory。我们可以手动指明头文件的路径,操作如下:
g++ -c -o first_make.o first_make.cpp -I../test_gcc
手动添加头文件路径当然不能满足我们的需求,还是要修改makefile文件。改过之后就可以正确地完成编译了。
# ~/make/src/first_make/Makefile
# $^ 依赖 不重复
# $@ 目标
TARGET=first_make
LIBS=-lpthread
OBJS=first_make.o xdata.o
CXXFLAGS=-I../test_gcc
# 修改一下上一节的Makefile文件,把.cpp改成.o
$(TARGET):$(OBJS)
@#内部注释,加@防止被打印出来
@echo "begin build $(TARGET)"
@$(CXX) $^ -o $@ $(LIBS)
@echo "$(Target) build success!"
特殊符号
- “-”:即使此条命令出错,make也会执行后续的命令。
- “@”:不显示命令本身,只显示结果。
伪目标
新的需求来了,有时我们希望缩小工程的体积或者更新源代码,这就需要删除掉工程中的.o、.i等中间文件。这样就引出了这一章的主题:伪目标。伪目标不同于一般目标的最大特点是伪目标一般没有目标文件生成。
如果当前目录下有名为clean的文件,则make clean不会执行clean对应的目标,而是试图编译出clean这个文件。声明目标为伪目标之后,Makefile将不会判断该目标是否存在或者该目标是否需要更新。makefile代码如下:
# ~/make/src/first_make/Makefile
# $^ 依赖 不重复
# $@ 目标
# @ 不显示命令执行
# - 发生错误后继续向后执行
TARGET=first_make
LIBS=-lpthread
OBJS=first_make.o xdata.o
CXXFLAGS=-I../test_gcc
# 修改一下上一节的Makefile文件,把.cpp改成.o
$(TARGET):$(OBJS)
@#内部注释,加@防止被打印出来
@echo "begin build $(TARGET)"
@$(CXX) $^ -o $@ $(LIBS)
@echo "$(Target) build success!"
# 定义伪目标clean
clean:
$(RM) $(OBJS) $(TARGET)
# 定义完还要声明
.PHONY: clean *clean
要运行伪目标时只需要输入命令:make clean即可。如果make后不加任何目标名,则执行第一个目标,即$(TARGET)。
都看到这里了,可以给个点赞或者评论吗?达瓦里希( ̄^ ̄)ゞ