Makefile详解 | 您所在的位置:网站首页 › makefile文件的后缀是什么 › Makefile详解 |
转自 ChinaUnix 链接地址:http://www.chinaunix.net/jh/23/408225.html 陈皓 CSDN 博客:http://blog.csdn.net/haoel/article/details/2886 Makefile经典教程(掌握这些足够):https://blog.csdn.net/ruglcc/article/details/7814546 GNU Make 使用手册(中译版):https://wenku.baidu.com/view/8d40f8c69ec3d5bbfd0a7440 自己找的一些 makefile 的资料:http://download.csdn.net/download/freeking101/10003539 1.用编辑器编写源代码,如.c文件。 2.用编译器编译代码生成目标文件,如.o。 3.用链接器连接目标代码生成可执行文件,如.exe。 但如果源文件太多,一个一个编译那得多麻烦啊?于是人们想到,为啥不设计一种类似批处理的程序,来批处理编译源文件呢? 于是就有了make工具,它是一个自动化编译工具,你可以使用一条命令实现完全编译。但是你需要编写一个规则文件,make依据它来批处理编译,这个文件就是makefile,所以编写makefile文件也是一个程序员所必备的技能。 对于一个大工程,编写makefile实在是件复杂的事,于是人们又想,为什么不设计一个工具,读入所有源文件之后,自动生成makefile呢,于是就出现了cmake工具,它能够输出各种各样的makefile或者project文件,从而帮助程序员减轻负担。但是随之而来也就是编写cmakelist文件,它是cmake所依据的规则。(cmake中有很多设置库的,此时还不是可执行文件,而make生成后才是二进制可执行文件。) gcc gcc 是 GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。 我们的程序只有一个源文件时,直接就可以用gcc命令编译它。 可是,如果我们的程序包含很多个源文件时,该咋整?用gcc命令逐个去编译时,就发现很容易混乱而且工作量大,所以出现了下面make工具。 make make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用 makefile 文件中用户指定的命令来进行编译和链接的。 makefile 简单的说就像一首歌的乐谱,make工具就像指挥家,指挥家根据乐谱指挥整个乐团怎么样演奏,make工具就根据 makefile 中的命令进行编译和链接的。makefile 命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。 makefile在一些简单的工程完全可以人工拿下,但是当工程非常大的时候,手写 makefile 也是非常麻烦的,如果换了个平台 makefile 又要重新修改,这时候就出现了下面的 Cmake 这个工具。 cmake cmake 就可以更加简单的生成 makefile 文件给上面那个 make 用。当然 cmake 还有其他更牛X功能,就是可以跨平台生成对应平台能用的 makefile,我们就不用再自己去修改了。 可是 cmake 根据什么生成 makefile 呢?它又要根据一个叫 CMakeLists.txt 文件(学名:组态档)去生成 makefile。 CMakeList.txt 到最后 CMakeLists.txt 文件谁写啊?亲,是你自己手写的。 nmake nmake 是 Microsoft Visual Studio 中的附带命令,需要安装 VS,实际上可以说相当于linux的make makefile 概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。必竟,这个make是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。这里所默认的编译器是UNIX下的GCC和CC。 程序的编译和链接一般来说,无论是 C、C++、还是其它编译型语言,首先要把源文件编译成 中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做 编译(compile)。然后再把大量的 Object File 合成执行文件,这个动作叫作 链接(link)。 编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。 链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。 总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File. make -hmake 命令格式:make [-f Makefile] [option] [target] make 是一个解释 makefile 中指令的命令工具。make 工具最主要也是最基本的功能:就是通过 makefile文件 来描述源程序之间的相互关系并自动维护编译工作。而 makefile文件 需要按照某种语法进行编写,文件中需要说明如何编译各个源文件,并连接生成可执行文件,并要求定义源文件之间的依赖关系。 更详细帮助可以查看 man make make -h Usage: make [options] [target] ... Options: -b, -m 为兼容性而忽略 -B, --always-make 无条件 make 所有目标 -C DIRECTORY, --directory=DIRECTORY 更改为DIRECTORY后,再做其他任何事 -d 打印 debug 信息 --debug[=FLAGS] 打印 debug 信息的变量类型 -e, --environment-overrides 重写 makefile 的环境变量 -E STRING, --eval=STRING 将 STRING 作为makefile语句求值。 -f FILE, --file=FILE, --makefile=FILE 指定 makefile 文件 -h, --help 帮助 -i, --ignore-errors 忽略错误 -I DIRECTORY, --include-dir=DIRECTORY 搜索目录中包含的makefile文件 -j [N], --jobs[=N] 一次允许N个工作; 没有参数时是无限的工作 -k, --keep-going 当一些 target 不能 made 时继续执行 -l [N], --load-average[=N], --max-load[=N] 设置最大负载(就是 jobs 最大数) -L, --check-symlink-times 在符号链接和目标之间使用最新的mtime。 -n, --just-print, --dry-run, --recon 不真实运行,仅仅打印 -o FILE, --old-file=FILE, --assume-old=FILE FILE 很老时不要 make 它。 -O[TYPE], --output-sync[=TYPE] Synchronize output of parallel jobs by TYPE. -p, --print-data-base 打印make的内部数据库。 -q, --question 不运行; 退出状态显示是最新的。 -r, --no-builtin-rules 禁用内置的隐式规则。 -R, --no-builtin-variables 禁用内置变量设置。 -s, --silent, --quiet Don't echo recipes. --no-silent Echo recipes (disable --silent mode). -S, --no-keep-going, --stop 关闭 -k 选项 -t, --touch Touch targets instead of remaking them. --trace 打印跟踪信息。 -v, --version 打印版本信息 -w, --print-directory 打印当前目录 --no-print-directory 关闭 -w 选项, 即使它是隐式开启的。 -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE 假设FILE是无限新的。 --warn-undefined-variables 当引用未定义的变量时发出警告。 cmake -hcmake官网:https://cmake.org/ CMake 这个名字是 "cross platform make" 的缩写。虽然名字中含有 "make",但是 CMake 和 Unix 上常见的 make 系统是分开的,而且更为高阶。 作用:指定一个源目录,以便在当前工作目录中为其(重新)生成构建系统。指定一个现有的构建目录来重新生成它的构建系统。 使用 cmake [options] cmake [options] cmake [options] -S -B Options -S = Explicitly specify a source directory. -B = Explicitly specify a build directory. -C = Pre-load a script to populate the cache. -D [:]= = Create or update a cmake cache entry. -U = Remove matching entries from CMake cache. -G = Specify a build system generator. -T = Specify toolset name if supported by generator. -A = Specify platform name if supported by generator. --toolchain = Specify toolchain file [CMAKE_TOOLCHAIN_FILE]. --install-prefix = Specify install directory [CMAKE_INSTALL_PREFIX]. -Wdev = Enable developer warnings. -Wno-dev = Suppress developer warnings. -Werror=dev = Make developer warnings errors. -Wno-error=dev = Make developer warnings not errors. -Wdeprecated = Enable deprecation warnings. -Wno-deprecated = Suppress deprecation warnings. -Werror=deprecated = Make deprecated macro and function warnings errors. -Wno-error=deprecated = Make deprecated macro and function warnings not errors. --preset ,--preset= = Specify a configure preset. --list-presets = List available presets. -E = CMake command mode. -L[A][H] = List non-advanced cached variables. --build = Build a CMake-generated project binary tree. --install = Install a CMake-generated project binary tree. --open = Open generated project in the associated application. -N = View mode only. -P = Process script mode. --find-package = Legacy pkg-config like mode. Do not use. --graphviz=[file] = Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for more. --system-information [file] = Dump information about this system. --log-level= = Set the verbosity of messages from CMake files. --loglevel is also accepted for backward compatibility reasons. --log-context = Prepend log messages with context, if given --debug-trycompile = Do not delete the try_compile build tree. Only useful on one try_compile at a time. --debug-output = Put cmake in a debug mode. --debug-find = Put cmake find in a debug mode. --trace = Put cmake in trace mode. --trace-expand = Put cmake in trace mode with variable expansion. --trace-format= = Set the output format of the trace. --trace-source= = Trace only this CMake file/module. Multiple options allowed. --trace-redirect= = Redirect trace output to a file instead of stderr. --warn-uninitialized = Warn about uninitialized values. --no-warn-unused-cli = Don't warn about command line options. --check-system-vars = Find problems with variable usage in system files. --profiling-format= = Output data for profiling CMake scripts. Supported formats: google-trace --profiling-output= = Select an output path for the profiling data enabled through --profiling-format. --help,-help,-usage,-h,-H,/? = Print usage information and exit. --version,-version,/V [] = Print version number and exit. --help-full [] = Print all help manuals and exit. --help-manual [] = Print one help manual and exit. --help-manual-list [] = List help manuals available and exit. --help-command [] = Print help for one command and exit. --help-command-list [] = List commands with help available and exit. --help-commands [] = Print cmake-commands manual and exit. --help-module [] = Print help for one module and exit. --help-module-list [] = List modules with help available and exit. --help-modules [] = Print cmake-modules manual and exit. --help-policy [] = Print help for one policy and exit. --help-policy-list [] = List policies with help available and exit. --help-policies [] = Print cmake-policies manual and exit. --help-property [] = Print help for one property and exit. --help-property-list [] = List properties with help available and exit. --help-properties [] = Print cmake-properties manual and exit. --help-variable var [] = Print help for one variable and exit. --help-variable-list [] = List variables with help available and exit. --help-variables [] = Print cmake-variables manual and exit. Generators The following generators are available on this platform (* marks default): Green Hills MULTI = Generates Green Hills MULTI files (experimental, work-in-progress). * Unix Makefiles = Generates standard UNIX makefiles. Ninja = Generates build.ninja files. Ninja Multi-Config = Generates build-.ninja files. Watcom WMake = Generates Watcom WMake makefiles. CodeBlocks - Ninja = Generates CodeBlocks project files. CodeBlocks - Unix Makefiles = Generates CodeBlocks project files. CodeLite - Ninja = Generates CodeLite project files. CodeLite - Unix Makefiles = Generates CodeLite project files. Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files. Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files. Kate - Ninja = Generates Kate project files. Kate - Unix Makefiles = Generates Kate project files. Sublime Text 2 - Ninja = Generates Sublime Text 2 project files. Sublime Text 2 - Unix Makefiles = Generates Sublime Text 2 project files. gmake -hgmake 是 GNU Make 的缩写。Linux 系统环境下的 make 就是 GNU Make,之所以有gmake,是因为在别的平台上,make 一般被占用,GNU make 只好叫 gmake 了。比如在安装二进制文件进行编译时要使用 make 命令,但如果在 Solaris 或其他非 GNU 系统中运行,必须使用 GNU make,而不是使用系统自带的 make 版本,这时要用 gmake 代替 make 进行编译。 Solaris 包含两种 make工具: GCC (GNU Compiler Collection)工具套装包括一个 C 编译器和一个 C++ 编译器。Solaris自身的 make 程序。freebsd 自带的 make 是 BSD make。两者的不同在于 Makefile 部分不兼容。即使是部分,有时候也不能完全把软件给 make 出来。 gmake -h Usage: gmake [options] [target] ... Options: -b, -m Ignored for compatibility. -B, --always-make Unconditionally make all targets. -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before doing anything. -d Print lots of debugging information. --debug[=FLAGS] Print various types of debugging information. -e, --environment-overrides Environment variables override makefiles. -E STRING, --eval=STRING Evaluate STRING as a makefile statement. -f FILE, --file=FILE, --makefile=FILE Read FILE as a makefile. -h, --help Print this message and exit. -i, --ignore-errors Ignore errors from recipes. -I DIRECTORY, --include-dir=DIRECTORY Search DIRECTORY for included makefiles. -j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg. -k, --keep-going Keep going when some targets can't be made. -l [N], --load-average[=N], --max-load[=N] Don't start multiple jobs unless load is below N. -L, --check-symlink-times Use the latest mtime between symlinks and target. -n, --just-print, --dry-run, --recon Don't actually run any recipe; just print them. -o FILE, --old-file=FILE, --assume-old=FILE Consider FILE to be very old and don't remake it. -O[TYPE], --output-sync[=TYPE] Synchronize output of parallel jobs by TYPE. -p, --print-data-base Print make's internal database. -q, --question Run no recipe; exit status says if up to date. -r, --no-builtin-rules Disable the built-in implicit rules. -R, --no-builtin-variables Disable the built-in variable settings. -s, --silent, --quiet Don't echo recipes. --no-silent Echo recipes (disable --silent mode). -S, --no-keep-going, --stop Turns off -k. -t, --touch Touch targets instead of remaking them. --trace Print tracing information. -v, --version Print the version number of make and exit. -w, --print-directory Print the current directory. --no-print-directory Turn off -w, even if it was turned on implicitly. -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE Consider FILE to be infinitely new. --warn-undefined-variables Warn when an undefined variable is referenced. dmakeDmake是同GNU Make类似的一个工具。其命令格式自成一体,但是可以适用于Linux, Solaris, and Win32 and other platforms。Dmake有一个变种,被OpenOffice.org使用。dmake 是一个命令行工具,与 make(1) 兼容。dmake 能够以网格、分布、并行或串行模式生成目标。如果使用的是标准 make(1) 实用程序,在对 makefile 进行任何更改时可以毫不费力地过渡到使用 dmake。dmake 是 make 实用程序的超集。 跨平台 编译工具 ( cmake、scons、ninja )其中最有名的两个是 cmake 和 scons cmake 和 python 大概代表了新一代跨平台编译工具的两种方向。 第一种 (cmake) 是延续并改良传统 automake, autoconf 工具链,将之合为一体,但最终仍然生成 Makefile,Visual Studio 的 .sln,Xcode 的 .xcodebuild 文件都是依赖现有的编译工具 (make, nmake, vcbuild, xcodebuild) 来编译;第二种是完全消除现有编译工具的调用,直接调用编译器,scons 就属于这一类 (scons 还有一个特点是完全不用专门的语言,控制编译的脚本就是 Python)cmake 只是使用 cmakelist 替代了 makefile,最终还是会调用 make。 scons 基于 python 完全替换 make,以及通过 SConstruct 和 SConscript 也完全替代 makefile。 ninja 还是使用 cmake,只不过最终调用的就不是 make 而是 ninja。也就是说 ninja 联合 cmake 完全替换了 make 和 makefile。 要说选择谁,可以选择 scons,毕竟 人生苦短,我用python 交叉 编译"交叉编译 (cross compiler) " 用作跨平台来编译程序!做交叉编译器要弄清楚3个概念: build -- 你在什么平台上编译的这个编译器host -- 这个编译器将来要在什么平台上运行target -- 编译器最终会生成在哪个平台上执行的可执行代码makefile 示例 介绍 1. Makefile 的规则 make命令执行时,需要一个 Makefile 文件,以告诉 make 命令需要怎么样的去编译和链接程序。 规则的格式: targets:prerequisites command command ...... 目标:依赖 命令 命令 ...... +++++命令需要以[TAB]键开始++++ 在讲述这个Makefile之前,还是让我们先来粗略地看一看 Makefile 的规则。 (三要素: 目标、条件、命令) target ... : prerequisites ... command ... ...makefile的构成 (1)target 也就是一个目标文件,需要由make工具创建的目标体(target)。可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。 (2)prerequisites 就是要生成那个target所需要的文件或是目标。即要创建的目标体所依赖的文件(dependency_file)。 (3)command 也就是make需要执行的命令(任意的Shell命令)。即创建每个目标体时需要运行的命令(command)。 makefile 文件其实就是一个文件的依赖关系。也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。 说到底,Makefile的东西就是这样一点,好像我的这篇文档也该结束了。呵呵。还不尽然,这是Makefile的主线和核心,但要写好一个Makefile还不够,我会以后面一点一点地结合我的工作经验给你慢慢到来。内容还多着呢。:) 在书写Makefile的时候,将单独在一个目录中编译软件,以避免生成的中间文件散在源文件中,乱花了眼。vpath(VPATH)可以指定搜索目录。auto tools在编译树中生成Makefile时就使用了vpath命令,来达到前面我们所说的目的。 例子,目录结构 src file1.cpp file2.cpp Makefile build Makefile 上面的结构中,src目录结构中的Makefile可以正常编写,如 all : file1.o file2.o。而build目录下的Makefile则使用如下规则 VPATH = ../src include ../src/Makefile 在build目录下,进行make的时候,生成的中间文件就放在build目录下了。是不是很简单呢。 vpath与VPATH的区别在于VPATH指定全局的搜索路径,而vpath可以针对特定的文件搜索路径。 vpath命令有三种形式: vpath pattern path : 为符合模式的文件指定搜索目录 vpath pattern : 清除符合模式的文件的搜索目录。 vpath : 清除所有已被设置好了的文件搜索目录。 需要包含“%”字符。“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”结尾的文件。指定了要搜索的文件集,而则指定了的文件集的搜索的目录。 例如:vpath %.h ../headers #该语句表示,要求make 在“../headers”目录下搜索所有以“.h”结尾的文件。 因为Makefile、hello.h hello.cpp main.cpp没有在同一个路径,所以要考虑路径的问题。同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径。另一个就是源文件所要包含的头文件等相关文件的路径。对于第一种来说,Makefile 提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。一般我们都是用此变量来说明规则中的依赖文件的搜索路径。 首先说明一下makefile的执行步骤: 1、读入所有的Makefile。 2、读入被include的其它Makefile。 3、初始化文件中的变量。 4、推导隐晦规则,并分析所有规则。 5、为所有的目标文件创建依赖关系链。 6、根据依赖关系,决定哪些目标要重新生成。 7、执行生成命令 Makefile中所有文件的搜索路径,包括依赖文件和目标文件。 变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。 例如: VPATH = src:../headers 它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”目录下,此时此规则等价于“foo:src:/foo.c” 对于第二种来说:当需要为不类型的文件指定不同的搜索目录时需要这种方式 vpath:关键字 它所实现的功能和上一小节提到的“VPATH”变量很类似,但是它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。 它的使用方法有三种 1、vpath PATTERN DIRECTORIES 为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者冒号(:)分开。类似上一小节的“VPATH” 2、vpath PATTERN 清除之前为符合模式“PATTERN”的文件设置的搜索路径 3、vpath 清除所有已被设置的文件搜索路径。 对于vpath的详细说明待续。 在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么 VPATH = include:src //指定了makefile的搜索路径 或者 vpath %.h include //指定.h类型文件的搜索路径是include vpath %.cpp src //指定.cpp类型文件的搜索路径是src 这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说在执行g++或者gcc时不会自动从VPATH 或者vpath中自动搜索要包含的头文件等信息文件。此时要用到了 -I 或者--incude +路径 例如依赖是: main.o:main.cpp hello.h 即 g++ -c $; littleoutput 其中,-$(subst output,,$@)中的“$”表示执行一个Makefile的函数,函数名为subst,后面的为参数。关于函数,将在后面讲述。这里的这个函数是截取字符串的意思,“$@”表示目标的集合,就像一个数组,“$@”依次取出目标,并执于命令。 七、静态模式静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活。我们还是先来看一下语法: ;: ;: ; ; ... targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。target-parrtern是指明了targets的模式,也就是的目标集模式。prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。这样描述这三个东西,可能还是没有说清楚,还是举个例子来说明一下吧。如果我们的;定义成“%.o”,意思是我们的;集合中都是以“.o”结尾的,而如果我们的;定义成“%.c”,意思是对;所形成的目标集进行二次定义,其计算方法是,取;模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。 所以,我们的“目标模式”或是“依赖模式”中都应该有“%”这个字符,如果你的文件名中有“%”那么你可以使用反斜杠“\”进行转义,来标明真实的“%”字符。 看一个例子: objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$; $@; \ rm -f $@.$$$$ 这个规则的意思是,所有的[.d]文件依赖于[.c]文件,“rm -f $@”的意思是删除所有的目标,也就是[.d]文件,第二行的意思是,为每个依赖文件“$ |
CopyRight 2018-2019 实验室设备网 版权所有 |