make如何推断最终目标需要什么样的编译器

how can the make infer what kind of compiler it needs for the final target?

本文关键字:什么样 编译器 目标 何推断 make      更新时间:2023-10-16

这里有一个简单的makefile。这是一个最低限度的c++项目,我希望make使用隐式规则进行正确的行为。使用以下makefile,它将报告错误。然后我键入"make-n",看起来make使用的是cc而不是cxx。但当我查看GNU页面时,它说CXX是一个隐式变量:https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html

我可以说最后的目标是什么。隐含的工具总是cc?

objects = test.o main.o
CXX=g++
CFLAGS=-std=c++11
test: $(objects)
.PHONY: clean
clean:
rm -f *.o test

您的对象文件很可能是使用Make的默认链接器$(CC)链接的。我们可以看到,如果我们看看make --print-data-base -f /dev/null的输出,特别是:

%: %.o
#  recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

如果我们看看LINK.o的定义,我们会看到:

# default
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

幸运的是,Make提供LINK.cc正是为了我们的目的:

# default
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

所以我们所需要做的就是将LINK.o重新定义为LINK.cc的值,并且链接将由我们的C++编译器完成:

LINK.o = $(LINK.cc)

如果我们有几个目标,以不同的方式联系起来,我们可能会使用一个目标相关变量来定位效果:

test: LINK.o = $(LINK.cc)

makefile上的其他注释:

  • test对程序来说是个糟糕的名字——很容易错误地运行标准的/usr/bin/test
  • 你可能是指CXXFLAGS=-std=c++11(而不是CFLAGS)
  • 所有makefile都应该包含一个.DELETE_ON_ERROR:目标,这样被中断的命令就不会留下最新的部分输出