精华内容
下载资源
问答
  • make 调试方法

    万次阅读 多人点赞 2021-10-17 19:28:51
    前言 驱动、内核等大型工程包含众多 .c .h 文件,如果手动一个个去编译这些文件是不现实的,通常的做法是使用 make 命令进行自动化编译。make 命令执行时,需要 makefile 文件,以告诉 make 命令需要怎样去编译和...

    前言

    驱动、内核等大型工程包含众多 .c .h 文件,如果手动一个个去编译这些文件是不现实的,通常的做法是使用 make 命令进行自动化编译。make 命令执行时,需要 makefile 文件,以告诉 make 命令需要怎样去编译和链接程序。

    不过这些大型工程的 makefile 文件往往不止一个,且常常分散在各个层级。如果编译时报错,调试起来就比较麻烦了。联想到 C 语言 Debug 的方法,通常是在出现问题的语句前面添加打印,来判断变量的值是否符合预期,语句是否被执行等等。那么在 Makefile 中有没有类似的 Debug 方法呢?

    控制 make 的函数

    答案是有的,那就是控制 make 的函数(Functions That Control Make)。

    make 提供了一些函数,可以检测 makefile 的运行时信息,来控制 make 的运行。

    1. info 函数
    $(info <text ..>)
    

    功能:打印信息

    1. error 函数
    $(error <text ...>)
    

    功能:产生一个致命的错误,终止 make 运行,<text …> 是错误信息。

    1. warning 函数
    $(warning <text ...>)
    

    功能:这个函数很像 error 函数,只是它并不会让 make 退出,只是输出一段警告信息,而 make 继续执行。

    案例分析

    期望:config.mk 作为 Makefile 的配置文件,ARM = y 表明想编译出 ARM 架构程序,即用 arm-linux-gcc 进行编译。但是执行后,make 并没有按照预期使用 arm-linux-gcc 进行编译,而是使用默认的 cc 进行编译。问题出在哪呢?

    先看代码

    $ tree
    .
    ├── config.mk
    ├── hello.c
    └── Makefile
    

    config.mk

    ARM = y 
    

    Makefile

    include config.mk
    
    ifeq ($(ARM), y)
    CC = arm-linux-gcc
    endif
    
    all:
    	$(CC) hello.c
    
    

    hello.c

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
    	printf("hello world\n");
    
    	return EXIT_SUCCESS;
    }
    

    执行 make

    $ make
    cc hello.c
    

    看到执行结果,很显然 CC 没有被正确赋值为 arm-linux-gcc,难道 ifeq ($(ARM), y) 条件不成立?测试一下

    include config.mk
    
    ifeq ($(ARM), y)
    111
    CC = arm-linux-gcc
    endif
    
    all:
    	$(CC) hello.c
    

    ifeq ($(ARM), y) 下面加入错误语句 111,结果执行没有报错,说明 ifeq ($(ARM), y) 条件确实是不成立的。但是我已经包含了 config.mk 这个文件了啊,而且 config.mk 里面定义了变量 ARM,并且赋值了 y。为什么 ifeq ($(ARM), y) 条件就是不成立呢?百思不得其解!!

    这时候就可以启用我们的 make 调试方法了,先上 info 函数

    include config.mk
    
    $(info "ARM=$(ARM)")
    
    ifeq ($(ARM), y)
    111
    CC = arm-linux-gcc
    endif
    
    all:
    	$(CC) hello.c
    
    

    执行

    $ make
    "ARM=y "
    cc hello.c
    

    原来 y 后面多了一个空格,导致条件判断不通过。可以看到,使用 info 函数进行 make 打印调试,可以快速定位问题。

    其实这里 ifeq ($(ARM), y) 的写法不好,更好的写法是 ifeq ($(strip $(ARM)), y)。这样,即便在 y 前后有空格,strip 函数也会帮助我们去除,增强脚本的健壮性。

    include config.mk
    
    $(info "ARM=$(ARM)")
    
    ifeq ($(strip $(ARM)), y)
    CC = arm-linux-gcc
    endif
    
    all:
    	$(CC) hello.c
    

    运行

    $ make
    "ARM=y "
    arm-linux-gcc hello.c
    

    可以看到,即便 y 后面有空格,由于使用 strip 函数的作用,帮我们把空格去除了,ifeq ($(strip $(ARM)), y) 条件也就成立了,最终使用了 arm-linux-gcc 进行编译。

    回过头来,这一切还是要归功于 info 函数给我们调试 make 带来的便利性,才能有后面我们的解决方案和优化方案。

    除了 info 函数,我们还可以使用 warning 函数,它比 info 函数打印更多的信息:文件名称和行号。

    不过上述两个函数只能打印调试信息,并不能控制 make 的运行,我们在 make 大型工程时,可能 make 流程已经不符合我们的预设了,但是 make 还在继续执行,这时我们只能手动停止,然后向上滚动 log 查找出错位置。其实我们可以有更好的方法,那就是使用 error 函数,它可以让 make 停止在你想要停止的位置,方便迅速定位问题。比如上面示例中,我们想要使用 arm-linux-gcc 进行编译,如果 CC 没能被正确赋值为 arm-linux-gcc,我们就让 make 报错停止下来。

    include config.mk
    
    # $(info "ARM=$(ARM)")
    # $(error "ARM=$(ARM)")
    $(warning "ARM=$(ARM)")
    
    ifeq ($(ARM), y)
    CC = arm-linux-gcc
    else
    $(error "ARM=$(ARM)")
    endif
    
    all:
    	$(CC) hello.c
    
    

    运行

    $ make
    Makefile:5: "ARM=y "
    Makefile:10: *** "ARM=y "。 停止。
    
    展开全文
  • make 命令

    千次阅读 2019-05-03 23:47:50
    https://www.ibm.com/support/knowledgecenter/zh/ssw_aix_71/com.ibm.aix.cmds3/make.htm 用途 ...make [ -DVariable ] [ -d Option ] [ -e ] [ -i ] [ -j [Jobs]] [ -k ] [ -n ] [ -p ] [ -q ...

    https://www.ibm.com/support/knowledgecenter/zh/ssw_aix_71/com.ibm.aix.cmds3/make.htm

    用途

    维护、更新和重新生成程序组。

    语法

    make [ -DVariable ] [ -d Option ] [ -e ] [ -i ] [ -j [Jobs]] [ -k ] [ -n ] [ -p ] [ -q ] [ -r ] [ -S ] [ -s ] [ -t ] [ -f MakeFile ... ] [ Target ... ]

    描述

    make 命令辅助您维护程序集。输入 make 命令的是一个文件相关性规范列表。

    在 makefile 中有四种类型的行:文件相关性规范、shell 命令、变量赋值和注释。通常,各行可通过以一个 \ (反斜杠) 结束来继续到下一行。以下行的末尾换行符和开头空白处都压缩成一个空格。

    文件依赖性规范

    相关性行由一个或多个目标、一个运算符和零或更多的先决条件(源)构成。这就建立了一种关系,其中目标取决于先决条件且通常创建自先决条件。在目标和先决条件之间的精确关系由分隔它们的运算符来确定。运算符如下所示:

    项目描述
    :如果目标的修改时间小于它的任何先决条件,那么将目标视为过期。在使用此运算符时,目标的先决条件是通过相关性行积累的。除非目标有 .PRECIOUS 属性,否则如果 make 命令中断,那么该目标将被删除。
    ::如果没有指定先决条件,那么始终重新创建目标。否则,如果目标的任何先决条件都比目标修改得更晚,那么将该目标认为过期。在使用此运算符时,目标的先决条件不通过相关性行积累。如果 make 命令中断,那么不会删除目标。

    文件相关性规范有两种类型的规则:推论和目标。推论规则指定目标如何才是最新的。这些规则有一个不带 /(斜杠)的目标和至少一个 .(句点)。目标规则指定如何构建目标。这些规则能够有多个目标。

    Makefile 执行

    make 命令逐行执行 makdfile 中的命令。如同 make 执行每一条命令,它将命令写入标准输出(除非另外指定的,例如使用 -s 标志)。makefile 在每一行的命令之前必须有一个制表符。

    当一条命令通过 make 命令执行时,它使用 make 的执行环境。它包含从命令行到 make 命令的任何宏和在 MAKEFLAGS 变量中指定的任何环境变量。make 命令的环境变量覆盖现有环境中的任何同名变量。注: 当 make 命令遇到以单词 include 开头,后面跟着另一个是 makefile 的名称的单词的行(例如 include depend)时,make 命令会试图打开那个文件,并且处理它的内容,就像那些内容原来就显示在 include 行处一样。这种行为只有在由 make 命令读取的第一个 makefile 的第一个非注释行不是 .POSIX 目标时发生;否则,将出现一个语法错误。

    注释:注释以字符 # 开始,可以放在除了 shell 命令行中的任何位置,并且到行尾结束。

    环境:如果 MAKEFLAGS 环境变量存在的话,make 命令将使用它。

    目标规则

    目标规则具有以下格式:

    target[target...] : [prerequisite...] [;command]
    <Tab>command

    多个目标和先决条件用空格分隔。任何后面跟着 ;(分号)的文本和所有以制表符开始的随后各行都被认为是用来更新目标的命令。一个新行不以制表符或 # 字符开始时,开始一个新的目标。

    注: 先决条件的列表可为空。

    特殊目标

    特殊目标不能包含到其他目标中;即它们是指定的唯一目标。这些目标控制 make 命令的操作。这些目标是:

    项目描述
    .DEFAULT这用作一些目标(只用作先决条件)的规则,这些目标是无法由 make 命令用其他任何方法创建的。仅使用 shell 脚本。继承 .DEFAULT 的命令的目标的 <(左尖括号)变量设成目标自身的名称。
    .IGNORE此目标的先决条件是目标本身;这会导致忽略与它们自身关联的命令所生成的错误。如果没有指定先决条件,那么等同于指定 -i 标志。
    .POSIX导致 make 命令使用不同的缺省规则文件。文件 /usr/ccs/lib/posix.mk 提供 POSIX 标准中指定的缺省规则。
    .PRECIOUS此目标的先决条件是目标本身。.PRECIOUS 将防止移除目标。如果没有指定先决条件,那么 .PRECIOUS 属性将应用于文件中的每一个目标。通常,当 make 被中断时(例如,使用 SIGHUPSIGTERMSIGINTSIGQUIT),它将删除所有未完全形成的目标。如果 make 以带有 -n-p-q 标志来调用,那么认为目标具有 .PRECIOUS 属性。
    .SCCS_GET必须在没有先决条件的情况下指定这个特殊目标。如果这个特殊目标包括在 makefile 中,那么与这个特殊目标关联的命令可以用来获取在当前目录中没有找到的所有 SCCS 文件。将用来从 SCCS 获取源文件的缺省命令替换成与这个特殊目标关联的命令。在相关性列表中命名源文件时,make 将它们视为与任何其他目标一样。目标没有相关性但在目录中出现时,make 假定文件是最新的。然而,如果为目标 source_file 找到一个命名为 SCCS/s.source_file 的 SCCS 文件,那么 make 另外进行检查以保证目标是最新的。如果目标丢失,或 SCCS 文件更新,那么 make 自动发出为 .SCCS_GET 特殊目标指定的命令以获取最新版本。然而,如果任何人可写目标,那么 make 不会检索新版本。
    .SILENT目标的先决条件是目标本身。这会导致执行与目标关联的命令之前不会将其写入标准输出。如果没有指定先决条件,那么 .PRECIOUS 属性将应用于文件中的每一条命令。
    .SUFFIXES使用此名称将更多的后缀添加到 make 识别的文件后缀列表中。目标的先决条件被附加到已知后缀列表。如果没有指定后缀,那么任何以前指定的后缀会被删除。这些后缀由推论规则使用。要更改后缀的顺序,需要指定一个空的 .SUFFIXES 条目,然后指定一个新的 .SUFFIXES 条目列表。makefile 一定不能将命令与 .SUFFIXES 关联。

    推理规则

    make 命令有一个缺省的推论规则集,能够用 makefile 中的附加推论规则定义来补充或改写它。缺省规则存储在外部文件 /usr/ccs/lib/aix.mk 中。可以通过在命令行中将 MAKERULES 变量设置为自己的文件名来替换自己的规则文件。下一行显示如何从命令行中更改规则文件:

    make MAKERULES=/pathname/filename

    推论规则由目标后缀和命令构成。通过后缀,make 命令确定先决条件,通过后缀和它们的先决条件,make 命令确定如何使目标最新。推论规则具有以下格式:

    rule:
    <Tab>command
    ...

    其中 rule 具有以下形式之一:

    项目描述
    .s1单后缀推论规则描述如何构建附加单后缀的目标。
    .s1.s2双后缀推论规则描述如何构建附加带有先决条件的 .s2 的目标,这个先决条件附加带有 .s1

    .s1.s2 后缀定义为特殊目标 .SUFFIXES 的先决条件。推论规则显示在 makefile 中时,后缀 .s1.s2 必须是已知的后缀。推论规则按其在 .SUFFIXES 中指定的顺序使用后缀。当新行不以 <Tab> 或 # 字符开始时,开始新的推论规则。

    如果 rule 为空,例如:

    rule: ;

    执行不起作用且 make 命令识别出后缀已存在,但当目标过期时无任何操作。

    在前面规则中的 ~(波浪号) 指的是 SCCS 文件。因此,规则 .c~.o 将 SCCS C 语言先决条件文件转换成对象文件(.o)。因为 SCCS 文件的 s. 是一个前缀,所以它和 make 命令的后缀视图不兼容。~(波浪号) 是一个将任何文件引用都更改成 SCCS 文件引用的方法。

    目标或先决条件也能够成为归档库的成员,即使名称中有圆括号也可以这样处理。例如,library(name) 表示 name 是归档库 library 的一位成员。要通过特殊的文件更新库的成员,可以使用格式 .s1.a,其中带有 .s1 后缀的文件用来更新归档库的成员。.a 指的是归档库。

    使用宏

    在 makefile 中,宏定义按以下格式定义:

    variable=value

    宏能够通过 makefile 显示,如下:

    • 如果宏显示在目标行中,那么在读取目标行时给宏赋值。
    • 如果宏显示在命令行中,那么在执行命令行时给宏赋值。
    • 如果宏显示在宏定义行中,那么在新的宏显示于规则或命令中时给宏赋值。

    如果宏没有定义,那么它缺省为 NULL。新的宏定义会覆盖现有的同名宏定义。宏可以按下面列示的顺序来赋值:

    1. 缺省的推论规则
    2. 环境的内容
    3. Makefile
    4. 命令行。

      注: -e 标志会使环境变量覆盖 makefile 中定义的变量。

    SHELL 宏比较特殊。它是由 make 命令设置到 shell 命令解释器(/usr/bin/sh)的路径名上。然而,如果在 makefile 中或命令行上重新定义 SHELL 宏,那么将覆盖它的缺省设置。

    注: SHELL 宏既不影响 SHELL 环境变量,也不受其影响。

    Shell 命令

    每个目标都可以具有与其关联的一系列 shell 命令,这些命令通常用来创建目标。此脚本中的每一条命令都必须以制表符开始。虽然任何目标都能够显示在相关性行上,但除非使用 :: 操作符,否则这些相关性中只有一个能够通过创建脚本来跟随。

    如果命令行的第一个或前两个字符是 @ (at 符号)、-(连字符)和 +(加号)这几个符号之一或全部,那么将特别处理该命令,如下:

    项目描述
    @使命令在被执行前不被回显。
    -使任何命令行的任何非零退出状态都被忽略。
    +使命令行可以通过指定 -n-q-t 选项来执行。

    没有元字符的命令通过 make 命令直接执行。例如,make 命令将下例中的第一条命令委托给 shell,因为它包含 >(大于号)shell 元字符。因为下例中的第二条命令不包含任何 shell 元字符,所以 make 命令直接执行它:

    target: dependency
            cat dependency > target
            chmod a+x target

    忽略 shell 程序可以节约时间,但是会导致某些问题。例如,如果命令行不包含至少一个 shell 元字符,那么要试图在 makefile 中通过设置 SHELL 宏到 /bin/csh 来执行 C shell 脚本的做法将不会成功。

    SHELL=/bin/csh
       
    target: dependency
            my_csh_script

    该 makefile 失败,这是因为 make 命令试图运行 my_csh_script,而不是将它委托到 C shell 中。

    变量分配

    make 命令中的变量和 shell 中的变量非常相似,全部由大写字母组成。= 运算符将值分配给变量。任何以前的变量都会被覆盖。删除已赋值前的所有空格。

    值可以按照如下所示附加到宏值:

    macro += word ... 
    macro += macro1

    使用 += 运算符代替 = 时,+= 运算符附加新值,并在以前的变量内容和附加的值之间插入一个空格。

    变量通过用 { } (花括号) 或 ( )(圆括号)括起变量名并在前面加一个 $(美元符号)来进行扩展。如果变量名只包含一个字母,那么不需要用花括号或圆括号将它括起来。不建议使用这种简短格式。

    变量替换出现在两种不同的时刻,取决于它被使用的场合。相关性行中的变量在此行被读取时被扩展。shell 命令中的变量在 shell 被执行时被扩展。

    变量的四种类型(按优先顺序从小到大排列):

    项目描述
    环境变量被定义为 make 命令的环境的一部分。
    全局变量在 makefile 中或在被包含的 makefile 中定义。
    命令行变量被定义为命令行的一部分。
    局部特定为某种目标定义的变量。局部变量如下:

    $<

    代表使目标过期(推论规则)的先决条件的全名或者目标(.DEFAULT 规则)的全名。

    $*

    代表使没有后缀的目标过期(在推论规则下)的先决条件的文件名段。

    $@

    代表当前目标的目标全名或库归档目标的归档文件名。

    $%

    如果目标是归档库的成员,代表目标规则中的库成员。

    还可以通过附加 DF 来使用局部变量:

    D

    表明局部变量应用于名称的目录部分。这是后面不带有 /(斜杠)的路径名。对于当前目录,D 是一个 .(句点)。

    False

    表明局部变量应用于名称的文件名部分。

    另外,make 命令设置或了解以下变量:

    $单个 $(美元符号);即 $$ 扩展到单个美元符号。
    LANGLC_ALL 和相应的环境变量(以 LC_ 开始的)都没有指定语言环境时,确定对语言环境类别所用的语言环境。
    LC_ALL确定用于重设语言环境类别的值的语言环境,这些语言环境类别是由 LANG 或任何其他的 LC_ 环境变量的设置指定的。
    LC_CTYPE确定对于字符形式的文本数据的按字节顺序解释的语言环境。例如,参数中的单字节对多字节字符串。
    LC_MESSAGES确定写消息所用的语言。
    MAKEFLAGS环境变量 MAKEFLAGS 包含在 make 命令行中指定的任何内容。任何在 make 命令行中指定的内容都被附加到 MAKEFLAGS 变量中,然后将变量输入到 make 执行的所有程序的环境中。注意 MAKEFLAGS 变量中的 -f-p 标志的操作未定义。在这个变量中,命令行标志优先于 -f-p 标志。
    VPATH允许指定搜索先决条件的目录列表。这个目录列表就像 SHELL 中的 PATH 变量那样工作。VPATH 变量可以用冒号隔开指定多个目录。例如:
    VPATH=src:/usr/local/src

    这表明 make 命令按以下顺序搜索给出的目录:

    • 当前目录(甚至在没有 VPATH 时也会出现)
    • src(当前目录中的一个子目录)
    • /usr/local/src.

    标志

    项目描述
    -DVariable设置变量值为 1。
    -dOption显示关于 make 检查(调试方式)的文件和次数的详细信息。没有任何选项或带有 A 选项的 -d 标志显示所有可用的调试信息。以下为个别可选的调试选项:

    A

    显示所有可能的调试信息。

    a

    显示关于归档搜索和高速缓存的调试信息。

    d

    显示关于目录搜索的调试信息。

    g1

    显示在构造任何对象前的关于输入图的调试信息。

    g2

    显示构造每个对象之后或出错退出之前关于输入图的调试信息。

    m

    显示关于构造目标的调试信息,包括修改日期。

    s

    显示关于后缀搜索的调试信息。

    v

    显示关于变量赋值的调试信息。

    -e指定环境变量覆盖 makefile 中的宏赋值。
    -f Makefile指定读取一个 makefile 来代替缺省的 makefile。如果 Makefile 是 -(连字符),那么读取标准输入。可以指定多个 makefile 并按指定的顺序读取。
    -i忽略 makefile 中的 shell 命令的非零退出。等同于在 makefile 中的每一个命令行前指定 -(连字符)。
    -j[Jobs]指定 make 构建独立目标所应使用的并行作业的数量。 Jobs 参数可以取任何正整数值。如果未指定 Jobs,那么 make 命令不会限制用于构建主目标的并行作业的数量。
    -k遇到错误后继续处理,但仅限于对不依赖于在创建时生成了错误的目标的那些目标进行该操作。
    -n显示命令,但是并不运行它们。然而,会执行以 +(加号)开始的行。
    -p在执行任何命令前显示所有宏定义集合和目标描述。
    -q如果对象文件没有过期,那么返回一个零状态码;如果目标过期,那么返回一个状态码。如果指定了该选项,将不更新目标。然而,会执行以 +(加号)为前缀的命令行。
    -r不使用缺省规则。
    -S如果发生错误,那么终止 make 命令。这是缺省值,与 -k 标志相反。
    -s执行命令时不在屏幕上显示它们。
    -t创建一个目标或更新它的修改时间,使它看起来没有过期。执行以 +(加号)开始的命令行。
    Target指定 Target 形式的目标名或设置变量值。

    退出状态

    当指定 -q 标志时,此命令返回以下退出值:

    项目描述
    0成功完成。
    1目标过期。
    >1发生错误。

    否则,此命令返回以下退出值:

    项目描述
    0成功完成。
    >1发生错误。

    示例

    1. 要制作在 makefile 中找到的首个目标,请输入:
      make
    2. 要显示但不运行 make 命令要用来制作文件的命令:

      make  -n search.o

      该执行将在使用一个新的描述文件时验证其是否正确。
    3. 要建立一个 makefile,例如 pgm,取决于两个文件(a.o b.o),这两个文件取决于它们相应的先决条件文件(a.cb.c)以及一个公共文件 incl.h,请输入:
      pgm: a.o b.o
                c89 a.o b.o -o pgm
      a.o: incl.h a.c
                c89 -c a.c
                b.o: incl.h b.c
      b.o: incl.h b.c
                c89 -c b.c
    4. 要从 .c 文件优化 .o 文件,请输入:
      .c.o:
                c89 -c -o $*.c
      或:
      .c.o:
                c89 -c -o $<
    5. 要查看内置规则的内容,请输入:

      make  -p  -f /dev/null 2>/dev/null

    6. 要在并行方式中使用 make 命令用最多 10 个并行作业来构建 makefile 中指定的目标,请输入:
      make -j10

    文件

    项目描述
    makefile包含相关性列表。
    Makefile包含相关性列表。
    s.makefile包含相关性列表。这是一个 SCCS 文件。
    s.Makefile包含相关性列表。这是一个 SCCS 文件。
    /usr/ccs/lib/posix.mk包含用于 make 命令的缺省的 POSIX 规则。
    /usr/ccs/lib/aix.mk包含用于 make 命令的缺省的规则。

    父主题:

    m

    相关信息:

    sh 命令

    make 命令概述

    Commands 命令

    展开全文
  • make_ext4fs

    热门讨论 2015-01-17 11:33:31
    Android中制作ext4压缩分区镜像的工具,可以将一个目录打包成为system.img文件。
  • make_ext4fs工具

    热门讨论 2015-02-09 12:50:31
    Android提供的制作ext4文件分区镜像的工具。Linux平台。
  • make详解

    千次阅读 2019-06-16 00:49:37
    Make 1. 学习make的必要性 在Linux中,有一个用来维护程序模块关系和生成可执行程序的工具-make。他可以根据程序模块的修改情况重新编译链接生成中间代码或最终的可执行程序。执行make 命令,需要一个名为...

    Make

    1. 学习make的必要性

    在Linux中,有一个用来维护程序模块关系和生成可执行程序的工具-make。他可以根据程序模块的修改情况重新编译链接生成中间代码或最终的可执行程序。执行make 命令,需要一个名为“makefile”或“Makefile”的文本文件,这个文件定义了整个项目的编译规则。它定义了模块间的依赖关系,指定文件的编译顺序,以及编译所使用的命令。有了make命令和Makefile文件,整个项目的源程序文件可以自动编译,极大地提高了软件的开发效率。在这里插入图片描述

    2. make的一般使用

    目标文件列表 分隔符 依赖文件列表[; 命令]
         [命令] 注意:如果命令换行写,前面加Tab键。
         [命令]

     main.o : main.c defs.h
       		cc -c main.c
    
      main.o : main.c defs.h;cc -c main.c
    
    • make如何解释执行

       过时:是指一个文件生成后,用来生成该文件的源文件或头文件被修改了,导致生成该文件所需要的源文件或头文件的修改时间比生成该文件的时间完。

    编译顺序:

    1. 如果只输入make命令。那么, make会在当前目录下找名字
      “Makefile”或“makefile”的文件。也可以命名为其他的名字make -f othername
    2. 它会找文件中的第一个目标文件(target)并把这个文件作为最终的目标文件。
    3. 观察目标文件是否过时,如果过时,执行规则后面的命令。否则,不执行。
    4. 从头到尾扫描完一遍Makefile文件后,make回溯一遍。

    Makefile告诉make命令如何编译和链接这几个文件

    1. 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
    2. 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序.
    3. 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

    3.Makefile文件的构成

    Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

    1. 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
    2. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
    3. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
    4. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
    5. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。
    显示规则
    main.o : main.c defs.h
    	 	cc -c main.c
     clean:
     		rm *.o
    
    1. 在规则中使用通配符
      *通配符代替了你一系列的文件,如*.c表示所有后缀为c的文件
    2. 文件搜寻
      • 如果定义了VPATH变量,make就会在当前目录找不到的情况下,到所指定的目录中去找寻文件了。VPATH = src:../headers
      • 另一个设置文件搜索路径的方法是使用make的“vpath”关键字,它可以指定不同的文件在不同的搜索目录中。
        vpath < pattern> < directories>为符合模式< pattern>的文件指定搜索目录。
        vpath < pattern> 清除符合模式< pattern>的文件的搜索目录。
        vpath 清除所有已被设置好了的文件搜索目录。
        注意:vapth使用方法中的< pattern>需要包含%字符。%的意思是匹配零或若干字符,例如,%.h表示所有以.h结尾的文件。
    3. 伪目标
      “伪目标”并不是一个文件,只是一个标签,所以make无法生成它的依赖关系和决定它是否要执行。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。为了避免和文件重名的这种情况,我们可以使用一个特殊的标记.PHONY来显示地指明一个目标是伪目标,向make说明,不管是否有这个文件,这个目标就是伪目标
      于是整个过程可以这样写:
     .PHONY: clean
       clean:          
       	   rm *.o 
    

    在Makefile中,一个伪目标可以有自己的依赖。在一个目录下如果需要生成多个可执行程序,可以在一个makefile中完成。

     all : prog1 prog2 prog3
     .PHONY : all
     prog1 : prog1.o utils.o
         cc -o prog1 prog1.o utils.o
     prog2 : prog2.o
         cc -o prog2 prog2.o
     prog3 : prog3.o sort.o utils.o
         cc -o prog3 prog3.o sort.o utils.o
    
    1. 多目标
      一个规则中可以有多个目标,规则所定义的命令对所有的目标都有效.

      mod1.o mod2.o mod3.o : commmand.c
      

    这个规则同时实现给3个目标文件制定一个依赖文件.由于隐含规则的作用,它等价与下面的规则:

    mod1.o : mod1.c  command.c
    	gcc -c mod1.c -o mod1.o
    mod2.o : mod2.c  command.c
    	gcc -c mod2.c -o mod2.o
    mod2.o : mod2.c  command.c
    	gcc -c mod2.c -o mod2.o
    
    隐含规则

    make自动推导

    main.o : main.c defs.h
    	cc -c main.c
    
    main.o : defs.h
    
    使用变量
    1. 引用变量
      变量的引用方式是:$(变量)或者 ${变量},如果要使用字符$,要用$$来表示.

    2. 定义变量
      1.递归展开变量=

      foo = $(bar)
      bar = $(ugh)
      ugh = Huh?
      all:
      echo $(foo)
      执行“make all”将会打出变量$(foo)的值是“Huh?”
      

      2.立即展开变量:=

      x := foo
      y := $(x) bar
      x := later
      其等价于:
      y := foo bar
      x := later
      
    3. 预定义变量
      常用的自动变量:
      $@:表示一个规则中的目标文件
      $%:当规则的目标文件是一个静态库文件时,代表静态库的一个成员库.
      $<:规则中的第一个依赖文件名
      $>:规则中的第一个依赖文件名,它的值是库名.
      $?:所有比目标文件新的依赖文件列表,以空格分隔.
      $^:规则的所有依赖文件,使用空格分隔.
      $+:保留了依赖文件中重复出现的文件.主要用在程序链接时库的交叉引用场合.
      $*:他的值是目标场合去掉后缀后的名称.
      在这里插入图片描述

    使用库

    在大型软件开发中,通常把编译好的模块按照功能不同放在不同的库中.在Linux中,最后链接生成可执行文件时,如果链接的是一般.o文件,是把整个.o文件的内容插入到可执行文件中.而如果链接的是库,则只从库中找出程序需要的变量和函数,把它们装入到可执行文件中.使用库可以大大节省空间,所以系统提供的标准函数一般都是以库的形式提供.
    库中的文件一般都是库的成员,成员的表示形式为:库员(成员名) mylib.a(file.o)
    通常使用ar命令对它进行维护和管理
    ar -ruv 库名 目标文件名

    使用条件语句

    ifeq表示条件语句的开始,并指定了一个比较条件(相等),还可以使用关键字ifneq,如果两个参数不相等.
    else当条件不满足时要执行的部分
    endif表示一个条件语句的结束,任何一个条件表达式都必须要以它结束

    libs_for_gcc=-lgnu
    normal_liba= 
    foo:foo.c
    ifeq($(CC),gcc)
    	$(CC) -o foo foo.c $(libs_for_gcc)
    else
    	$(CC) -o foo foo.c $(normal_liba)
    endif
    

    ifdef用来判断一个变量是否已经定义,ifndef用来判断一个变量是否没有被定义.

    bar=
    foo=$(bar)
    ifdef foo
    frobozz=yes
    else
    frobozz=no
    endif
    
    make参数
    • -C dir 或者 --directory=DIR
      在读取Makefile文件之前,先切换到dir目录下.
    • -d
      make执行时打印出所有的调试信息.
    • -e
      不允许在Makefile中对系统环境变量进行重新赋值.
    • -f filename
      使用指定文件作为Makefile文件
    • -i
      忽略执行是产生的错误,不退出make
      在这里插入图片描述
    展开全文
  • Ubuntu 安装make

    千次阅读 2019-11-18 16:56:19
    3、安装make:apt-get install make 方法二:(手动安装) 1、查看make版本,在浏览器搜索:ftp://ftp.gnu.org/gnu/make/ 可进入下载页面 2、进入文件存放路径:cd /home/tool 3、下载安装包:wget htt...

    方法一:(自动安装)

    1、进入root权限:su root

    2、更新安装列表:apt-get update

    3、安装make:apt-get install make

     

    方法二:(手动安装)

    1、查看make版本,在浏览器搜索:ftp://ftp.gnu.org/gnu/make/ 可进入下载页面

    2、进入文件存放路径:cd /home/tool

    3、下载安装包:wget http://ftp.gnu.org/gnu/make/make-3.81.tar.gz

    4、解压压缩包:tar -zvxf make-3.81.tar.gz

    5、进入解压文件目录:cd make-3.81

    6、系统配置make:./configure --prefix=/usr/local/make-3.81

    7、执行编译:make

    8、安装make:sudo make install  

    这里加上sudo是因为这一步会将编译好的make 3.81版本的文件转移到/usr/local/make-3.81目录下,这个目录只有root有权限写入。因此需要sudo权限

    9、查看安装是否成功:make -v 会显示 GNU Make 3.81则说明安装成功

    展开全文
  • catkin_make, cmake, catkin build区别

    万次阅读 多人点赞 2019-10-30 19:29:55
    文章目录1 catkin的历史1.1 Legacy Catkin Workflow1.2 Isolated Catkin Workflow1.3 Parallel Isolated Catkin Workflow and catkin build2 cmake和catkin_make区别3 catkin_make和catkin build3.1 catkin_make 和 ...
  • ./configure && make && make install详解

    万次阅读 2018-06-04 15:59:05
     我们都知道源码包安装分为这么几个阶段,1、 ./configure:“configure”会在你的系统上测试存在的特性 Make:编译程序。5、 cd:进入到这个源码包。 现在ls一下mrtg这个目录下多了一个...
  • Linux 下的make命令与Makefile

    万次阅读 多人点赞 2019-04-23 10:57:09
    博客内容包含linux下make命令的使用与makefile的书写规则等,希望通过本文档使读者对make命令makefile文件有进一步了解,由于鄙人经验学识有限文档中会有描述不准确以及理解偏差,欢迎读者指正。fythons@sina.com ...
  • make 的作用是开始进行源代码编译,以及一些功能的提供,这些功能由他的 Makefile 设置文件提供相关的功能,比如 make install 一般表示进行安装,make uninstall 是卸载,不加参数就是默认的进行源代码编译。...
  • make xxx_defconfig

    千次阅读 2019-03-21 10:36:36
     make config, make menuconfig, make oldconfig, make xx_defconfig make config:这个要求用户手动选择所有配置项,配置完成后生成 .config 文件。 make menuconfig:显示以curses的图形配置菜单,当已有....
  • linux安装make

    万次阅读 热门讨论 2019-08-28 12:51:41
    wget http://ftp.gnu.org/gnu/make/make-4.2.tar.gz tar -zxvf make-4.2.tar.gz cd make-4.2 ./configure make make install ln -s -f /usr/local/bin/make /usr/bin/make
  • 关于make_unique的构造及使用例程,MSDN的讲解非常详细 ...1. make_unique 同 unique_ptr 、auto_ptr 等一样,都是 smart pointer,可以取代new 并且无需 delete pointer,...
  • Ubuntu之makemake命令行工具的简介、安装、使用方法之详细攻略 目录 make命令行工具的简介 make命令行工具的安装 make命令行工具的使用方法 make命令行工具的简介 Ubuntu Make is a command line ...
  • GNU Make项目管理(高清PDF中文版)

    热门讨论 2011-07-22 10:13:31
    make是unix和其他操作系统上最持久的工具之一。make提供了许多选项让你能够操作多个目录、为不同的平台编译不同版本的程序以及自定义编译方法。本书重点介绍的是GNU make,主要探索GNu make所提供的强大扩充功能。书...
  • 文章目录一、Linux安装Redis1、下载安装包2、解压文件压缩包3、安装基本环境拓展:makemake install4、redis默认安装路径 `use/local/bin`5、将redis配置文件赋值到默认路径下6、设置为后台运行7、通过指定的配置...
  • 一、Make_blobs(聚类生成器) n_samples:待生成的样本的总数 n_features:每个样本的特征数,默认为2 centers: 要生成的样本中心(类别)数,默认为3 cluster_std: 每个类别的方差,默认为1 shuff...
  • make-3.81-20.el6.x86_64.rpm

    热门讨论 2013-08-02 08:59:28
    linux centos 版本的make命令RPM安装包,下载.tar.gz格式的安装文件安装很麻烦,这个简单快捷
  • make与sudo make的区别

    千次阅读 2020-09-02 23:38:33
    在ubuntu上交叉编译的时候,make时使用的是arm-linux-gcc编译器,但提示文件没有权限,而使用sudomake则会使用默认的gcc编译器编译。因为sudomake会切换到root环境,在当前用户下export的一些环境变量不会生效,也就...
  • CentOS 之 make 安装

    千次阅读 2019-10-23 10:06:27
    CentOS 之 make 安装命令 命令 yum install make -y
  • CMake和Make之间的区别

    千次阅读 2019-01-10 17:21:42
        编程人员已经使用CMake和Make很长一段时间了。当你加入一家大公司或者开始在一个具有大量代码的工程上开展工作时,你需要注意所有的构建。你需要看到处跳转的”CMakeLists.txt”文件。你应该会在终端使用”...
  • xhprof在php5.4.8下make错误

    热门讨论 2013-04-17 13:41:50
    解决xhprof在php5.4.8下make错误 make: *** [xhprof.lo] Error 1的解决办法 这是个bug,而且已经修复了,但是php的pecl里并没有更新,在php5.4.8下会编译错误,解决办法是修改xhprof.c的代码,下载此文件即可
  • make all和make有什么不同?

    千次阅读 2019-06-13 21:47:24
    https://stackoverflow.com/questions/6856263/what-is-the-difference-between-make-and-make-all 问: 我有一个如下结构的Makefile: .PHONY: image flashcard put-files put-files: @echo "=== put-files" ...
  • make,仅编译; make install,编译并安装(比如安装到/usr/bin目录下,然后可以直接使用。因为/usr/bin只有管理员才能向里面添加文件,所以通常要加sudo) 这个要看你的Makefile的,约定俗成的而已 一般"潜...
  • Linux中make命令详解

    千次阅读 2017-05-08 18:45:43
    原文地址:... ...About make make syntax make examples Related commands Linux and Unix commands help About make make is a utility(实用的) for b
  • make是用来编译的,它从Makefile中读取指令,然后编译。 make install是用来安装的,它也从Makefile中读取指令,安装到指定的位置。 make 的作用是开始进行源代码编译,以及一些功能的提供,这些功能由他的 ...
  • Linux系统无make的情况下,安装make

    千次阅读 2019-12-20 11:00:40
    在linux系统下输入make命令,提示没有这个命令。 根据博客内容走 在make这一步会报找不到make 这是使用tar.gz压缩包源码方式安装,但我使用这种方式安装不正确,因为它要求系统本就有make的情况下进行的安装。 ...
  • make j* make j4 make j8 区别

    千次阅读 2019-03-15 22:05:58
    make-j4是什么意思 看书上说 1) make(1)只衍生一个作业//作业是什么意思?make(1) 是不是就是make的意思? 2) 在双处理器上make -j4,难道是让每个处理器跑两个作业?那和make -j2效率相比 难道不是一样的? 新手...
  • linux make命令安装详解

    千次阅读 2018-05-23 15:48:00
    对于GNU Make或许很多Windows开发的程序员并不是很了解,因为Windows中的很多集成开发环境(IDE)都帮我们做了这件事。但是作为一个专业从事 Linux嵌入式开发的程序员就必须要了解GNU Make,会不会使用GNU Make从一定...
  • Linux下使用make命令编译c源文件! 文章目录一、概述二、关于程序的编译和链接三、Makefile 介绍3.1、Makefile的规则四、一个例子参考文章 一、概述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,850,306
精华内容 740,122
关键字:

make