我正在尝试为我的Makefile创建一个通用的构建模板,就像他们在eval documentation中讨论一样。
我遇到了GNU Make 3.80的已知错误。当$(eval)评估超过193个字符的行时,使用“虚拟内存耗尽”错误导致崩溃。
我的代码导致问题看起来像这样。
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修复了这个bug。不幸的是,我没有权限或能力在我正在研究的系统上安装新版本。我坚持使用3.80。
那么,有一些解决方法吗?也许拆分$$($(1)_SRC_FILES)并在eval中单独声明每个依赖项?
答案 0 :(得分:5)
lol hacks
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的东西。
答案 1 :(得分: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 :=
当然,这有点难看(使用全局变量将参数传递给技术上的宏)。我更喜欢第一个答案......: - )