Make是Linux的工程管理器,管理较多的文件,类似于Windows的 VisualStudio , Make是自动管理的,根据文件的时间戳,自动发现有更新过的文件才去编译,只编译改动的代码文件,不全编译。Make要工作,需要依靠Makefile脚本。
Makefile脚本的工作原则如下:
目标(文件):依赖(文件) 因为文件才有时间概念,目标不是文件就当成最老的来看。目标不是文件,就会找依赖,生成文件,依赖也不是文件,就会出错。
第一个版本:
这是一个最基础的Makefile结构:hello就是这个目标,他依赖于:后面的文件,如果这几个文件的时间戳比hello新,那就执行下面的执行语句(前面一定要加tab键,不能是空格),使用这个命令,就可生成前面的目标hello。
写完Makefile如何编译呢,直接敲make 回车,他会自动去找当前目录下面的Makefile文件,先找hello,发现没有hello就去生成他。(但是如果依赖特别多,每次的编译时间很长,一般不用)
第二个版本:
先定义了一个变量CXX=g++;目标变量TARGET=hello;OBJ变量来代表各依赖文件。然后$(TARGET): $(OBJ)表示,TARGET变量依赖于这些OBJ文件,如果OBJ文件更新了,就会执行下面的命令$(CXX) -o $(TARGET) $(OBJ)等价于g++ -o hello main.o ...o 而这些.o文件是依靠下面的语法main.o: main.cpp得来的。
敲入make后是怎么执行的呢?从头开始读,先遇到第一个目标TARGET,他就去找hello是否存在,不存在就要生成他,生成他要依赖OBJ的一系列.o文件,这些.o文件也没有,他就继续找依赖,通过.cpp文件生成这些.o文件。 如下图就是他的执行顺序。
第三个版本:
从CXXFLAGS = -c -Wall开始与第二版不同了。这个是编译选项,在C语言中是CFLAGS,编译选项到底有什么作用呢?请看右侧代码,完整的编译命令为gcc -o2 -Wall main.c -o main
接下来的$@代表的是前面的目标TARGET,$^代表上面的依赖OBJ,这样写就更方便了。
%.o: %.cpp是一个统一规则(通配符规则),是将所有的.cpp生成.o文件。简化了前面的三条命令
注:^向上指的尖尖代表所有的 <向左指,表示依赖里的第一个。
.PHONY clean 表示.PHONY永远不会存在,那就会依赖clean,就会一直执行clean的删除命令
生成目标clean的话,就执行 rm -f *.o $(TARGET)命令(强制删除所有的.o和TARGET文件)
第四个版本:
这个版本进一步简化,只在第三版本下修改了这部分内容
所有当前目录下的cpp都放在变量SRC里,然后再把SRC里的.cpp全替换成.o文件,放在OBJ里,这样写的好处是,增加一个新的cpp文件到这个项目里,我都不需要修改Makefile。
=========================================================================
那Cmake又是什么呢?
各个开发平台(window、linux等)有一套自己的工程管理器,如果针对于多个平台开发,就要维护多个工程管理器(VS、make)的配置方法,很麻烦,为解决这个问题又开发了一个能产生对应平台的工程管理文件,不需要自己写makefile了,它可以根据你所在的平台以及对应的编译工具,自动选择生成makefile 还是VS
注:但是cmake不是工程管理器,他是为了创建工程管理器文件,是一个工程管理器产生的文件
cmake也需要一个配置文件来告诉他如何工作,这个文件就是CMakeLists.txt文件。有了这个文件后,Cmake就可以通过他来生成对应平台的工程管理文件(Linux下生成Makefile)