分享

Makefile的使用

 昵称48979411 2022-03-09

Make 工具最主要也是最基本的功能就是通过Makefile文件来描述源程序之间的相互关系并自动维护编译工作,本质上Makefile文件是个文本文件,用于配置编译过程。Makefile文件描述了整个工程的编译,连接等规则。其中包括工程中的哪些源文件需要编译以及如何编译,需要创建哪些中间文件以及如何创建这些中间文件,以及如何产生我们最后想要的可执行文件。尽管看起来是很复杂的事情,但是为工程编写Makefile的好处是能够用一行命令来完成自动化编译,极大提高了效率。

规则解释

Makefile 文件的规则包含了一系列规则。语法规则如下所示

Targets prerequisites

          Command

Command

Command

Targets一般是文件名,用空格隔开,一般一条规则只有一个文件名。

Commands是生成target(s)的一系列步骤,用Tab 符号开始,而不是空格。

Prerequisites也是文件名,用空格隔开,这些文件在target运行前必须存在,它们也可以成为依赖dependencies

make 程序根据规则的依赖关系,决定是否执行规则所定义的命令的过程我们称之为执行规则。

通常,make 在执行命令行之前会把要执行的命令行输出到标准输出设备,我们称之为回显(echo)。但是,如果规则的命令行以字符“@”开始,则 make 在执行这个命令时就不会回显这个将要被执行的命令。

也谈在.NET 平台上使用Scala 语言()- 银河- 博客园(cnblogs.com)

在上图中,第一行的五个文件是源程序文件,最后一行是我们要生成的目标文件,其余四个是编译过程中产生的中间文件,在目标文件生成之后,这些中间文件都可以被清除。

第一行到第七行定义了一些变量,第八行开始引用定义的变量,引用方法是$(变量名)

10行到第11行定义了一个规则,指明了如何从.cs文件生成.dll文件。Target是一个带有通配符(Wildcard)%的文件,用来匹配所有以.dll结尾的文件。对于%.dll: %.cs,表示所有的.dll文件依赖于对应的.cs文件。在command$@ 表示该规则的目标文件名,$<表示该规则的第一个依赖文件名。至于-out-t-r应该是具体编译器里面的指令。

13行的all是我们的终极目标,这个规则没有命令部分,仅仅是为了生成或更新它的依赖。我的理解是如果单独在cmd窗口写 makedotnet.exe 就会只生成dotnet.exe,如果写make,就会生成dotnet.exeCsTest.exe

1422行规则指明了如何生成dotnet.exeCsTest.exedotnet.msil

24行到第26行的规则用来运行编译好的目标文件。

28行到第29行的规则用来清除当前目录下编译生成的所有文件。Makefile文件中那些没有任何依赖只有执行动作的目标称为伪目标。可输入make clean来执行clean目标所定义的命令。

命令出错

我在现实情况确认遇到了,缺少某个文件,但是最后需要的报告还是生成了。

每当命令运行完后,make会检测每个命令的返回码,如果命令返回成功,那么make会执行下一条命令,当规则中所有的命令成功返回后,这个规则就算是成功完成了。如果一个规则中的某个命令出错了(命令退出码非零),那么make就会终止执行当前规则,这将有可能终止所有规则的执行。

有些时候,命令的出错并不表示就是错误的。例如mkdir命令,我们一定需要建立一个目录,如果目录不存在,那么mkdir就成功执行,万事大吉,如果目录存在,那么就出错了。我们之所以使用mkdir的意思就是一定要有这样的一个目录,于是我们就不希望mkdir出错而终止规则的运行。

为了做到这一点,忽略命令的出错,我们可以在Makefile的命令行前加一个减号“-”(在Tab键之后),标记为不管命令出不出错都认为是成功的。如:

clean:

-rm -f *.o

还有一个全局的办法是,给make加上“-i”或是“--ignore-errors”参数,那么,Makefile中所有命令都会忽略错误。而如果一个规则是以“.IGNORE”作为目标的,那么这个规则中的所有命令将会忽略错误。这些是不同级别的防止命令出错的方法,你可以根据你的不同喜欢设置。

还有一个要提一下的make的参数的是“-k”或是“--keep-going”,这个参数的意思是,如果某规则中的命令出错了,那么就停止该规则的执行,但继续执行其它规则。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多