我想使用一些在旧版gcc中不可用的gcc警告开关(例如-Wtype-limits)。
有没有一种简单的方法来检查gcc版本并仅在使用较新版gcc时添加这些额外选项?
我想使用一些在旧版gcc中不可用的gcc警告开关(例如-Wtype-limits)。
有没有一种简单的方法来检查gcc版本并仅在使用较新版gcc时添加这些额外选项?
我不会说这很容易,但你可以使用GNU make的shell
函数执行像gcc --version
这样的 shell 命令,然后使用ifeq
条件表达式检查版本号并适当地设置你的CFLAGS
变量。
以下是一个快速示例makefile:
CC = gcc
GCCVERSION = $(shell gcc --version | grep ^gcc | sed 's/^.* //g')
CFLAGS = -g
ifeq "$(GCCVERSION)" "4.4.3"
CFLAGS += -Wtype-limits
endif
all:
$(CC) $(CFLAGS) prog.c -o prog
编辑:没有ifgt
命令。不过,你可以使用shell中的expr
命令进行大于比较。下面是一个例子
CC = gcc
GCCVERSIONGTEQ4 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 4)
CFLAGS = -g
ifeq "$(GCCVERSIONGTEQ4)" "1"
CFLAGS += -Wtype-limits
endif
all:
$(CC) $(CFLAGS) prog.c -o prog
:=
代替=
,否则每次扩展$(GCCVERSION)
时都会运行$(shell)
。 - Jack KellyGCCVERS := $(shell gcc --version | grep ^gcc | awk '{print $$3}')
。 - Paul Rooney40701
),请使用:gcc -dumpfullversion -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$/&00/'
这涉及到版本号中任何一部分出现两位数的可能性,以及在gcc -dumpversion
输出中缺少第三部分版本号的情况(在某些早期的gcc版本中存在此情况)。
因此,要在makefile中测试版本号,请使用类似以下命令(请注意最后一个sed命令中的$$
):
GCC_GTEQ_472 := $(shell expr `gcc -dumpfullversion -dumpversion | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/'` \>= 40702)
ifeq "$(GCC_GTEQ_472)" "1"
...
endif
我遇到了这个问题,需要测试gcc的前两位数字,并希望有一个比上面巧妙的sed hackery更易读的选项。我使用了bc进行比较,因为它支持浮点数(expr将非整数视为字符串):
GCC_VER_GTE44 := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | bc )
ifeq ($(GCC_VER_GTE44),1)
...
endif
GCC_VER_GTE44 := $(shell echo `gcc -dumpversion | cut -f1-2 -d.` \>= 4.4 | sed -e 's/\./*100+/g' | bc )
ifeq ($(GCC_VER_GTE44),1)
...
endif
我发现这个方法非常聪明,可以用更少的Shell调用实现>、>=、<和<=:
GCC_VERSION := $(shell gcc -dumpversion)
VERSION := 7.4.0
ifeq ($(VERSION),$(firstword $(sort $(GCC_VERSION) $(VERSION))))
# stuff that requires GCC_VERSION >= VERSION
endif
https://lists.gnu.org/archive/html/help-make/2006-04/msg00065.html
sort -n
可能会解决这个问题。 - Charlie Reitzel我已经准备好了一个可直接使用的IF_GCC宏,基于以上答案:
MY_GCC_VERSION=$(if $(GCC_VERSION),$(GCC_VERSION),$(GCC_DEFAULT_VER))
MY_GCC_TOINT=$(shell echo $(1) | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$//')
MY_IF_GCC=$(if $(shell test $(call MY_GCC_TOINT, $(MY_GCC_VERSION)) -$(1) $(2) || echo 0),$(4),$(3))
GCC_DEFAULT_VER:=$(firstword $(shell cc -V 2>&1 | grep default | sed -r 's/( *)([0-9.]+),(.*)/\2/g'))
用法: $(call MY_IF_GCC,ge,30305,-fan_option_for_gcc_ge_3.3.5)
作为第二个参数,您可以使用test(1)支持的任何运算符:eq、gt、lt、ge、le等。
如果cc -V对您不起作用,请将其替换为gcc -dumpversion或适当的命令。
希望这有所帮助。
GCC_VER_GTE44 := $(shell expr $$(gcc -dumpversion | awk -F. '{print $$3+100*($$2+100*$$1)}') \>= 40400)
注意:在Makefile中,$
需要用另一个$
进行转义。
最初的回答:
请注意,在Makefile中,要使用两个美元符号$$
来转义$
。
你是否使用类似于autoconf的工具?
值得尝试的是使用gcc调用一次“虚假”的编译,并启用该标志,如果该编译因为编译器不识别该标志而失败,则可以回退到不使用较新警告选项的命令行。
我认为awk
是更好的工具,因为它可以将版本字符串分割成$1
、$2
和$3
,然后在一个命令中使用>
、<
、>=
等进行比较。如果表达式为假,则整行从awk
输出中省略。
GCC_VERSION_GT_75 = $(shell gcc -dumpfullversion -dumpversion | awk -F. '$$1 > 7 && $$2 > 5')
ifneq ($(GCC_VERSION_GT_75),)
# stuff that requires gcc version > 7.5
endif
gcc --version
有什么问题吗? - rlibby