4

我正在尝试为我的 Makefile 创建一个通用的构建模板,就像他们在eval 文档中讨论的那样。

我遇到了 GNU Make 3.80 的一个已知错误。当 $(eval) 计算超过 193 个字符的行时,Make 崩溃并出现“虚拟内存耗尽”错误。

我拥有的导致问题的代码如下所示。

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $$(SRC_DIR)$(1)/
  $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c)
  $(1)_OBJ_FILES = $$($(1)_SRC_FILES):.c=.o)

  $$($(1)_OBJ_FILES) : $$($(1)_SRC_FILES) # This is the problem line
endef

$(eval $(call PROGRAM_template,$(PROG_NAME)))

当我运行这个 Makefile 时,我得到

gmake: *** virtual memory exhausted.  Stop.

预期的输出是 ./src/test/ 中的所有 .c 文件都被编译成 .o 文件(通过隐式规则)。

问题是 $$($(1)_SRC_FILES) 和 $$($(1)_OBJ_FILES) 一起超过 193 个字符(如果有足够的源文件)。

我尝试在只有 2 个 .c 文件的目录上运行 make 文件,它工作正常。只有当 SRC 目录中有许多 .c 文件时,我才会收到错误消息。

我知道 GNU Make 3.81 修复了这个错误。不幸的是,我没有权限或能力在我正在使用的系统上安装更新版本。我被困在3.80。

那么,有什么解决方法吗?也许将 $$($(1)_SRC_FILES) 拆分并在评估中单独声明每个依赖项?

4

2 回答 2

5

大声笑

ifneq (3.81,$(shell (echo $(MAKE_VERSION); echo 3.81) | sort | head -n1))

make-3.81/make:
        wget -nc http://ftp.gnu.org/pub/gnu/make/make-3.81.tar.gz
        gzip -cd make-3.81.tar.gz | tar xvf -
        cd make-3.81 && ./configure --prefix=$$(pwd)
        $(MAKE) -C make-3.81 make

%: make-3.81/make
        make-3.81/make $@

else

# rest of your makefile

endif

说真的,不可能有任何东西阻止您安装 3.81,即使它只是在本地安装。

于 2010-03-11T21:05:12.567 回答
3

也许没有人再需要这个了,但我想巧妙地使用include可以克服这种限制。

替换define PROGRAM_template为:

define PROGRAM_template
__template_arg := $(1)
include PROGRAM_template.mk
endef

创建PROGRAM_template.mk实现模板宏的核心:

$(__template_arg)_SRC_DIR = $(SRC_DIR)$(__template_arg)/
$(__template_arg)_SRC_FILES = $(wildcard $($(__template_arg)_SRC_DIR)*.c)
$(__template_arg)_OBJ_FILES = $($(__template_arg)_SRC_FILES:.c=.o)

$($(__template_arg)_OBJ_FILES) : $($(__template_arg)_SRC_FILES)
__template_arg :=

当然,这有点难看(使用全局变量将参数传递给技术上的宏)。我更喜欢第一个答案... :-)

于 2012-08-08T03:39:33.863 回答