【问题标题】:Having trouble placing object files in a new directory using makefile使用 makefile 将目标文件放置在新目录中时遇到问题
【发布时间】:2019-04-30 20:55:42
【问题描述】:

我对制作非常陌生。到目前为止,我已经设法使用在线找到的一些 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


    【解决方案1】:

    任何时候您看到生成的输出没有转到文件$@ 的规则时,您就知道这是不对的。 Make 会将$@ 自动变量设置为它期望创建的文件名,如果配方做了不同的事情,makefile 将不起作用。

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      有两个部分可以明确地做到这一点。

      • 首先,也是最基本的一点,如果您希望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 将输出输出到单独的目录中。

      【讨论】:

      • 感谢您的回答,但这仍然不起作用。我收到以下错误:“*** 没有制定目标的规则。”我根据您的建议修改了我的代码。
      猜你喜欢
      • 2019-04-04
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2011-05-05
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多