C 非递归Makefile编译问题

C 非递归Makefile编译问题,c,makefile,gnu-make,C,Makefile,Gnu Make,在阅读了Emile van Bergen关于非递归makefile的文章之后,我试图从递归转换到非递归,但似乎我没有正确地理解它 更新:我终于弄对了 这些文件是: $ ls -R .: folder1 Makefile test.c topRules.mk ./folder1: file.c Rules.mk 测试c 生成文件 topRules.mk folder1/file.c 在包含folder1/Rules.mk之前,应该如何设置$(sp)和$(d) 您尚未设置它们,因

在阅读了Emile van Bergen关于非递归makefile的文章之后,我试图从递归转换到非递归,但似乎我没有正确地理解它

更新:我终于弄对了

这些文件是:

$ ls -R
.:
folder1  Makefile  test.c  topRules.mk

./folder1:
file.c  Rules.mk

测试c
生成文件
topRules.mk
folder1/file.c 在包含
folder1/Rules.mk
之前,应该如何设置
$(sp)
$(d)

您尚未设置它们,因此它们是空的

替换
$(OBJS_$(d):%%=%.c))
可能也没有达到您想要的效果

尝试添加一些
$(信息当前d值为$(d))
行,以显示变量的设置

另外,
main()
应该返回
int
而不是
void

  • 从对象列表生成源列表的替换错误。它不是剥离
    .o
    扩展名:

     SRC_$(d) := $(OBJS_$(d):%.o=%.c))
                              ^^
    
    完全删除这个变量,你就不需要它了

  • $(OBJS_$(d)):$(SRC_$(d))
    规则既多余又错误:

  • 这是多余的,因为
    %.o:%.c
    模式规则适用并且做正确的事情
  • 这是错误的,因为它创建了一个规则来执行所有编译,但您需要分别编译每个源。例如,当您有两个文件时,它将扩展为:

    foo.o bar.o : foo.c bar.c
    
    但你需要两条独立的规则

  • 完全删除该规则,不要添加任何其他规则。正确的规则就在那里


    实际上,这个错误是由于这两个规则相互作用不好造成的"如果规则从隐式规则中获得命令,
    $您必须说明正在发生的事情和预期会发生的事情。否则,您就不清楚需要什么。我只是尝试编译两个不同目录中的文件,并使用非递归的makefile方法。这并不能真正澄清任何事情。要说明我“发生”意味着提供一个shell会话的完整准确的转录本。并具体描述它的错误。如果你没有什么要执行的,你需要对它做更多的工作,并可能询问你不知道如何将特定的东西放入makefile中。我的makefile中似乎有一个问题,特别是在folder1中文件已编译并链接到top folder test.o。它目前不起作用。请查看Makefile topRules.mk folder1/Rules.mk我缺少的是什么。topRules.mk的内容实际上是两个文件和一个shell命令的内容,我假设shell命令之前的所有内容都是o的一部分ther.mk文件?我的答案仍然适用,你没有设置你使用的变量,你的替换是错误的。我只是使用了文章中的makefile和rules.mk,顶层makefile中没有设置sp和d。我甚至下载了OpenRadius 0.9.5,它也没有设置。顺便说一句,对于当前的文件,我得到了这个错误,请使用cc-o folder1/file.o-c cc:致命错误:未终止任何输入文件编译。make:**[folder1/file.o]错误4got它。现在我已经非常简化了它。但是得到了相同的错误。更新了question@mSO:不,您没有。我将明确表示,我希望您完全删除不正确的规则,而不添加任何内容。@mSO:我已扩展了对第2点的解释。删除
    $(OBJS_$(d)):$((SRC_$(d))
    rule from
    folder1/Rules.mk
    ,不要在其中添加任何新内容。明白了。更新了makefile和Rules.mk。folder1正在编译,但test.o没有生成,因此认为。o rule应该应用于it@mSO:您尚未处理我的第三点。您运行的目标错误。请请求
    target.exe
    显式地(运行
    make target.exe
    而不是只运行
    make
    )或重新排列目标,以便在处理
    Makefile
    时遇到的第一个目标是生成
    target.exe
    的目标。
    COMPILE = $(CC) $(CFLAGS) -o $@ -c $<
    LINK = $(CC)  -o $@ $^ 
    
    %.o:    %.c
        $(COMPILE)  
    
    sp := $(sp).x
    dirstack_$(sp) := $(d)
    d := $(dir)
    
    OBJS_$(d) := $(d)/file.o
    $(d): $(OBJS_$(d))
    
    void sub_print()
    {
        printf("Hello Sub World\r\n");
    }
    
     SRC_$(d) := $(OBJS_$(d):%.o=%.c))
                              ^^
    
    foo.o bar.o : foo.c bar.c
    
    $(OBJS_$(d)): %.o: %.c
        specific-command
    
    $(OBJS_$(d)): %.o: CFLAGS=specific-cflags