使用makefile将目标文件放在新目录中时遇到问题

问题描述 投票:1回答:2

我很擅长制作。到目前为止,我已经设法使用在线发现的一些GNU手册和教程创建了以下内容。我想让make将所有创建的目标文件放入目录'obj'中。我已经能够成功创建这个目录,但我无法弄清楚如何将文件放入其中。任何建议或提示表示赞赏。另外,总的来说,除了GNU文档之外,还有一个学习如何使用make的好资源吗?

# specify compiler
CC          := gcc
# set compiler flags
CFLAGS      := -M -Igen/display -Igen/logic -Iman -Ilib/include -pipe -march=native -ftime-report
# set linker flags
LDFLAGS     := -lglut32 -loglx -lopengl32 -Llib
# specify separate directory for objects
OBJDIR      := obj
# include all sources
SOURCES     := $(wildcard gen/display/*.c gen/logic/*.c man/*.c)
# create objects from the source files
OBJECTS     := $(patsubst %.c,%.o,$(SOURCES)) 
# specify the name and the output directory of executable
EXECUTABLE  := win32/demo

# all isn't a real file
all: $(EXECUTABLE)

# compile
%.o: %.c
    @mkdir -p $(@D)
    $(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$@   

# link
$(EXECUTABLE): $(OBJECTS)
    $(CC) $^ $(LDFLAGS) -o $@

# clean objects
clean:
    @$(RM) -rf $(OBJDIR)

.PHONY: all clean
c gcc makefile gnu-make
2个回答
0
投票

任何时候你看到一个规则,其中生成的输出没有转到文件$@,你知道它是不对的。 Make会将$@自动变量设置为它希望创建的文件名,如果配方执行不同的操作,makefile将不起作用。

你的规则将文件发送到$(OBJDIR)/$@,而不是$@,所以它不对。

所以,你需要像这样写你的模式规则:

%.o: %.c
        @mkdir -p $(@D)
        $(CC) $(CFLAGS) -c $< -o $@

如果这不起作用,您需要提供更多信息,例如编译行调用的示例,您看到的错误等。


0
投票

我已经能够成功创建这个目录,但我无法弄清楚如何将文件放入其中。

有两个部分要写明确地这样做。

  • 首先,最基本的是,如果你想要make创建一个文件,你必须给它一个规则。你确实有一个模式规则原则上可以产生这种效果...... %.o: %.c # ... ...但实际上,该规则永远不能与obj/目录中的文件匹配,因为您的源不在该目录中。这可能更有效: $(OBJDIR)/%.o: %.c @mkdir -p $(@D) $(CC) $(CFLAGS) -c $< -o $@ 特别注意规则的目标现在如何匹配该规则实际产生的工件。
  • 其次,您必须要求构建规则的目标,通常是将其作为其他规则的依赖关系。请注意,定义对$(EXECUTABLE)有贡献的对象文件的变量不依赖于obj/目录中的对象。它是由这种模式替换产生的...... OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) ...生成与相应源具有相同路径的对象名称。你可能想要更像这样的东西: OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(SOURCES)) 您将注意到这也与前一点中显示的更改相对应。

但是,这是一项很少收获的工作。你不必在没有它的情况下修改你的clean目标。您可以用更简单和更传统的形式编写文件,并通过利用the VPATH feature of GNU (and some other) make将输出输出到单独的目录中。

© www.soinside.com 2019 - 2024. All rights reserved.