【问题标题】:Makefile with multiple files always builds everything具有多个文件的 Makefile 始终构建所有内容
【发布时间】:2017-08-02 23:42:05
【问题描述】:

我正在编写一个编译多个 C 文件的 Makefile,其中一些与 Makefile 位于同一目录中,而另一些则位于父目录中(出于历史原因必须在那里)。我想将所有 *.o 文件放在一个目录中(在我的情况下为 objdir)。这似乎可行,但由于某种原因,这个 Makefile 总是构建一切,即使没有任何改变。我的规则/依赖项哪里出错了?

更新:我已将我的 Makefile 和源代码精简到最低限度(请参阅下面的源文件内容。要清楚,这确实编译和链接。问题是它每次运行时都会进行编译和链接make,即使没有任何改变。这不是典型的 make 行为。

Makefile 内容:

CC = gcc
CFLAGS = -g -Wall -Werror -I..
SRCS = main.c ../a.c
OBJS = $(patsubst %.c, objdir/%.o, $(SRCS))
LN_OBJS = $(patsubst %.c, objdir/%.o, $(notdir $(SRCS)))
MAIN = foo

.PHONY: clean

default: objdir $(MAIN)
    @echo  Done

$(MAIN): $(OBJS) 
    $(CC) $(CFLAGS) -o $(MAIN) $(LN_OBJS    )

objdir/%.o: %.c
    $(CC) $(CFLAGS) -c $< -o objdir/$(notdir $@)

objdir:
    @mkdir -p objdir

clean:
    @$(RM) -rf objdir $(FDP) $(DK)

main.c 内容

#include "stdlib.h"
#include "stdio.h"

#include "a.h"

int main(int argc, char**argv)
{
    printf("Hello\n");
    a();
}

../a.c 内容

#include <stdio.h>

void a()
{
    printf("Hi from a\n");
}

../a.h 内容

#ifndef __a__
#define __a__

void a();

#endif

【问题讨论】:

  • 我无法重现您的错误。我建议您将您的 makefile 缩减为一个最小示例,并将其与您看到的输出一起发布。
  • 我用一个简化的例子更新了这个问题

标签: c makefile dependencies gnu-make


【解决方案1】:

您的 objdir/%.o: 规则扩展为 objdir/../a.o: ../a.c,但您随后创建 objdir/$(notdir $@),违反了 Rules of Makefiles 的规则 2。

解决此问题的一种方法是使用vpath(另请注意objdir 应该是对象的(仅顺序)依赖项):

SRCS = main.c a.c
vpath %.c ../
# [...]
objdir/%.o: %.c | objdir
    $(CC) $(CFLAGS) -c $< -o $@

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    相关资源
    最近更新 更多