【问题标题】:Generate include files for the Makefile by the same Makefile通过同一个 Makefile 为 Makefile 生成包含文件
【发布时间】:2017-02-23 09:03:14
【问题描述】:

在我的程序中,我的构建过程有些复杂。目前,在一个目录中,我在Makefile.am 中使用include 和一个文件,该文件不存在但必须自行构建。原因是这个包含文件很长。进一步在实际程序中,它不仅仅是一个文件,而是多个文件,并且该文件的生成过程会不时改变。

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 似乎被加载了不止一次。

此外,Automake 的 manual include 声明:

请注意,这些片段是由 automake 读取和解释的,而不是由 制作。

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

我的问题基本上是:

  • 为什么有效?
  • 这是正确的方法还是我应该使用其他方法,例如在Makefile 内启动make 的新实例。

【问题讨论】:

    标签: makefile autotools


    【解决方案1】:

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

    如果在任何这些目录中都找不到包含的 makefile {标准包含目录},a 生成警告消息,但它不是立即致命的 错误;继续处理包含包含的 makefile。 一旦它完成了对 makefile 的读取,make 将尝试重新制作任何 已过时或不存在。请参阅如何重新制作 Makefile。 只有在它试图找到一种方法来重新制作一个 makefile 并且失败之后, 将 make 将丢失的 makefile 诊断为致命错误。

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

    -include filenames…

    这就像在所有方面都包含在内,除了如果任何文件名(或任何 任何文件名的先决条件)不存在或不能 重制。

    所以基本上,在他完成对主 Makefile 的解析之前,make 无法执行重新制作包含文件的方法。所以它会引发警告,继续阅读 Makefile,找到重新制作包含文件的规则,重新制作它,然后重新启动自己(这在 Makefiles 如何重新制作部分中有详细说明)。

    【讨论】:

    • 感谢您的评论。我认为这主要解释了它为什么起作用。我将查看制作手册以获取更多详细信息。不过,我不会接受答案,因为也许有人对如何处理我的情况有更好的了解。
    • 仅供参考,无关的错误消息问题已在较新版本的 GNU make(4.2 及更高版本)中得到修复;您不再需要使用-include 来抑制它。
    【解决方案2】:

    回到manual,它指出automakes 包含两种形式:

    include $(srcdir)/file
    

    include $(top_srcdir)/file
    

    两者都不匹配您的include。所以我想include实际上是由底层make运行的(例如GNU Make,当然其他make程序也有这个功能)。

    现在回答问题:

    为什么会起作用?

    正如另一个答案中所解释的,GNU Make 将尝试在失败之前创建一个丢失的 included 生成文件。

    这是正确的方法还是我应该使用另一种方法,例如在 Makefile 中启动新的 make 实例

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

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

    automakeinclude 语句会很高兴地将一个由较小组件组成的大型 makefile 粘贴在一起。

    进一步在实际程序中,它不仅仅是一个文件,而是多个文件,并且这个文件的生成过程会不时改变。

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

    【讨论】:

      猜你喜欢
      • 2020-07-28
      • 2012-07-06
      • 2012-10-02
      • 2016-10-13
      • 1970-01-01
      • 2021-04-20
      • 2013-10-18
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多