通过相同的Makefile为Makefile生成包含文件

时间:2017-02-23 09:03:14

标签: makefile autotools

在我的程序中,我有一个有点复杂的构建过程。目前,在一个目录中,我在include中使用Makefile.am一个文件,该文件不存在但必须自行构建。原因是这个包含文件很长。此外,在真实程序中,它不仅仅是一个文件而是几个文件,并且该文件的生成过程可能会不时发生变化。

Makefile.am看起来像这样

noinst_LIBRARIES = libtest.a
nodist_libtest_a_SOURCES = file.c
CLEANFILES = file.c Make_file.mk 

$(builddir)/Make_test.mk: $(srcdir)/Perl/generate_mk_files.pl
      perl $(srcdir)/Perl/generate_mk_files.pl file

include $(builddir)/Make_file.mk

创建Make_file.mk后,它看起来像

$(builddir)/file.c: $(srcdir)/file.template $(srcdir)/Perl/generate_c.pl
      perl $(srcdir)/Perl/generate_c.pl $(srcdir)/file.template

Automake工作和最终构建过程。 make的输出类似于(我已经将其缩短了一些):

Makefile:721: Make_file.mk: Datei oder Verzeichnis nicht gefunden (file not found)
perl ../../../../src/components/test/Perl/generate_mk_files.pl test
perl ../../../../src/components/test/Perl/generate_c.pl ../../../../src/components/test/file.template

因此,make首先抱怨找不到包含文件,然后创建它,然后也遵循包含文件的规则。

虽然我很高兴它有效但我想知道为什么。首先,我认为make加载Makefile。在此步骤中,Make_file.mk不存在。因此,Makefile似乎不止一次加载。

此外,include的Automake manual表示:

  

请注意,这些片段由automake读取和解释,而不是由   使

这不是我所看到的,因为在执行Automake期间不存在包含的片段。

我的问题基本上是:

  • 为什么会这样?
  • 这是正确的方法吗?或者我应该使用其他方法,例如在make内开始Makefile的新实例。

2 个答案:

答案 0 :(得分:2)

我不太了解Automake,但是,从GNU make手册:

  

如果在任何这些目录中找不到包含的makefile {standard includes directories}, a   生成警告消息,但它不是立即致命的   错误;处理包含include的makefile继续。   一旦完成阅读makefile,make会尝试重制任何   已过期或不存在。请参阅如何重新制作Makefiles。   只有在它试图找到重制makefile并失败的方法之后,   将错误的makefile诊断为致命错误。

     

如果你想让make简单地忽略一个不存在的makefile或   无法重新编译,没有错误消息,请使用-include指令   而不是包括,像这样:

     

configurations { drivers } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.+' compile(group: 'org.testng', name: 'testng', version: '6.1.+'){ exclude group: "junit" } drivers ("com.company:chromedriver-win32:2.8@exe", "com.company:iechromedriver-win32:2.39@exe") } task copyDrivers(type: Copy) { from configurations.drivers into "$buildDir/drivers-down" }

     

除了没有任何错误(甚至没有警告),如果有任何文件名(或任何文件名)   任何文件名的先决条件)不存在或不存在   重拍。

所以基本上,在完成解析主Makefile之前,make不能执行重构include文件的配方。因此它会发出警告,继续读取Makefile,找到重新生成包含文件的规则,重新制作它,然后重新启动(在Make Makefiles Are Remade部分中有详细解释)。

答案 1 :(得分:0)

回到manual,它说明automake包含机制有两种形式:

include $(srcdir)/file

include $(top_srcdir)/file

两者都不符合您的include。所以我认为include实际上是由潜在的make运行的(例如GNU Make,但当然其他make程序也具有此功能)

现在提出问题:

  

为什么会这样?

正如另一个答案所解释的那样,GNU Make会在失败之前尝试制作一个丢失的include d makefile。

  

这是正确的方法吗?或者我应该使用其他方法,例如在Makefile中启动make的新实例

生成makefile是autotools执行的任务之一,可以通过autoconfautomake完成。经历“制作文件”的多个阶段似乎容易出错(并且难以维护)。 Recursive make也有类似的问题。

  

原因是这个包含文件很长。

automake include语句可以很好地将较大的makefile粘贴到较小的组件中。

  

此外,在真正的程序中,它不仅仅是一个文件而是几个文件,并且该文件的生成过程可能会不时发生变化。

根据“更改”的确定方式,很难建议在autotools中建议做什么。由于您似乎也在使用libtool向库(或整个库)添加/删除源,因此可能会受到conditionals,变量等的影响。