makefile - 如何将目标文件放置在单独的子目录中

标签 makefile gnu-make

我在尝试使用 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)

最佳答案

由于您使用的是 GNUmake,因此请使用模式规则来编译目标文件:

$(OBJDIR)/%.o: %.c
    $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<

关于makefile - 如何将目标文件放置在单独的子目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5178125/

相关文章:

c - make 找不到 sys/signal.h

c++ - cmake os x 失败 ar 没有特定的存档成员

c++ - c++ 源代码的递归生成文件

makefile - 如何为同一目标文件的不同依赖项集运行不同的配方

makefile - 如何使用文件列表执行 Makefile 模式规则

linux - 如何在Makefile中测试CFLAGS中是否加入了某个符号?

go - 如何在文件更改时自动执行 make 目标?

bash - 许多Shell命令架构

c++ - 多个子目录的 Makefile 模式规则

makefile - 在规则执行时定义 make 变量