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

时间:2019-04-30 20:55:42

标签: c gcc makefile gnu-make

我很新。到目前为止,我已经设法使用一些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

2 个答案:

答案 0 :(得分:0)

每当您看到一条规则,其中所生成的输出不会发送到文件$@时,您就会知道这是不正确的。 Make会将$@自动变量设置为期望创建的文件名,如果配方做不同的操作,则makefile将不起作用。

您的规则将文件发送到$(OBJDIR)/$@,而不是$@,因此不正确。

因此,您需要这样编写模式规则:

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

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

答案 1 :(得分: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将其输出到单独的目录中。