【问题标题】:Makefile generic rule not workingMakefile通用规则不起作用
【发布时间】: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 再三考虑我同意你的观点,所以我删除了它。我最初的想法是,如果它们被更改,它应该重建源,但我这样做的方式是不正确的,就像你说的那样是多余的,因为它已经被不工作的目标文件的依赖所暗示。问题还没有解决,到目前为止你的所有评论都与问题无关,所以我编辑了问题以澄清我想问的问题。
  • 有一定的问题质量阈值,我不愿意将问题转化为实际再现报告的问题,而是倾向于指出问题中的弱点问题。没关系,它现在出现在我的眼前,添加了答案。

标签: gcc makefile


【解决方案1】:

尝试将./build./src 添加到您的规则中(它们包含在您的“显式”规则中,但不包含在您在Makefile 中使用的变量中)。

【讨论】:

  • 就是这样。我怀疑它与目录有关...将%$(OBJECT_EXT): %$(SOURCE_EXT) 更改为$(OBJECT_DIR)/%$(OBJECT_EXT): $(SOURCE_DIR)/%$(SOURCE_EXT) 修复了它。你能解释一下为什么在目标前面加上目录很重要吗?我希望% 符号包含目录。
  • @RPFeltz:如果% 包含目录,你怎么能为源文件目录以外的目录中的目标文件制定规则?
  • 嗯,我不太清楚你的意思。我个人是这样理解的:所有以 .obj 结尾的依赖都应该由 %.obj 指定的规则来处理,与它们所在的目录无关。
  • @RPFeltz:那你还没有真正理解% 是如何工作的。规则 dependency 端的 % 被规则 target 端的% 所代表的字符串替换为了。如果 %.obj 匹配例如./build/main.obj,那么右侧的 %.cc 将是 ./build/main.cc - 您将无法从不同目录中的源文件创建 ./build 中的目标文件。这就是为什么% 不匹配目录名,而只匹配文件名(或者实际上是基本名)。
  • 我明白了!这很有意义。我现在明白为什么它不起作用了。非常感谢。
猜你喜欢
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多