【发布时间】:2011-07-07 21:07:25
【问题描述】:
我在尝试使用 make 将目标文件放在单独的子目录中时遇到了麻烦,这可能是一种非常基本的技术。我尝试使用此页面中的信息: http://www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types
我从 make 得到以下输出:
make: *** No rule to make target `ku.h', needed by `obj/kumain.o'. Stop.
然而 ku.h 是一个依赖而不是一个目标(尽管它显然是 #included 在 c 源文件中)。当我不尝试使用目标文件的子目录(即错过 OBJDIR 部分)时,它可以正常工作。为什么 make 认为 ku.h 是目标?
我的makefile是这样的:(样式是看了各种资料后的)
.SUFFIXES:
.SUFFIXES: .c .o
CC=gcc
CPPFLAGS=-Wall
LDLIBS=-lhpdf
VPATH=%.c src
VPATH=%.h src
VPATH=%.o obj
OBJDIR=obj
objects= $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
kushapes.o )
ku : $(objects)
$(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)
$(objects) : ku.h kudefines.h kuglobals.h kufns.h | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)
.PHONY: clean
clean :
rm $(objects)
编辑: 我应用了更改以使用 vpath 指令。我的版本是 VPATH=xxx 和 vpath %.c xxx 的错误混合。但是我现在遇到了另一个问题(这是我添加错误 vpath 之前的原始问题)。这是现在的输出:
gcc -o ku -lhpdf obj/kumain.o obj/kudlx.o obj/kusolvesk.o ..etc
gcc: obj/kumain.o: No such file or directory
gcc: obj/kudlx.o: No such file or directory
gcc: obj/kusolvesk.o: No such file or directory
gcc: obj/kugetpuz.o: No such file or directory
gcc: obj/kuutils.o: No such file or directory
gcc: obj/kurand.o: No such file or directory
gcc: obj/kuASCboard.o: No such file or directory
gcc: obj/kuPDFs.o: No such file or directory
gcc: obj/kupuzstrings.o: No such file or directory
gcc: obj/kugensud.o: No such file or directory
gcc: obj/kushapes.o: No such file or directory
make: *** [ku] Error 1
尽管手册说,make 似乎没有对目标文件应用隐式规则 “隐式规则告诉make如何使用惯用的技术,这样当你想使用它们时就不必详细指定它们。例如,有一个用于C编译的隐式规则。文件名决定了运行哪些隐式规则。对于例如,C 编译通常需要一个 .c 文件并生成一个 .o 文件。因此,当 make 看到这种文件名结尾组合时,它会应用 C 编译的隐式规则。以及“在考虑隐式规则时也会通过 VPATH 或使用 vpath 指定的目录进行搜索(请参阅使用隐式规则)。”
再次在这里“例如,当文件 foo.o 没有显式规则时,make 会考虑隐式规则,例如如果该文件存在则编译 foo.c 的内置规则。如果这样的文件在当前目录,在适当的目录中搜索它。如果 foo.c 在任何目录中存在(或在 makefile 中提到),则应用 C 编译的隐式规则。"
如果能帮助我获得适用于我的 makefile 的隐式规则,我们将不胜感激。
编辑 2: 感谢 Jack Kelly,我已经制定了一个明确的规则来编译 .c 文件,因为我无法在任何地方尝试使用隐式规则。还要感谢 al_miro 提供的 vpath 信息。
这是工作的 makfile:
.SUFFIXES:
.SUFFIXES: .c .o
CC=gcc
CPPFLAGS=-Wall
LDLIBS=-lhpdf
OBJDIR=obj
vpath %.c src
vpath %.h src
objects = $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
kushapes.o )
ku : $(objects)
$(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)
$(OBJDIR) obj/%.o : %.c ku.h kudefines.h kuglobals.h kufns.h
$(CC) -c $(CPPFLAGS) $< -o $@
.PHONY : clean
clean :
rm $(objects)
【问题讨论】:
-
样式说明:
$(CPPFLAGS)传统上用于 C 预处理器标志,而$(CFLAGS)用于编译器标志。