-
前文 :我会在后面写道 version 1 ----version 4 ,我推荐用version 4写 makefile
- 但是这并不意味着你直接看 version 4 就可以了,version 4中的 知识点我在version 1 --version3 中 串联进行了解释,直接看 version 4 可能对刚刚接触makefile的同学不太友好,建议从version 1 看到 version 4
-
复习Linux系统代码
-
熟悉g++ 的一些常用命令
-
在使用 g++ 编译 C++ 程序时,可以在编译命令后面添加一些选项来指定编译器的行为。其中,-c 选项表示将源码编译成目标文件(.o 文件),不进行链接;-o 选项则用于指定生成的可执行文件名或者目标文件名。
例如,使用 g++ 编译一个 hello.cpp 的程序文件,可以使用以下命令:
g++ -c hello.cpp
这样会生成一个名为 hello.o 的目标文件。如果需要将多个目标文件进行链接、生成可执行文件,则可以使用以下命令:
g++ -o hello hello.o
其中,-o 后面的参数 hello 表示生成的可执行文件的名称,而 hello.o 表示要链接的目标文件。
-
-
开始makefile
-
version 1
-
使用 version 1 来展示 makefile的话,编译一个多文件项目有多复杂
-
1、
-
序号 1: hello 生成的可执行文件 ,它是目标 ,它依赖于 序号 2 这几个文件 。 序号 3 的开头就要加 一个 table :我要生成 hello可执行文件这个目标,要依赖序号2的这些文件 ,然后使用 序号 3的 命令来生成 目标
-
在这个终端中 使用 make 命令 它默认是 执行 当前目录下面的 名 为 Makefile的文件
-
如果当前文件夹中你写的makefile文件 的文件名字 不是 makefile 那么 可以 用 这个代码来实现 “make -f makefile文件名字”
- 然后按回车 它就去寻找 当前目录下有没有目标文件 hello ,如果没有 它就要去生成 目标文件 hello
- 如果我上一阶的代码都执行完后 再去 使用 make 命令 ,那么弹出提示 说明这个目标文件 比它的 依赖文件都要新,除非依赖文件中改动了代码(不会管你改动了什么代码,它这里的判断只是判断文件修改时间)
-
-
-
-
现在 来看 version 2
version 2 主要就是把需要的依赖文件、命令、目标文件名写成了变量的方式
-
上图的表述其实就是把 version 1 的表述转变成了使用变量名来表示,另外每个变量名用括号括起来,然后再在前面+一个 $ 符号
-
然后再把下图内容写上
-
格式:main.o : 依赖文件
-
g++ -c main.cpp
-
现在开始在终端中输入内容 :make
-
然后他在第10行遇到TAEGET,然后它就去当前目录下去找,发现当前目录下没有目标文件 hello,既然没有目标文件,它就要去生成目标文件 。开始生成 :读取目标文件名 :获取依赖文件 ---------使用 g++命令 :
g++ -o hello hello.o
其中,-o 后面的参数 hello 表示生成的可执行文件的名称,而 hello.o 表示要链接的目标文件。
-
-
我们做完这些以后去把文件 运行 一遍 , 然后得到结果。然后我们去 main.cpp 文件中 去修改一些文件 并保存----------再去终端 输入make 回车的时候,它只是编译了一下修改过的文件,不会再去把整个文件都编译一遍,这样就很节约编译时间
现在开始 version 3
- "-Wall" 选项是编译器开启所有警告信息,以便检查出所有潜在的错误和问题。
代码 解释 $@ : 代表 TARGET ,就是30行代码的 冒号前面的那一个
$^ : 代表 OBJ 也就是 30行 冒号后面的那一个
%. o : 匹配符 就是 所有的 “ * . o” 文件 , :冒号后面就是所有的 “ *. cpp ” 文件
$(CXX) :编译器
$(CXXFALGS) :编译选项
$^
"g++ $^" 是一个 Linux 和 Unix 系统下的 Makefile 中的 g++ 编译器命令,它的含义是编译当前目录下的所有源文件,并且输出可执行文件。
其中""是一个自动变量,表示所有的依赖文件,即被编译的源文件(.cpp或.c文件)。""是一个自动变量,表示所有的依赖文件,即被编译的源文件(.cpp或.c文件)。"@" 也是一个自动变量,表示所有的目标文件,即生成的可执行文件名。
$<
在 GNU Makefile 中,$< 表示当前规则中第一个依赖文件的名称(即源文件名称),通常用于指定编译命令。
因此,g++ $< 这个命令表示使用 g++ 编译当前规则中的第一个依赖文件(即源文件)。
例如,在以下规则中:
main.o: main.cpp g++ -c $<
$< 会被替换成 main.cpp,因此这个规则的意思是编译 main.cpp 文件生成目标文件 main.o。
rm :remove 删除
-f :强制删除
*. o :所有的. o file
$(TAEGET) :所有的目标文件
只要 在 终端 中 执行 make clean ,它就会执行这句命令 ,不管你的依赖是啥,都会强制执行
这里 写了 “ .PHONY : clean ” 也就是 说 PHONY是依赖 clean 的,到时候用的时候不要前面的 # ,#是注释 。 为什么要 一个 .PHONY 呢,因为如果当前目录下刚好有一个 clean 为名字的文件 ,那么你要去删除 这些生成的文件 就删除不了 ,所有 + 了 PYONY
在 version 3这个版本 中可以直接在这里添加新的文件 进去 比如 下面 第26行的 file3.o 文件 ,包括看 28行的 文件编译选项中 也是一样的
重头戏来了 :version 4
之前三个版本我们还把 依赖的 “ . o”文件写到 OBJ 里面,这个版本就不用写了
wildcard(英文意思是通配符的意思) *.cpp :这句指令的意思是把当前目录的所有 .cpp 文件都放到 SRC 中 来
patsubst %.cpp , %.o , $(SRC) : 路径替换 ,把 SRC中的所有 .cpp 文件 替换为 . o 文件
这样的话 ,我们所有当前目录的所有新的文件 都不需要手动去输入 添加 进来了
至此,大家就可以去实际操作了写两个文件 去搞一搞,试一试