跟我一起写 Makefile(9)

合集下载

makefile参数

makefile参数

makefile参数
Makefile是一个用于自动化构建和编译项目的工具。

它使用了一种特定的语法来定义构建规则和依赖关系。

Makefile支持一些参数,用于指定不同的构建选项和行为。

以下是一些常见的Makefile参数:
1. 目标(Target):指定要构建的目标文件。

Makefile使用目标来定义构建规则和依赖关系。

目标可以是单个文件或多个文件。

2. 依赖(Dependencies):指定构建目标所需的依赖文件。

当依赖文件发生变化时,Makefile会自动重新构建目标文件。

3. 命令(Commands):指定构建目标所需的命令行指令。

Makefile会按照命令的顺序执行,以构建目标文件。

4. 变量(Variables):用于定义可在Makefile中使用的变量。

变量可以用来简化构建过程,例如指定编译器选项或源文件路径。

5. 条件语句(Conditionals):用于根据特定条件来选择性地执行命令或定义变量。

这对于构建不同平台或配置下的特定版本非常有用。

6. 规则(Rules):指定构建规则的匹配模式和构建命令。

规则告诉Makefile如何从源文件构建目标文件。

7. 注释(Comments):用于在Makefile中添加注释,以提供对规则和命令的说明。

注释以“#”开头,并被视为注释行。

陈皓-跟我一起学MAKEFILE

陈皓-跟我一起学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++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。

MakeFile脚本的编写

MakeFile脚本的编写

MakeFile脚本的编写1.Eclipse Debug下默认会⽣成 .mk格式的makefile多⽂件2.下连接可以⽤⼀个⽂件来实现MakeFile功能。

转载⾸先进⾏的内容是参数设置部分,如下:设置项⽬名字,它决定了我们make之后,⽣成的⽂件名。

⽐如libXX.so或者XXX.a或者XXXX#set your project namePRJ_NAME=libXXX.so设置项⽬的类型,是共享库、可执⾏程序还是静态库#set your project type : choose one belowPRJ_TYPE =g++ -shared#PRJ_TYPE = g++#PRJ_TYPE = ar -r设置编译的类型,是Debug还是Release#set Debug or ReleaseCompile_Flag = Debug#Compile_Flag = Release设置编译后的⽂件的输出路径,这个⽂件夹⼀定要有才可以,否则会出错的。

所以要事先建⽴好#set your output pathOutput:= bin这⾥是设置代码所在的⽂件夹#set your source folderSRC:=code如果引⽤了什么库,就在这⾥添加好了.#add the lib you used here#LIBS := -lLib1 -lLib2 -lLib3LIBS := -lpthread#LIBPATH := -Lpath1 -Lpath2 -Lpath3LIBPATH :=INCLUDEPATH :=# INCLUDEPATH := -I/usr/lib/XXX/include要设置的参数就这么多。

下⾯进⼊第⼆部分,makefile核⼼内容的解释。

下⾯我仔细讲⼀下。

#符号,表⽰注释。

makefile⾥⾯有它的那⾏,就不会起作⽤了。

⽐如下⾯两⾏就是注释。

####################################DON"T MODIFY THE BELOWS#combine output folderFinalOutput := $(Output)/$(Compile_Flag)/上⾯的代码,定义了⼀个变量,名字是FinalOutput,给它赋值,可以⽤=或者:=,等⼀下说区别。

[转]makefile文件的编写规则及实例

[转]makefile文件的编写规则及实例

[转]makefile⽂件的编写规则及实例1.⼀个简单的makefile例⼦假设⼀个程序有两个⽂件file1.c,file2.c,每个⽂件都包含head.h,⽣成file可执⾏⽂件file:file1.o file2.o 附属⾏(⽂件的依存关系)gcc -o file1.o file2.o 命令⾏file1.o:file1.c head.hgcc -c file1.cfile2.o:file2.c head.hgcc -c file2.c从file最终的⽬标⽂件开始倒推,依次列出⽂件的依存关系,make在执⾏时:(1)判断file可执⾏⽂件是否存在,若不存在,则执⾏命令⾏,向下寻找依存关系(2)若file存在,则检查依靠⽂件,是否存在更新,若存在更新则执⾏命令⾏,若没有更新则给出提⽰:make:'file' is up to date.2.makefile中的宏定义及内部变量宏定义:OBJS = file1.o file2.oCC = gccCFLAGS = -wall -O -g引⽤:file:$(OBJS)$(CC) $(OBJS) -o filefile1.o:file1.c head.h$(CC) $(FLAGS) -c file1.cfile2.o:file2.c head.h$(CC) $(FLAGS) -c file2.c内部变量:$@:当前规则的⽬的⽂件名$<:依靠列表中的第⼀个依靠⽂件$^:整个依靠列表file:$(OBJS)$(CC) $^ -o $@file1.o:file1.c head.h$(CC) $(FLAGS) -c $< -o $@file2.o:file2.c head.h$(CC) $(FLAGS) -c $< -o $@"$(CC) $(FLAGS) -c $< -o $@"是隐含规则,可以不写,默认使⽤此规则3.假象假设⼀个项⽬要⽣成两个可执⾏⽂件file1和file2,这两个⽂件是相与独⽴的,则在makefile开始处:all:file1 file2make总是假设all要⽣成,去检查它的依赖⽂件4.清除由make产⽣的⽂件clean:rm *.orm file执⾏:make clean则会清除由make⽣成的*.o和file⽂件如果有clean⽂件存在,则清除不会执⾏(因clean没有可依赖的⽂件,永远是最新的)使⽤PHONY⽬标,避免同名⽂件相冲突,不会检查clean⽂件存在与否,都要执⾏清除操作.PHONY : cleanclean:rm *.orm file5.makefile函数搜索当前⽬录,⽣成由*.c结尾的⽂件列表,wildcard--函数名SOURCE = $(wildcard *.c)⽤%.o替换$(SOURCE)中的%.c⽂件OBJS = $(patsubst %.c,%.O,$(SOURCE))6.产⽣新规则SOURCE = $(wildcard *.c)depends:$(SOURCE)gcc -M $(SOURCE) > depends(为每⼀个.c⽂件产⽣规则,c⽂件和相关头⽂件为依靠)在makefile⽂件中:include depends7.⼀个有效的makefile⽂件可以完成⼤部分我们所需要的依靠检查,不⽤做太多的修改就可⽤在⼤多数项⽬⾥功能:搜索当前⽬录,寻找源码⽂件,放⼊SOURCE变量⾥,利⽤patsubst产⽣⽬标⽂件(*.o)CC = gccCFLAGS = -Wall -O -gSOURCE = $(wildcard *.c,*.cc)OBJS = $(patsubst %.c,%.o,$(patsubst,%.cc,%.o,$(SOURCE)))file:$(OBJS)$(CC) $^ -o $@⽤默认规则产⽣⽬标⽂件(*.o)1:编译可执⾏程序。

一些通用的makefile模板

一些通用的makefile模板

一些通用的makefile模板
以下是一个简单的通用Makefile模板,用于编译C/C++程序: Makefile.
# 定义编译器。

CC = gcc.
CXX = g++。

# 定义编译选项。

CFLAGS = -Wall.
CXXFLAGS = -Wall.
# 定义链接选项。

LDFLAGS =。

# 定义目标文件。

TARGET = program.
# 定义源文件。

SRCS = main.c file1.c file2.c. # 生成目标文件列表。

OBJS = $(SRCS:.c=.o)。

# 默认目标。

all: $(TARGET)。

# 生成可执行文件。

$(TARGET): $(OBJS)。

$(CC) $(LDFLAGS) -o $@ $^。

# 生成目标文件。

%.o: %.c.
$(CC) $(CFLAGS) -c -o $@ $<。

# 清理生成的文件。

clean:
rm -f $(OBJS) $(TARGET)。

这个模板包含了常见的Makefile设置,包括了编译器的定义、编译选项、链接选项、目标文件、源文件、生成目标文件和可执行文件的规则,以及清理生成文件的规则。

你可以根据自己的需求对其进行调整和扩展。

linux makefile 写法

linux makefile 写法

linux makefile 写法Linux Makefile 写法Makefile 是一种用于组织和管理软件项目的文件格式,它指导着编译器如何构建程序。

在Linux 环境下,Makefile 是一种特别常见的构建工具,它通过定义目标和规则,使得软件开发人员能够轻松地构建、编译和部署项目。

本文将一步一步回答关于Linux Makefile 写法的问题,帮助你深入了解如何编写高效的Makefile。

第一步:创建Makefile 文件首先,你需要在你的Linux 环境中创建一个名为"Makefile" 的文本文件。

你可以使用任何文本编辑器,如Vim、Nano 或者Emacs 来完成这个任务。

确保你的Makefile 文件保存在项目的根目录下,这样Make 命令才能找到它。

第二步:定义变量在Makefile 中,你可以定义各种变量来存储重复使用的值,如编译器名称、编译选项和目标文件名。

定义变量的语法是"变量名=值",例如:CC=gccCFLAGS=-Wall -WerrorTARGET=myprogram在上面的例子中,我们定义了三个变量:`CC`、`CFLAGS` 和`TARGET`。

`CC` 变量的值是`gcc`,指定了使用GCC 编译器。

`CFLAGS` 变量的值是`-Wall -Werror`,这些编译选项用于启用所有警告,并将警告视为错误。

`TARGET` 变量的值是`myprogram`,这是我们期望生成的最终可执行文件的名称。

第三步:指定编译规则在Makefile 中,你需要指定编译规则来告诉编译器如何构建你的程序。

编译规则由目标、依赖和命令组成。

下面是一个简单的例子:(TARGET): main.o utils.o(CC) (CFLAGS) -o (TARGET) main.o utils.o在上面的例子中,我们指定了一个名为`(TARGET)` 的目标,它依赖于`main.o` 和`utils.o` 两个文件。

c语言makefile编写规则

c语言makefile编写规则

c语言makefile编写规则C语言Makefile编写规则什么是MakefileMakefile是一种用于管理和构建软件项目的文件,通常被用于编译和链接C语言程序。

Makefile中包含了一系列的规则和指令,用于告诉编译器如何编译程序中的各个部分,并最终生成可执行文件。

Makefile的基本结构Makefile的基本结构由多个规则组成,每个规则由一个目标(target)和一个或多个依赖(dependencies)组成。

目标指明了要生成的文件或要执行的操作,依赖指明了目标所依赖的文件或操作。

一个简单的Makefile规则的语法如下:target: dependenciescommand其中,target是生成的文件或要执行的操作,dependencies是目标所依赖的文件或操作,command是执行的命令。

每个规则的命令必须以一个tab键开始。

Makefile的应用场景Makefile广泛应用于C语言项目的构建中,它可以自动化执行编译、链接和清理等操作。

通过Makefile,我们可以方便地管理源代码文件、头文件和库文件之间的关系,从而提高项目的可维护性和可扩展性。

Makefile的编写规则1.目标和依赖应该使用合适的命名方式,能够清晰地表达其作用以及所依赖的内容。

避免使用中文、空格和特殊字符,使用下划线和英文字母进行命名。

2.命令行命令应该以tab键开始,而不是空格。

这是Makefile的语法要求,且使用tab键可以提高代码的可读性。

3.注意规则的顺序,确保前置依赖在目标之前。

Makefile会按照规则的声明顺序进行构建,如果前置依赖在目标之后,可能导致构建失败。

4.使用变量来定义重复使用的内容,如编译器选项、源文件列表等。

这样可以提高代码的可维护性,并方便进行后续的修改和维护。

5.使用通配符来表示一类文件,如使用*.c表示所有的C语言源文件,使用$(wildcard pattern)函数来获取符合某种模式的文件列表。

跟我一起写Makefile(高清)

跟我一起写Makefile(高清)

跟我一起写Makefile1.1概述什么是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 Linux8.0,make的版本是3.80。

必竟,这个make是应用最为广泛的,也是用得最多的。

而且其还是最遵循于IEEE1003.2-1992标准的(POSIX.2)。

在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。

如何编写makefile文件

如何编写makefile文件

目的:基本掌握了make 的用法,能在Linux系统上编程。

环境:Linux系统,或者有一台Linux服务器,通过终端连接。

一句话:有Linux编译环境。

准备:准备三个文件:file1.c, file2.c, file2.hfile1.c:#include <stdio.h>#include "file2.h"int main(){printf("print file1$$$$$$$$$$$$$$$$$$$$$$$$\n");File2Print();return 0;}file2.h:#ifndef FILE2_H_#define FILE2_H_#ifdef __cplusplusextern "C" {#endifvoid File2Print();#ifdef __cplusplus}#endif#endiffile2.c:#include "file2.h"void File2Print(){printf("Print file2**********************\n");}基础:先来个例子:有这么个Makefile文件。

(文件和Makefile在同一目录)=== makefile 开始===helloworld:file1.o file2.ogcc file1.o file2.o -o helloworldfile1.o:file1.c file2.hgcc -c file1.c -o file1.ofile2.o:file2.c file2.hgcc -c file2.c -o file2.oclean:rm -rf *.o helloworld=== makefile 结束===一个makefile 主要含有一系列的规则,如下:A: B(tab)<command>(tab)<command>每个命令行前都必须有tab符号。

ck文档 - makefile写法整理

ck文档 - makefile写法整理

makefile写法整理1 Makefile基本语法Makefile:程序模块的内部关系决定了源程序编译和链接的顺序,通过建立makefile可以描述模块间的相互依赖关系。

Make命令从中读取这些信息,然后根据这些信息对程序进行管理和维护。

在makefile里主要提供的是有关目标文件(即target)与依靠文件(即dependencyies)之间的关系,还指明了用什么命令生成和更新目标文件。

有了这些信息,make会处理磁盘上的文件,如果目的文件的时间标志(该文件生成或被改动进的时间)比任意一个依靠文件旧,make就执行相应的命令,以便更新目的文件(目的文件不一定是最后的可执行文件,它可以是任何一个文件)。

1)makefile的基本单位是“规则”,即描述一个目标所依赖的文件或模块,并给出其生成和算法语言需要用到的命令。

规则的格式如下:目标[属性]分隔符号 [依赖文件][命令列]{<tab>命令列}与Linux下面的命令格式相同,[]中的内容表示为可选择项,{}中的内容表示可出现多次。

A.目标:目标文件列表,即要维护的文件列表。

B.属性:表示该文件的属性。

C.分隔符:用来分割目标文件和依赖文件的符号,如冒号“:”等。

D.依赖文件:目标文件所依赖的文件的列表。

E.命令列:重新生成目标文件的命令,可以有多条命令。

注意:在makefile中,除了第一条命令,每一个命令行的开头必须是一个<tab>符号,也就是制表符,而不能因为制表符相当于4个空格而不去键入tab符号。

因为make命令是通过每一行的tab符号来识别命令行的。

另外,对于第一条命令而言,不必用<tab>键,就可以直接跟在依赖文件的列表后面。

对于注释的了,起头应该用#符号,并用换行符号结束。

如果要引用#符号,要用到“”。

2)make命令的使用格式为:make [选项][宏定义][目标文件]make命令有多个选项参数,列举参数含义如下:A.-f:指定需要维护的目标。

MAKEFILE的编写

MAKEFILE的编写

MAKEFILE的编写第一章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都成为了一种在工程方面的编译方法。

make命令执行时,需要一个Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

首先,我们用一个示例来说明Makefile的书写规则。

以便给大家一个感兴认识。

这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。

我们的规则是:1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

简单制作Makefile方法

简单制作Makefile方法

1.在当前目录下创建一个名为hello的子目录。hello这个目录用于存放hello.c这个程序及相关文件。新建一个源程序文件hello.c
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Welcome to use autoconf and automake\n");
通过以上步骤,在源代码所在目录下自动生成了Makefile文件。
configure.in文件
autoconf提用来产生"configure"文件的工具。"configure"是一个Shell脚本,它可以自动设定一些编译参数使程序能够在不同平台上进行编译。autoconf读取configure.in文件然后产生,"configure"这个Shell脚本。
如何使用产生的Makefile文件
执行configure脚本文件所产生的Makefile文件有几个预定的选项可供使用。
l make all:产生设定的目标,即生成所有的可执行文件。使用make也可以达到此目的。
l make clean:删除之前编译时生成的可执行文件及目标文件(形如*.o的中间文件)。
configure.in文件的内容是一系列GNU m4的宏,这些宏经autoconf理后会变成检查系统特性的Shell脚本。configure.in文件中宏的顺序并没有特别的规定,但是每一个configure.in文件必须以宏AC_INIT开头,以宏AC_OUTPUT结束。一般可先用autoscan这个工具扫描原始文件以产生一个configure.scan文件,再对configure.scan作些修改,从而生成configure.in文件

如何写一个简单的Makefile

如何写一个简单的Makefile

如何写一个简单的Makefile当我们在提示符号之下下一个命令:$ make program就是说你要去”make”一个新版本—而且通常是最新版本—的程序. 如果这个程序是一个可执行文件,你所下的这个命令意思就是说你想要完成有所必须的编译(compiling)与连结(linking),然后得出一一个可执行文件. 你可以使用make来使这些程序自动化,不必不断输入为数可观的gcc(or cc)这些编译器指令.当我们讨论make的时候,我们把我们所要建造的程序(program)称做目标(target). 程序是由一个或一个以上的文件汇集在一起所建造出来的,这些文件的关系分为必要文件(prerequisites)与附属文件(dependents). 每一个构成程序的文件依序有他们自己的必要文件和附属文件.例如,你由连结建造了可执行文件. 一旦你的原始文件(source file)或头文件(head file)改变了,你就必须再连结新的可可执行文件之前重新编译目标文件(object file). 每一个原始文件都是一个目标文件的必要文件.Make的优点就是它对附属的隶属关系是非常敏感的,像是原始文件->目标文件,目标文件->可可执行文件. 你负责在描述文件(description file)中指定一些附属文件,这个描述文件的文件名通常为makefile 或是Makefile. 但是make也知道自己所在的执行环境,它也会自己决定许多它自己的附属文件. make会利用文件的文件名,这些文件最近修改的时间,和一些內建的规则,决定编译时要使用哪些文件与如何去建立它们. 在这样的技术背景之下,之前所做的那个简单的make指令会保证在隶属中所有建造目标时必须存在的部分都会被更新.描述文件(Description File)假设你写了一个程序,程序由以下部分所組成:*用C语言写的原始文件— main.c iodat.c dorun.c*用其它语言写的程序码—lo.s ,此文件被C写成的原始文件所调用*一組位于/usr/fred/lib/crtn.a 之中的函数库方法(library routine)如果你用手一一下指令建造这个程序,你会在提示符号下打入:$cc –c main.c$cc –c iodat.c$cc –c dorun.c$as –0 lo.o lo.s$cc –o program main.o iodat.o dorun.o lo.o /usr/fred/lib/crtn.a当然你也可以在一行cc命令之內就做好编译,连结的工作(要下很长的一串指令),但是在实际的程序设计环境下这是很少发生的(因为指令实在是又长又复杂),因为以下原因: 首先,每一个原始文件都可能被不同的人所建立或测试. 第二,一个大程序会花掉好几小时的编译工作,所以程序设计师一般都会尽可能的使用已经存在的目标文件而不要再重新编译(可以节省时间).现在让我们来看看如何透过描述文件下指令給make. 我们建立了一个新的文件叫做makefile,这个文件和所有的原始码放在同一个目录之下. 为了方便起见,这个描述文件中的每一个指令和附属文件都明显的打出来,很多对make来说都是不需要的. 这个描述文件的內容如下:program : main.o iodat.o dorun.o lo.o /usr/fred/lib/crtn.acc –o program main.o iodat.o dorun.o lo.o /usr/fred/lib/ctrn.amain.o : main.ccc –c main.ciodat.o : iodat.ccc –c iodat.cdorun.o : dorun.ccc –c dorun.clo.o : lo.sas –0 lo.o lo.s在每一行左边的数字并不属于描述文件的一部份,只是为了待会解释方便这个描述文件中包含了五个项目(或说是入口点)(entry). 每一个项目由一个含有冒号(:)(叫做附属列[dependency line]或是规则列[rules line]),和一个或一个以上以tab(4个字元空白)开头的命令列(command line). 在附属行那个冒号左边的叫做目标(target);冒号左边的就是目标的必要文件. 受tab影响的(tab-indented)命令列,告诉make如何从他们的必须文件中建造出目标.从上面的描述文件来看,第1列说明了program这个目标依靠main.o,iodat.o,dorun.o,lo.o这些目标文件,还有依靠函数库/usr/fred/lib/crtn.a .第2列指定了从必要文件构造program这个目标文件所必须下的编译器指令.(这些文件都是目标文件与函数库,所以实际上并不用编译,只调用了连结器(linker)而已). 假设program这的目标文件不存在,你可以下这个指令:$make programmake会去执行第二行的命令. 如果其中一个目标文件不在该怎么办呢? 你能够把这个目标文件当作参数传給make(例如:没有main.o ,你可以下指令$make main.o ,就可以得到main.o 这个文件),但是几乎不必这样做.Make最重要的贡献就在于它有能力可以自己决定什么东西必须被建立(例如:在建立program时,如果少了main.o,则他会根据附属列所指定的內容,自己建立main.o这个文件).检查附属文件(Dependency Checking)当你要求make去建造program这个目标时,make会去参考前面所列出的那一个描述文件,但是,第二列的编译器指令并不会立刻就执行. make所做的动作应该如下: 首先,make先去检查目录下是否有program这个文件,如果有的话,make会去检查main.o , iodat.o , dorun.o , lo.o , 还有/usr/fred/lib/crtn.a 这些文件,看看这些文件有没有比program这个文件更新(更新的意思是说,这些文件比program这个文件建造的时间更晚). 这个动作非常容易,因为操作系统会储存每一个文件最近被修改的时间,你只要下一个指令ls –l就可以看到这个信息. 如果program的建造时间比它所有的必要文件的最近修改时间还要晚,make会决定不再重新建造program这个文件,然后不会发出任何指令就离开(跳回提示符号下). 但是在make下这个决定之前,它还会做一些检查: make会根据附属列所描述的必要文件,去检查每一个 .o文件的必要文件是否有更新的情况.例如,从第3列就可以看出main.o的建造必须依靠main.c. 因此,如果再main.o被建造之后,main.c才又被修改,则make就会去执行第4列的指令重新建造一个新的main.o. 只有在program的必要文件都被检查而且更新过(这必要文件的必要文件也要被检查且更新过. 例如:main.o是program的必要文件,main.c是main.o的必要文件). make 才会去执行第2列的指令建造program这个目标文件. 假设自从上一次建造program这个文件之后,iodat.c是唯一被更新过的文件,所以当我们再次执行$make program之后,make所发出的编译器指令实际上只有cc –c main.ccc –o program main.o iodat.o dorun.o lo.o /usr/fred/lib/crtn.a这两行指令而已.make命令执行以后,会在标准输出上显示出它所发出的指令,因此当你使用make的时候,你可以从你的屏幕上看到它所发出的命令的顺序.总而言之,一个程序的建造包含了顺序正确的指令连接(chain). 一般而言,你只要要求make去建造连接中最后的那个文件即可. make会透过附属文件连接(你在描述文件中所指定的那些必要文件所构成的树状結构构成附属文件连接),自己回朔跟踪(traces back,也就是往树状結构的叶子方向)这个连接,然后找出哪些指令必须被执行. 最后,make会慢慢在连接中前进(moves forward,就是往数状結构的根部移动),执行每个建造目标所必须要有的指令直到目标建立完成(或被更新). 因为这种特性,make是一个使用后序方法(backward-chaining:在人工智能领域中,一种搜索问题答案的方法,它的搜索方向是由目标状态开始,然后向初始状态前进,最后再慢慢回来)这个技巧最有名的例子,这个技巧通常仅使用在像是Prolog语言这一类大家比较不熟悉的环境上.重建最小化(Minimizing Rebuilds)现在我们来讨论一个可以以各种不同版本形式存在的程序(通常是不同平台,或是不同操作系统,或是要分散(release)給不同层级使用者的版本),这是一个可以告诉你make如何节省你的时间,而且可以避免混淆的例子,比前的例子更复杂一点. 假设你写了一个可以绘出文件的程序,它可以在终端(文字模式)或是图形界面(例如:X window)之下执行. 涉及到计算和文件处理的部分在两个版本之中都相同,而且你把它们都存放在basic.c这个文件中. 处理文字模式下使用者输入的程序放在prompt.c之中,而处理图形界面上使用者输入的程序放在window.c之中.因此,这个程序可以以两种不同的版本被发行(release),当你想要建立这个程序时,你可以选择要建立你觉得最适合你现在工作环境的版本. 以文字模式下的版本来说,你可以由basic.c 与prompt.c这两个文件来产生plot_prompt这个可执行文件. 对图形界面的版本来说,你就可以使用basic.c与window.c这两个文件来产生叫做plot_win的可执行文件. 以下产生这两种版本所使用的自述文件:plot_prompt : basic.o prompt.occ –o plot_prompt basic.o prompt.oplot_win : basic.o window.occ –o plot_win basic.o window.obasic.o : basic.ccc –c basic.cprompt.o : prompt.ccc –c prompt.cwindow.0 : window.ccc –c window.c当你第一次建造其中一个可执行文件时,你必须编译basic.c这个文件. 但是只要你没有改变basic.c这个文件,也没有刪除掉basic.o的话,下一次你想要重新产生新的图形界面可执行文件时,就可以不必再重新编译basic.c. 如果你修改了prompt.c,然后重新建立plot_prompt的话,make会去检查修改时间,然后就明白只要重新编译prompt.c,然后再连结就可以了. 也就是说,如果你重新下$make plot_prompt这个指令,你会在屏幕上看到下面的結果:cc –c promptcc –o plot_prompt basic.o prompt.o这这些范例之中的描述文件,实际上可以被大量的简化. 因为make 有內建的规则和宏(macro)的定义可以用来处理在文件中一再重复出现的附属物(dependencies),例如”.o”文件的附属文件”.c”文件,他们都是前面的名称相同,只有副文件名不同而已. 我们会讨论这些make的特色. 在这里,我们只把附属(dependency)和更新(updating)的概念传达給你而已引用make(Invoking make)前面的几个小节的范例都有以下的假设:*工程文件(project file),也就是描述文件,和原始码放在同一个目录底下*描述文件的文件名叫做makefile或是Makefile*將你输入make指令时,工作目录就是这些文件放置的目录有了这些假设,你只要下一个$make target的指令,就可以建立在描述文件中的任何一个目标. 建造这个目标所必须要下的指令都会被显示在终端上,然后执行. 如果一些中间文件(intermediate file)已经存在或者已经被更新过,make会掠过建造这些中间文件的指令. make只会发出建造这个目标所必须执行的最少指令. 如果在上次建造这个目标后,没有任何必要文件被修改或是删除,make会发出一个信息‘target’ is up to date然后什么事情也不做.如果你想要建造在描述文件中没有指定,后置规则(suffix rule)中所讨论的內定规则所蕴涵的目标,例如:你下了一个指令建造一个不存在的目标$make nottarget则make会回应:‘nottarget’ is up to date或是make: Don’t know ho to ma ke nontarget. Stop.如果再目前的工作目录之下真的有nontarget这个文件存在,就会发出上面的第一个信息. 我们可以一次要make建立好几个目标. 这个命令的效果就跟连续的发出好几个make命令相同,例如:$make main.o target就相当于$make main.o$make target一样我们也可以只简单的打上$make没有附上任何的目标名称. 在此情況下,在描述文件中的第一个目标將会被建立(同时他的必要文件也会一起被建立)在命令列下发出make指令有许多的选择项(option,通常前面会加上”-“). 例如,你可以选择不要在终端上显示出make所发出的命令. 反过来说,你也可以要求显示出哪些命令会被执行,而实际上并没有执行它们.语法的基本规则(Basic Rules of Syntax)在你开始要尝试写自己的描述文件之前,你应该了解一些在make所使用的一些难懂的条件(requirement),这些条件如果单独从范例中来体会,是不够不清楚的.最重要的一条规则就是”每一个命令列的开头都要是一个tab字元(四个空格)”. 一个常常犯的错误就是在每个命令列的开头省略了tab字元. 就算在每个命令列中按空白键插入四个空白也不行,因为make无法辨別出这就是tab字元,而且非常不幸的,在这种情況下,就算出了错误,make也无法提供有用的信息.make是靠开头的那个tab字来辨认命令列,所以一定要注意不要在其他不是命令列的那一列之前加上tab字元. 如果你把tab当作第一个字元加在附属列,注解,或这甚至是一个空白列之前,你都会得到错误信息.Tab字元可以用在每一列的任何地方,只有在每一列的第一个字元才有上述的限制.如果你想要检查描述文件中的tab字元,你可以下指令$cat –v –t –e makefile在这里–v 与–t会使得描述文件中的每一个tab字元以^I 的方式显示出来,而–e 会使得每一列的最后以$ 的样子显示出来,所以你可以看出在每一列的結束之前有几个空白.你可以打很长一串指令,如果已经到了文字编辑器的右边界,你可以在到达右边界之前放入一个斜线(\)符号. 你必须确定在新的一列开始之前,会有一个斜线符号在哪里.斜线符号和新的一行之间不要有空白(don’t let any white space slip in between). 由斜线符号所连续的每一列都会被当作单独一列来语法分析(parsing).make会忽略描述文件中的空白行(blank line). 同样的,它也会忽略掉以# 符号开头,到每一列結尾之间的字元,所以# 符号用来当作每个注解的开头.命令列跟附属列不一定都要各自佔掉一列的空间,你可以写成plot_prompt : prompt.o ; cc –o plot_prompt prompt.o虽然之前有说过命令列的开头都要有一个tab字元,不过这里是唯一的例外.一个单独的目标也可以用多个附属列来表示. 当你为了要易于区分附属文件的的种类时,这是一个很实用的技巧,例如file.o : file.ccc –c file.c……file.o : global.h defs.h虽然实际上建造file.o的命令是第一个附属列的下面那一行,即使重新建造时,file.c并没有被修改,可是如果附属的.h文件被修改过的话,file.o仍然会被重新编译.如果你使用了多个附属列的技巧,只有其中一个附属列才能有能够伴随有指令列. 但是如果你在一个附属列中使用了两个冒号,则不在此限.在描述文件中可以有”没有附属文件的目标”(但是冒号还是要打上去,不能省略),这些文件通常不全是文件名. 例如,许多描述文件含有下面的目标,用来幫助程序设计师在一天辛苦的测试之后删除临时文件.clean :/bin/rm –f core *.o当我们下指令$make clean如果工作目录下没有clean这个文件,make就会去执行claen这个项目下的命令脚本(command script). 这是因为make把每一个不存在的目标当作是一个过时的目标在每个项目中的命令,就目前来说,应该要是單一一行的Bourne Shell指令.不要尝试去使用別名(aliases),环境变数(environment variables),或是像if或for这一类会有很多行的命令,同时要避免使用cd,现在你已经能够借由输入你习惯在终端前打的指令来建立你自己的描述文件了. 但是很快的,你会发现非常的乏味. 往后你可简化(simplify)与一般化(generalize)你属于你自己的描述文件的方法.。

Makefile书写规范

Makefile书写规范

跟我一起写Makefile陈皓(CSDN)概述——什么是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++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。

makefile写法实例

makefile写法实例

makefile写法实例makefile例⼦假设我们有⼀个程序由5个⽂件组成,源代码如下:/*main.c*/#include"mytool1.h"#include"mytool2.h"int main(){mytool1_print("hello mytool1!");mytool2_print("hello mytool2!");return 0;}/*mytool1.c*/#include"mytool1.h"#include<stdio.h>void mytool1_print(char *print_str){printf("This is mytool1 print : %s ", print_str);}/*mytool1.h*/#ifndef _MYTOOL_1_H#define _MYTOOL_1_Hvoid mytool1_print(char *print_str);#endif/*mytool2.c*/#include"mytool2.h"#include<stdio.h>void mytool2_print(char *print_str){printf("This is mytool2 print : %s ", print_str);}/*mytool2.h*/#ifndef _MYTOOL_2_H#define _MYTOOL_2_Hvoid mytool2_print(char *print_str);#endif⾸先了解⼀下make和Makefile。

GNU make是⼀个⼯程管理器,它可以管理较多的⽂件。

我所使⽤的RedHat 9.0的make版本为GNU Make version 3.79.1。

Makefile简单编写

Makefile简单编写

Makefile 惯例下面是Makefile中一些约定俗成的目标名称及其含义:all编译整个软件包,但不重建任何文档。

一般此目标作为默认的终极目标。

此目标一般对所有源程序的编译和连接使用"-g"选项,以使最终的可执行程序中包含调试信息。

可使用strip 程序去掉这些调试符号。

clean清除当前目录下在make 过程中产生的文件。

它不能删除软件包的配置文件,也不能删除build 时创建的那些文件。

distclean类似于"clean",但增加删除当前目录下的的配置文件、build 过程产生的文件。

info产生必要的Info 文档。

check 或test完成所有的自检功能。

在执行检查之前,应确保所有程序已经被创建(但可以尚未安装)。

为了进行测试,需要实现在程序没有安装的情况下被执行的测试命令。

install完成程序的编译并将最终的可执行程序、库文件等拷贝到指定的目录。

此种安装一般不对可执行程序进行strip 操作。

install-strip和"install"类似,但是会对复制到安装目录下的可执行文件进行strip 操作。

uninstall删除所有由"install"安装的文件。

installcheck执行安装检查。

在执行安装检查之前,需要确保所有程序已经被创建并且被安装。

installdirs创建安装目录及其子目录。

它不能更改软件的编译目录,而仅仅是创建程序的安装目录。

下面是Makefile 中一些约定俗成的变量名称及其含义:这些约定俗成的变量分为三类。

第一类代表可执行程序的名字,例如CC 代表编译器这个可执行程序;第二类代表程序使用的参数(多个参数使用空格分开),例如CFLAGS 代表编译器执行时使用的参数(一种怪异的做法是直接在CC 中包含参数);第三类代表安装目录,例如prefix 等等,含义简单,下面只列出它们的默认值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

隐含规则————在我们使用Makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix下是[.o]文件,Windows下是[.obj]文件)。

本章讲述的就是一些在Makefile中的“隐含的”,早先约定了的,不需要我们再写出来的规则。

“隐含规则”也就是一种惯例,make会按照这种“惯例”心照不喧地来运行,那怕我们的Makefile中没有书写这样的规则。

例如,把[.c]文件编译成[.o]文件这一规则,你根本就不用写出来,make会自动推导出这种规则,并生成我们需要的[.o]文件。

“隐含规则”会使用一些我们系统变量,我们可以改变这些系统变量的值来定制隐含规则的运行时的参数。

如系统变量“CFLAGS”可以控制编译时的编译器参数。

我们还可以通过“模式规则”的方式写下自己的隐含规则。

用“后缀规则”来定义隐含规则会有许多的限制。

使用“模式规则”会更回得智能和清楚,但“后缀规则”可以用来保证我们Makefile的兼容性。

我们了解了“隐含规则”,可以让其为我们更好的服务,也会让我们知道一些“约定俗成”了的东西,而不至于使得我们在运行Makefile时出现一些我们觉得莫名其妙的东西。

当然,任何事物都是矛盾的,水能载舟,亦可覆舟,所以,有时候“隐含规则”也会给我们造成不小的麻烦。

只有了解了它,我们才能更好地使用它。

一、使用隐含规则如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。

那么,make会试图去自动推导产生这个目标的规则和命令,如果make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。

当然,隐含规则是make事先约定好的一些东西。

例如,我们有下面的一个Makefile:foo : foo.o bar.occ –o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)我们可以注意到,这个Makefile中并没有写下如何生成foo.o和bar.o这两目标的规则和命令。

因为make的“隐含规则”功能会自动为我们自动去推导这两个目标的依赖目标和生成命令。

make会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。

如果找不到,那么就会报错。

在上面的那个例子中,make调用的隐含规则是,把[.o]的目标的依赖文件置成[.c],并使用C 的编译命令“cc –c $(CFLAGS) [.c]”来生成[.o]的目标。

也就是说,我们完全没有必要写下下面的两条规则:foo.o : foo.ccc –c foo.c $(CFLAGS)bar.o : bar.ccc –c bar.c $(CFLAGS)因为,这已经是“约定”好了的事了,make和我们约定好了用C编译器“cc”生成[.o]文件的规则,这就是隐含规则。

当然,如果我们为[.o]文件书写了自己的规则,那么make就不会自动推导并调用隐含规则,它会按照我们写好的规则忠实地执行。

还有,在make的“隐含规则库”中,每一条隐含规则都在库中有其顺序,越靠前的则是越被经常使用的,所以,这会导致我们有些时候即使我们显示地指定了目标依赖,make也不会管。

如下面这条规则(没有命令):foo.o : foo.p依赖文件“foo.p”(Pascal程序的源文件)有可能变得没有意义。

如果目录下存在了“foo.c”文件,那么我们的隐含规则一样会生效,并会通过“foo.c”调用C的编译器生成foo.o文件。

因为,在隐含规则中,Pascal的规则出现在C的规则之后,所以,make找到可以生成foo.o的C的规则就不再寻找下一条规则了。

如果你确实不希望任何隐含规则推导,那么,你就不要只写出“依赖规则”,而不写命令。

二、隐含规则一览这里我们将讲述所有预先设置(也就是make内建)的隐含规则,如果我们不明确地写下规则,那么,make 就会在这些规则中寻找所需要规则和命令。

当然,我们也可以使用make的参数“-r”或“--no-builtin-rules”选项来取消所有的预设置的隐含规则。

当然,即使是我们指定了“-r”参数,某些隐含规则还是会生效,因为有许多的隐含规则都是使用了“后缀规则”来定义的,所以,只要隐含规则中有“后缀列表”(也就一系统定义在目标.SUFFIXES的依赖目标),那么隐含规则就会生效。

默认的后缀列表是:.out, .a, .ln, .o, .c, .cc, .C, .p, .f, .F, .r, .y, .l, .s, .S, .mod, .sy m, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el。

具体的细节,我们会在后面讲述。

还是先来看一看常用的隐含规则吧。

1、编译C程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.c”,并且其生成命令是“$(CC) –c $(CPPFLAGS) $(CFLAGS)”2、编译C++程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.cc”或是“<n>.C”,并且其生成命令是“$(CXX) –c $(CPPFLAGS) $(CFLAGS)”。

(建议使用“.cc”作为C++源文件的后缀,而不是“.C”)3、编译Pascal程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.p”,并且其生成命令是“$(PC) –c $(PFLAGS)”。

4、编译Fortran/Ratfor程序的隐含规则。

“<n>.o”的目标的依赖目标会自动推导为“<n>.r”或“<n>.F”或“<n>.f”,并且其生成命令是: “.f”“$(FC) –c $(FFLAGS)”“.F”“$(FC) –c $(FFLAGS) $(CPPFLAGS)”“.f”“$(FC) –c $(FFLAGS) $(RFLAGS)”5、预处理Fortran/Ratfor程序的隐含规则。

“<n>.f”的目标的依赖目标会自动推导为“<n>.r”或“<n>.F”。

这个规则只是转换Ratfor或有预处理的Fortran程序到一个标准的Fortran程序。

其使用的命令是:“.F”“$(FC) –F $(CPPFLAGS) $(FFLAGS)”“.r”“$(FC) –F $(FFLAGS) $(RFLAGS)”6、编译Modula-2程序的隐含规则。

“<n>.sym”的目标的依赖目标会自动推导为“<n>.def”,并且其生成命令是:“$(M2C) $(M2FLAGS) $(DEFFLAGS)”。

“<n.o>” 的目标的依赖目标会自动推导为“<n>.mod”,并且其生成命令是:“$(M2C) $(M2FLAGS) $(MODFLAGS)”。

7、汇编和汇编预处理的隐含规则。

“<n>.o” 的目标的依赖目标会自动推导为“<n>.s”,默认使用编译品“as”,并且其生成命令是:“$(AS) $(ASFLAGS)”。

“<n>.s” 的目标的依赖目标会自动推导为“<n>.S”,默认使用C预编译器“cpp”,并且其生成命令是:“$(AS) $(ASFLAGS)”。

8、链接Object文件的隐含规则。

“<n>”目标依赖于“<n>.o”,通过运行C的编译器来运行链接程序生成(一般是“ld”),其生成命令是:“$(CC) $(LDFLAGS) <n>.o $(LOADLIBES) $(LDLIBS)”。

这个规则对于只有一个源文件的工程有效,同时也对多个Object文件(由不同的源文件生成)的也有效。

例如如下规则:x : y.o z.o并且“x.c”、“y.c”和“z.c”都存在时,隐含规则将执行如下命令:cc -c x.c -o x.occ -c y.c -o y.occ -c z.c -o z.occ x.o y.o z.o -o xrm -f x.orm -f y.orm -f z.o如果没有一个源文件(如上例中的x.c)和你的目标名字(如上例中的x)相关联,那么,你最好写出自己的生成规则,不然,隐含规则会报错的。

9、Yacc C程序时的隐含规则。

“<n>.c”的依赖文件被自动推导为“n.y”(Yacc生成的文件),其生成命令是:“$(YACC) $(YFALGS)”。

(“Yacc”是一个语法分析器,关于其细节请查看相关资料)10、Lex C程序时的隐含规则。

“<n>.c”的依赖文件被自动推导为“n.l”(Lex生成的文件),其生成命令是:“$(LEX) $(LFALGS)”。

(关于“Lex”的细节请查看相关资料)11、Lex Ratfor程序时的隐含规则。

“<n>.r”的依赖文件被自动推导为“n.l”(Lex生成的文件),其生成命令是:“$(LEX) $(LFALGS)”。

12、从C程序、Yacc文件或Lex文件创建Lint库的隐含规则。

“<n>.ln” (lint生成的文件)的依赖文件被自动推导为“n.c”,其生成命令是:“$(LINT) $(LINTFALGS) $(CPPFLAGS) -i”。

对于“<n>.y”和“<n>.l”也是同样的规则。

三、隐含规则使用的变量在隐含规则中的命令中,基本上都是使用了一些预先设置的变量。

你可以在你的makefile中改变这些变量的值,或是在make的命令行中传入这些值,或是在你的环境变量中设置这些值,无论怎么样,只要设置了这些特定的变量,那么其就会对隐含规则起作用。

当然,你也可以利用make的“-R”或“--no–builtin-variables”参数来取消你所定义的变量对隐含规则的作用。

例如,第一条隐含规则——编译C程序的隐含规则的命令是“$(CC) –c $(CFLAGS) $(CPPFLAGS)”。

Make默认的编译命令是“cc”,如果你把变量“$(CC)”重定义成“gcc”,把变量“$(CFLAGS)”重定义成“-g”,那么,隐含规则中的命令全部会以“gcc –c -g $(CPPFLAGS)”的样子来执行了。

我们可以把隐含规则中使用的变量分成两种:一种是命令相关的,如“CC”;一种是参数相的关,如“CFLAGS”。

下面是所有隐含规则中会用到的变量:1、关于命令的变量。

相关文档
最新文档