gcc-../(点斜杠)在Makefile中的变量中是什么意思?

时间:2018-09-19 21:36:42

标签: gcc makefile

我已经搜寻了几个小时以寻求答案。我是gcc和Makefile的新手。

我的一些源代码中包含一个Makefile,如下所示:

CC=gcc
SRCDIR=src
BINDIR=../bin
CFLAGS= -flag
LIBS= -lthing
...
$(BINDIR)/program_name: $(SRCDIR)/program_name.c
    $(CC) $(CFLAGS) $(SRCDIR)/program_name.c -o $(BINDIR)/program_name $(LIBS)

除了BINDIR中的../是要做什么的以外,我理解所有这些都是什么意思。制作Makefile时,出现错误消息:

/usr/bin/ld: cannot open output file ../bin/program_name: No such file or directory
collect2: error: ld returned 1 exit status
Makefile:20: recipe for target '../bin/program_name' failed
make: *** [../bin/program_name] Error 1

我的猜测是该Makefile的原始作者意味着bin文件夹应该放在Makefile所在的父目录中。我知道在使用Linux CLI命令cd时,点号表示进入目录。这就是要达到的目的吗?

2 个答案:

答案 0 :(得分:1)

您的makefile缺少创建BINDIR目录的规则-如果该目录不存在,则您的链接行将无法在其中放置生成的二进制文件!像这样的规则应该做到这一点:

$(BINDIR): 
    mkdir -p $(BINDIR)

只需确保其他任何规则(例如您的问题中的一个)也依赖于此目录!

答案 1 :(得分:1)

要在实际需要之前自动创建$(BINDIR)目录,必须将其声明为使用该目录的任何目标的先决条件(依赖项)。但是,每次其内容更改时,其时间戳也会更改。因此,将其声明为常规先决条件不是最好的选择,因为依赖于它的目标将在没有真正原因的情况下重新构建,仅因为$(BINDIR)的内容已更改。< / p>

这就是为什么make也支持order-only prerequisites(OOP):

$(BINDIR)/program_name: $(SRCDIR)/program_name.c | $(BINDIR)
    $(CC) $(CFLAGS) $< -o $@ $(LIBS)

$(BINDIR):
    mkdir -p $@

请注意介绍OOP列表的|。如果不存在,则会构建一个OOP,这也会导致依赖于它的目标也被(重新构建)。但是,如果存在,make甚至不会考虑其最后修改时间。即使某些依赖它的目标较旧,也不能因此而重建它。

注意:我还使用了$<$@ automatic variables。在规则的配方中,它们分别扩展为第一个先决条件($(SRCDIR)/program_name.c)和目标($(BINDIR)/program_name)。强烈建议使用它们:键入少,错误少,规则更通用……它们具有许多良好的属性。