原文链接https://www.bogotobogo.com/cplusplus/make.php
Table of Contents
2.1 选项和参数:Options and Arguments
2.2.2 makefile定义将在编译和链接中使用的变量。与环境变量相似。
2.2.3 makefile定义一个名为mybuild的目标,该目标依赖于其他对象"main.obj" 和 "foo.obj"。我们要确保建立依赖关系。
2.2.4 在这里,它(leo注:makefile)找到了依赖行中的对象 main.obj。
2.2.5 makefile构建了main.obj和 foo.obj对象。
2.2.6 一旦建立了所有依赖项,它就会返回定义依赖关系的行。然后建立目标。
2.2.7 /NODEFAULTLIB 在解析外部引用时忽略所有(或指定的)默认库。
2.2.8 LIBCMT.LIB是用于创建多线程程序的可重入库。
2.2.9 在共享MSVCRT70.DLL中调用代码的MSVCR.LIB库也是可重入的。
1、make
make 用于从源代码构建可执行程序和库。
Make用一个目标文件名的list,以生成命令行参数:
make TARGET [TARGET ...]
在没有参数的情况下,make构建出现在其makefile中的第一个目标,这个目标传统上是一个名为all的符号虚假目标。
2、makefile/Makefile
make基于程序的时间戳和每个程序所依赖的源文件,保持一组可执行程序当前状态。
make 对我们有很多好处。我们所要做的就是让make知道我们想从中得到什么。那就是为什么我们需要一个文件来告诉make该怎么做。(leo注:原文what应为that)makefile告诉make如何编译和链接一个程序。 make搜索当前目录中的makefile。例如, GNU make 搜索文件,以便找到名为 GNUmakefile, makefile, Makefile之一的文件,然后(仅)从该文件运行指定的(或默认的)目标。
make 语法如下:
make [options] [target_files] [arguments]
2.1 选项和参数:Options and Arguments
-
Arguments
target_file引用makefile中依赖行上的目标。如果我们不指定它,make在makefile中的第一个依赖行更新目标。 -
Options
如果我们不使用-f选项,make从名为makefile或Makefile的文件中获得输入,按此顺序,在当前工作目录中。(leo注:在当前目录中搜索)。表单name=value的参数是在makefile文件中设置变量name的值value。
2.2 makefile
我们将使用前一个makefile作为例子。
------------- makefile ---------------
myHOME = C:\Testing
INCS=$(myHOME)\include
LIBS=$(myHOME)\lib
mybuild: main.obj foo.obj
cl /o myTest.exe main.obj foo.obj /link \
/LIBPATH:$(LIBS) myLib.lib /NODEFAULTLIB:libcmt.lib
main.obj: main.cpp
cl /c /EHsc main.cpp -I $(INCS)
foo.obj: foo.cpp
cl /c /EHsc foo.cpp -I $(INCS)
all:mybuild
clean:
del *.exe *.obj
--------------------------------------
若要使用此makefile创建可执行文件名为mybuild,请键入:
make
既然clean不是编辑的先决条件,如果我们给出的命令make没有参数,则这个规则根本不会运行。 因此,要使用此makefile从目录中删除可执行文件和所有对象文件,请键入:
make clean
关于makefile我们应该知道几件事:
2.2.1一个简单的makefile包含有下列语法的规则:
target ... : prerequisites (dependencies) ...
recipe (system command)
...
一个规则解释如何以及何时remake特定规则的目标的某些文件。make在“先决条件”上执行recipe,以创建或更新target。 规则也可以解释如何以及何时执行一个动作。换句话说,一个规则告诉make它making什么(target),和它如何make(系统命令)。
- target通常是由程序生成的文件的名称。 它可以是可执行或对象文件。一个target也可以是一个action执行的名字,比如clean。
- 先决条件是一个文件,用来作为输入来创建target。 target常常依赖于多个文件。
- recipe是一种使执行发挥作用的action。recipe 可以有多个命令,可以在同一行上,也可以在自己的行上。 注意,我们需要在每个recipe行的开头加一个标签字符。请注意,make不知道recipes是如何工作的。这是由我们提供recipes,使更新目标文件正确。所有的make都是执行我们在目标文件需要更新时所指定的recipe。
当目标是文件时,如果其任何先决条件改变,则需要重新编译或重新链接。此外,任何自动生成的先决条件都应该首先更新。
2.2.2 makefile定义将在编译和链接中使用的变量。与环境变量相似。
myHOME = C:\Testing
INCS=$(myHOME)\include
LIBS=$(myHOME)\lib
2.2.3 makefile定义一个名为mybuild的目标,该目标依赖于其他对象"main.obj" 和 "foo.obj"。我们要确保建立依赖关系。
mybuild: main.obj foo.obj
2.2.4 在这里,它(leo注:makefile)找到了依赖行中的对象 main.obj。
这取决于cpp源文件,main.cpp,然后我们进入下一行编译文件。这是一个只编译的 /c选项。 正如你所看到的,我们使用的是 -I $(INCS),它指定目录来搜索包含文件。
main.obj: main.cpp
cl /c /EHsc main.cpp -I $(INCS)
foo.obj: foo.cpp
cl /c /EHsc foo.cpp -I $(INCS)
2.2.5 makefile构建了main.obj和 foo.obj对象。
2.2.6 一旦建立了所有依赖项,它就会返回定义依赖关系的行。然后建立目标。
在这里(leo注:如下例) ,我们使用/link 来给出链接器选项,在这种情况下,链接是myLib.lib的LIBPATH。
cl /o myTest.exe main.obj foo.obj /link \
/LIBPATH:$(LIBS) myLib.lib /NODEFAULTLIB:libcmt.lib
2.2.7 /NODEFAULTLIB 在解析外部引用时忽略所有(或指定的)默认库。
2.2.8 LIBCMT.LIB是用于创建多线程程序的可重入库。
2.2.9 在共享MSVCRT70.DLL中调用代码的MSVCR.LIB库也是可重入的。
2.2.10 /ESCS:catch子句不会捕获异步异常。
3、CMake 3.3.1
CMake,跨平台的开源构建系统。 CMake 是一个设计用于构建测试和打包软件的工具系列。CMake 用于使用简单的平台和编译器无关的配置文件来控制软件编译过程。CMake 生成可以在你选择的编译器环境中使用的本机生成文件(makefiles)和工作区。原文: http://www.cmake.org/
使用CMake的构建过程非常简单:称为 CMakeLists.txt的配置文件被放置在源目录中,然后用于创建标准构建文件。它可以生成许多平台和IDE的makefiles,包括Unix、Windows、Mac OS X、MSVC、CygWin、MinGW和Xcode。 平台的本地构建工具用于实际的创建。
我们项目中的每个目录都应该有一个makefile文件。子目录中的makefile文件继承了父目录中设置的属性,减少了代码复制的数量。
3.1 CMake - 一个 build 系统生成器
- CMake 是一个生成器: 它生成本地构建系统文件(Makefile、IDE项目文件,…),因此它不编译(即,构建)源,而底层构建工具(make、XCode、Code::Blocks…)则编译(即,构建)源。
- CMake 使用脚本语言来描述构建
- 开发人员编辑的 CMakeLists.txt调用CMake但不应编辑生成的文件
- CMake 可以由构建系统(自动)重新调用
3.2 CMake - 工作流程
- CMake:CMake正在运行和处理CMakeLists.txt
- Build: 生成工具运行并调用编译器
- Install: 编译后的二进制文件即从构建区域安装到安装位置
- CPack: CPack为创建包运行
- Package Install: 安装前一个步骤的包
简明教程CMake-tutorial-pdf.pdf from cmake.org
一个不错的cmake实例:CMake结合PCL库学习