特定于目标的变量是否有条件地设置变量?

时间:2017-07-29 20:02:08

标签: makefile gnu-make

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

  

make中的变量值通常是全局的;也就是说,它们是一样的   无论他们在哪里被评估......一个例外是   自动变量(参见自动变量)。

     

另一个例外是特定于目标的变量值。此功能   允许您根据相应变量定义不同的值   目前建立的目标。和自动一样   变量,这些值仅在a的上下文中可用   目标的配方(以及其他特定于目标的分配)。

     

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

target … : variable-assignment
     

多个目标值为其创建特定于目标的变量值   目标列表中的每个成员。

     

...

     

目标特定变量还有一个特殊功能:何时   您定义了一个特定于目标的变量,变量值也在其中   影响该目标的所有先决条件及其所有先决条件   先决条件等(除非这些先决条件覆盖该变量   用他们自己的特定目标变量值)。所以,例如,a   声明如下:

prog : CFLAGS = -g
prog : prog.o foo.o bar.o
     

...

在上面的GNU Make示例的上下文中,我需要类似的东西:

使用SSE4.2的英特尔机器

crc-simd.o: CRC_FLAG = -msse4.2
crc-simd.o:
    $(CXX) $(CXXFLAGS) $(CRC_FLAG) -c $<

带CRC32的ARMv8a计算机

crc-simd.o: CRC_FLAG = -march=armv8-a+crc
crc-simd.o:
    $(CXX) $(CXXFLAGS) $(CRC_FLAG) -c $<

我认为Define make variable at rule execution time可能是相关的,但细节对我来说仍然模糊不清。我不确定它是否是关键或只是另一种选择。

特定于目标的变量是否有条件地设置CRC_FLAG变量?如果是,那么我们如何使用它来有条件地设置变量?

如果没有,那么只有在需要构建CRC_FLAG时才能为crc-simd.o分配值吗?如果有,那我们该怎么做呢?

这是我们的GNUmakefile包含的内容。虽然显示了ARMv8a,但x86 / x32 / x64类似。我们对SSE4.2,NEON,AES,SHA,CLMUL,AVX和BMI做了类似的工作。

测试编译后,MIPS上的CRC_FLAG为空,SSE4.2可用时为-msse4.2,ARMv8a为-march=armv8-a+crc。问题是,它使像make clean这样的食谱需要花费太多时间来运行。即使构建一个脏对象文件也会引发所有编译的完全愤怒。滞后是显而易见的。

TEMPDIR ?= /tmp
EGREP ?= egrep

IS_ARMV8 ?= $(shell uname -m | $(EGREP) -i -c 'aarch32|aarch64')
...

ifeq ($(IS_ARMV8),1)
  HAS_CRC := $(shell $(CXX) $(CXXFLAGS) -march=armv8-a+crc -o $(TEMPDIR)/t.o -c crc-simd.cpp; echo $$?)
  ifeq ($(HAS_CRC),0)
    CRC_FLAG := -march=armv8-a+crc
  endif
endif
...

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

1 个答案:

答案 0 :(得分:1)

如果您只需要{。1}}这样的单个.o文件的此标记,那么为什么在crc-simd.o的分配中使用:=?如果您使用CRC_FLAG代替它,那么在它被使用之前它不会被展开,如果您只使用它一次它将只展开一次。

类似的东西:

=

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