1

我正在开发完全修补的 Solaris 11。我试图通过在 ISA 下转储预处理器宏来确定编译器是否支持 ISA。

由于Missing Separator. Missing Separator与 GNU make 的shell function一起使用时,我无法找到有关错误的信息。

这是简化的情况。没有空格,所以它不是像Make error: missing separator and friends 中那样的空格/制表符问题。

$ cat -n GNUmakefile-test
 1  EGREP ?= egrep
 2  SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: (Sun|Studio)")
 3
 4  # Begin SunCC
 5  ifeq ($(SUN_COMPILER),1)
 6  $(info "Sun compiler")
 7  $(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>/dev/null)
 8  ifeq ($(.SHELLSTATUS),0)
 9  $(info "SSSE3")
10  SSSE3_FLAG = -xarch=ssse3 -D__SSSE3__=1
11  endif
12  endif
13  # End SunCC
14
15  all:
16          $(info "Do nothing")

上面的想法是,SunCC 不为 ISA 提供宏,例如__AES____SHA__. 但是,如果不支持 ISA,SunCC 将出错,例如-xarch=sha在 SunCC 12.4 上。如果我没有收到错误,那么我知道编译器支持 ISA,就像-xarch=aes在 SunCC 12.4 上一样。如果有错误,我可以从.SHELLSTATUS. (SunCC 在这方面不像 Clang、GCC、Intel ICC 或 MSVC)。

结果如下:

$ CXX=/opt/solarisstudio12.4/bin/CC gmake -f GNUmakefile-test
"Sun compiler"
GNUmakefile-test:7: *** missing separator.  Stop.

缺少的分隔符在哪里?或者, make没有报告的真正错误是什么?也许还有别的?


鉴于之前被问过多少次,我很抱歉问这个问题。

我添加了标签以试图安抚make。它产生了同样的错误。

$ cat -n GNUmakefile-test
 1  EGREP ?= egrep
 2  SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: (Sun|Studio)")
 3
 4  # Begin SunCC
 5  ifeq ($(SUN_COMPILER),1)
 6       $(info "Sun compiler")
 7       $(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>/dev/null)
 8       ifeq ($(.SHELLSTATUS),0)
 9            $(info "SSSE3")
10            SSSE3_FLAG = -xarch=ssse3 -D__SSSE3__=1
11       endif
12  endif
13  # End SunCC
14
15  all:
16       $(info "Do nothing")
4

2 回答 2

5

shell函数的工作方式(如手册中所述)是它运行命令,然后扩展为命令的输出。这就是为什么,当你看到:

SUN_COMPILER := $(shell $(CXX) -V 2>&1 | $(EGREP) -i -c "CC: (Sun|Studio)")

该变量SUN_COMPILER设置为该 shell 命令的输出。

所以当你写这个时:

$(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>/dev/null)

运行命令,然后替换输出。之后,make 尝试将结果解析为 make 语法。但是该命令的输出显然不是 make 语法,因此您会收到此错误。

如果您不关心输出而只关心退出代码,则需要丢弃输出:

$(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null >/dev/null 2>&1)

或者将其分配给虚拟变量:

_x := $(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>/dev/null)

这样 make 将结果分配给一个变量,而不是认为它是 make 语法。

于 2017-08-24T18:10:55.373 回答
1

我们决定避免.SHELLSTATUS,因为它似乎有一些问题。我们倒退到grep和弦"illegal value ignored"上。

ifeq ($(SUN_COMPILER),1)
  COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=ssse3 -xdumpmacros /dev/null 2>&1 | $(EGREP) -i -c "illegal value ignored")
  ifeq ($(COUNT),0)
    SSSE3_FLAG = -xarch=ssse3 -D__SSSE3__=1
    ARIA_FLAG = -xarch=ssse3 -D__SSSE3__=1
  endif
  COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=sse4_2 -xdumpmacros /dev/null 2>&1 | $(EGREP) -i -c "illegal value ignored")
  ifeq ($(COUNT),0)
    BLAKE2_FLAG = -xarch=sse4_2 -D__SSE4_2__=1
    CRC_FLAG = -xarch=sse4_2 -D__SSE4_2__=1
  endif
  COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=aes -xdumpmacros /dev/null 2>&1 | $(EGREP) -i -c "illegal value ignored")
  ifeq ($(COUNT),0)
    GCM_FLAG = -xarch=aes -D__PCLMUL__=1
    AES_FLAG = -xarch=aes -D__AES__=1
  endif
  COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=sha -xdumpmacros /dev/null 2>&1 | $(EGREP) -i -c "illegal value ignored")
  ifeq ($(COUNT),0)
    SHA_FLAG = -xarch=sha -D__SHA__=1
  endif
endif
# End SunCC

我们不确定-xarch=sha。目前,我们正试图弄清楚需要什么。

于 2017-08-24T23:24:56.690 回答