Makefile详解 您所在的位置:网站首页 makefile文件的后缀是什么 Makefile详解

Makefile详解

2023-11-23 19:21| 来源: 网络整理| 查看: 265

转自 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

make、cmake、gmake、nmake、Dmake 区别

源代码到编程成可执行程序大体流程

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 -h

make 命令格式: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 -h

cmake官网: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 -h

gmake 是 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.

dmake

Dmake是同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 实验室设备网 版权所有