Makefile 目标特定变量是否是有条件设置变量的合适工具?

Makefile 目标特定变量是否是有条件设置变量的合适工具?,makefile,gnu-make,Makefile,Gnu Make,我正在处理下面描述的问题。在研究时,第6.11节说: make中的变量值通常是全局的;也就是说,它们是相同的 不管他们在哪里被评估。。。一个例外是 自动变量参见自动变量 另一个例外是特定于目标的变量值。此功能 允许您根据以下内容为同一变量定义不同的值: 生成的目标当前正在生成。就像自动驾驶一样 变量,这些值仅在 目标的配方和其他特定于目标的作业 设置特定于目标的变量值,如下所示: target … : variable-assignment prog : CFLAGS = -g prog :

我正在处理下面描述的问题。在研究时,第6.11节说:

make中的变量值通常是全局的;也就是说,它们是相同的 不管他们在哪里被评估。。。一个例外是 自动变量参见自动变量

另一个例外是特定于目标的变量值。此功能 允许您根据以下内容为同一变量定义不同的值: 生成的目标当前正在生成。就像自动驾驶一样 变量,这些值仅在 目标的配方和其他特定于目标的作业

设置特定于目标的变量值,如下所示:

target … : variable-assignment
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
多个目标值为创建特定于目标的变量值 目标列表中的每个成员都是单独的

目标特定变量还有一个特殊特性:何时 您定义了一个特定于目标的变量,该变量的值也在其中 此目标的所有先决条件及其所有 先决条件等,除非这些先决条件覆盖该变量 具有自己的目标特定变量值。例如,一个 声明如下:

target … : variable-assignment
prog : CFLAGS = -g
prog : prog.o foo.o bar.o

在上面的GNU Make示例中,我需要如下内容:

ifeq ($(IS_ARMV8),1)
  CRC_FLAG = $(shell $(CXX) $(CXXFLAGS) -march=armv8-a+crc -o $(TEMPDIR)/t.o -c crc-simd.cpp 2>/dev/null && printf %s -march=armv8-a+crc)
endif

# SSE4.2 or ARMv8a available
crc-simd.o : crc-simd.cpp
        $(CXX) $(strip $(CXXFLAGS) $(CRC_FLAG) -c) $<
带SSE4.2的英特尔计算机:


如果您只需要为单个.o文件(如crc simd.o)使用此标志,那么为什么在crc_标志的赋值中使用:=呢?如果改为使用=则在使用之前不会展开,如果只使用一次,则只展开一次

比如:

ifeq ($(IS_ARMV8),1)
  CRC_FLAG = $(shell $(CXX) $(CXXFLAGS) -march=armv8-a+crc -o $(TEMPDIR)/t.o -c crc-simd.cpp 2>/dev/null && printf %s -march=armv8-a+crc)
endif

# SSE4.2 or ARMv8a available
crc-simd.o : crc-simd.cpp
        $(CXX) $(strip $(CXXFLAGS) $(CRC_FLAG) -c) $<

这仍然会编译文件两次;似乎应该有一种更快的方法来确定该标志是否受支持,但无论如何。

您似乎已经回答了最初的问题,现在您的问题似乎应该是如何停止重建所有内容,但您尚未提供完整的示例。谢谢@user657267。我该如何停止重建所有的东西——实际上需要更多的规则来避免构建所有的东西。因此,我试图对CRC_旗进行外科手术。抱歉搞混了。我不知道你说的什么会引起所有编译人员的愤怒。所有这些都是什么?你的意思是,HAS_CRC:=$shell$CXX。。。编译?我不明白为什么他们都会跑;不只是为这个特殊值编译的一个是uu。。。run?@MadScientist-如果我需要构建foo.o和bar.o,它们会导致HAS_CRC齿轮运行,因为我不知道如何说,在构建CRC-simd.o时,只计算HAS_CRC,只设置CRC_标志变量的值。好的,但它只在每次调用make时运行一次,并且其中只有一个运行,对吗?所以,基本上每次调用make都需要额外编译一次,对吗?我知道这可能很烦人,但我试图理解你的评论引起了所有编译的愤怒。似乎应该有一种更快的方法来确定是否支持该标志,但无论如何…-哈哈,是的,我知道你的意思。问题主要是武装目标。GCC和Clang在本机构建时非常出色。它们的行为就像AARC64上的ARMv6,只是它们为AARC64生成代码。否则,GCC不会做任何广告。例如,请参见,因此,gcc-march=armv8-a-target帮助的输出在crc扩展可用时和不可用时均不显示该扩展名?谢谢@madsciphest。我没有看到任何有趣的东西。没有像crc、aes、sha、pmull、asimd这样的点击。这是Pastebin,如果有兴趣的话:。我相信您回答了这个问题:如果没有,那么只有在需要构建CRC simd.o时,才有方法为CRC_标志赋值吗?如果有,那我们怎么做?你回答的对吗?这就是我回答的问题,是的。如果使用递归变量赋值,则在定义变量时,值不会展开;相反,当使用变量时,它会展开。如果变量在crc simd.o目标的配方中只使用了一次,那么它将仅在构建该目标时扩展。