【问题标题】:How to detect which the first Makefile in a include chain?如何检测包含链中的第一个 Makefile?
【发布时间】:2021-01-19 04:10:28
【问题描述】:

假设我有一个目录~/dir1/dir2/dir3/,该目录中有一个文件Makefile,其中包含内容

include ../Makefile

~/dir1/dir2/Makefile~/dir1/dir2/dir3/Makefile的内容相同

如果允许我控制~/dir1/Makefile 的内容,并且make~/dir1/dir2/dir3/ 中被调用,我如何获取字符串~/dir1/dir2/dir3/Makefile(第一个包含文件)用作@987654332 中的变量@?

可重复的示例(根据 MadScientist 的要求):

  1. 任何 unix 系统
  2. mkdir -p ~/dir1/dir2/dir3
  3. cd ~/dir1/dir2/dir3
  4. echo 'include ../Makefile' > Makefile
  5. cp ./Makefile ../Makefile

现在我们在 ~/dir1/dir2/dir3/~/dir1/dir2/ 中有一个具有相同声明的 Makefile,即包含父目录中的 Makefile 的包含声明。

如果在~/dir1/dir2/dir3 中调用了make,那么包含链最终会停在~/dir1/Makefile

如何找到此包含链中第一个文件的路径,即~/dir1/dir2/dir3/Makefile 以用作~/dir1/Makefile 中的变量?

【问题讨论】:

  • 如果目录名称不完全一样,这个问题会更容易理解。我不确定你是如何从~/test/test/test/Makefile~/test/Makefile...还有其他包含吗?无论如何,我认为您可以通过适当使用 MAKEFILE_LIST gnu.org/software/make/manual/html_node/… 来获得您想要的东西,但如果不是,也许您可​​以澄清这个问题,希望使用 MCVE stackoverflow.com/help/minimal-reproducible-example
  • 我建议您仅使用include 来合并专门为此目的设计和使用的makefile 片段。否则,如果您想使用其他 makefile 中定义的规则,请使用递归 make。这将为您省去很多麻烦。其中包括不确定任何给定文件是否是包含树的根。
  • @MadScientist 我已根据您的建议重构了帖子。 MAKEFILE_LIST 确实为我完成了这项工作,但在重构帖子后我发现了另一个错误。不知何故,包含来自父目录的 Makefile 意味着您不能包含存在于包含的 Makefile 的父目录中的另一个 Makefile(在包含的 Makefile 中),由于 dir2,我编写的示例在 make 中返回 Bad Address 错误makefile 包括../Makefile
  • 您新发现的错误是较低的两个makefile中的错误;您可以修复它,但不能从顶级生成文件中修复。至于主要问题,你想要波浪号('~')吗?绝对路径(例如/users/monke/dir1/dir2/dir3/Makefile)更容易构建。

标签: makefile gnu-make


【解决方案1】:

要获取从 CLI 调用的第一个 make 文件的完整路径:

make_path_called_from_cli:=$(firstword $(foreach mk,${MAKEFILE_LIST},$(abspath ${mk})))

获取包含当前make文件的make文件的完整路径:

$(info Using GNUmake Special variable to obtain Every make file used...)

$(info ${MAKEFILE_LIST})

$(info Compute the full path for all of those make files...)
all_make_file_full_path:=$(foreach mk,${MAKEFILE_LIST},$(abspath ${mk}))

$(info ${all_make_file_full_path})

$(info The last one from the list is the current make file...)

current_make_file_path:=$(lastword ${all_make_file_full_path})
$(info ${current_make_file_path})

$(info Now we remove the current make file from the list of make...)
all_make_file_path_except_current:=$(filter-out ${current_make_file_path}, ${all_make_file_full_path})

$(info ${all_make_file_path_except_current})

# Now the last one from the list is the make file which included the current one
parent_make_file_path:=$(lastword ${all_make_file_path_except_current})

$(info We finally have the answer...)
$(info ${parent_make_file_path})

【讨论】:

  • 我相信 OP 要求调用第一个 makefile(命令行中的那个),它只是 $(firstword $(MAKEFILE_LIST))
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 2020-06-22
  • 2016-02-19
相关资源
最近更新 更多