【发布时间】:2014-05-22 10:53:14
【问题描述】:
我试图创建一个通用的 makefile,您可以在其中提供源文件和一些目录的名称,但我无法获得目标文件工作的通用规则。
我的makefile是这样的:
SOURCE_NAMES=main
EXECUTABLE_NAME=Program
EXECUTABLE_DIR=./dist
EXECUTABLE_EXT=
SOURCE_DIR=./src
SOURCE_EXT=.cc
OBJECT_DIR=./build
OBJECT_EXT=.obj
COMPILER=gcc
COMPILER_FLAGS=-c -Wall -std=gnu++11
LINKER_FLAGS=
SOURCES=$(addsuffix $(SOURCE_EXT),$(addprefix $(SOURCE_DIR)/,$(SOURCE_NAMES)))
OBJECTS=$(addsuffix $(OBJECT_EXT),$(addprefix $(OBJECT_DIR)/,$(SOURCE_NAMES)))
EXECUTABLE=$(EXECUTABLE_DIR)/$(EXECUTABLE_NAME)$(EXECUTABLE_EXT)
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(COMPILER) $(LINKER_FLAGS) $(OBJECTS) -o $@
%$(OBJECT_EXT): %$(SOURCE_EXT)
$(COMPILER) $(COMPILER_FLAGS) $< -o $@
但是,从我得到的错误来看,最终规则 %$(OBJECT_EXT): %$(SOURCE_EXT) 似乎无法正常工作:
make: *** Er is geen regel om doel 'build/main.obj' te maken, nodig voor 'dist/RandomGenerator'。格斯托。
翻译为:
make: *** 没有规则可以制作目标“build/main.obj”,这是“dist/RandomGenerator”所必需的。停止了。
当我明确地编写规则时,它确实有效:
./build/main.obj: ./src/main.cc
$(COMPILER) $(COMPILER_FLAGS) $< -o $@
但我宁愿不对每个源文件都明确地这样做。
我该如何解决这个问题?
编辑:
为了清楚起见,这个问题是关于为什么我的 makefile 末尾的通用规则不起作用。我希望 ./build/main.obj 与 %$(OBJECT_EXT) 或 %.obj 匹配,但事实并非如此,我不明白为什么它不起作用。
【问题讨论】:
-
不把扩展变成变量?我觉得你在这里有点过头了......
-
@DevSolar 你是什么意思?就像简单地将所有出现的 $(OBJECT_EXT) 和 $(SOURCE_EXT) 分别替换为 .obj 和 .cc 一样?我已经试过了,但没有用。
-
我无法真正理解您要做什么。例如,您将
$(SOURCES)添加到all:目标;你可能有一个好主意,但对我来说它看起来像一个错误。我建议采取相反的方式:从 simple(和功能性)Makefile 开始,然后从那里开始工作。另外,Makefile tutorial. -
@DevSolar 再三考虑我同意你的观点,所以我删除了它。我最初的想法是,如果它们被更改,它应该重建源,但我这样做的方式是不正确的,就像你说的那样是多余的,因为它已经被不工作的目标文件的依赖所暗示。问题还没有解决,到目前为止你的所有评论都与问题无关,所以我编辑了问题以澄清我想问的问题。
-
有一定的问题质量阈值,我不愿意将问题转化为实际再现报告的问题,而是倾向于指出问题中的弱点问题。没关系,它现在出现在我的眼前,添加了答案。