检查Makefile中的gcc版本?

时间:2011-03-04 00:19:45

标签: gcc makefile version portability compiler-warnings

我想使用一些旧的gcc版本中没有的gcc警告开关(例如-Wtype-limits)。

有没有一种简单的方法可以检查gcc版本,只有在使用最新的gcc时才添加这些额外的选项?

8 个答案:

答案 0 :(得分:45)

我不会说它很简单,但您可以使用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

答案 1 :(得分:15)

将完整的3部分gcc版本(不仅是第一个数字)转换为数字格式,适合比较(例如40701)使用

gcc -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输出中缺少版本的第3部分的可能性(在某些早期的gcc版本中就是这种情况)。

所以要测试makefile中的版本,请使用类似(上一个sed命令中的注释$$

GCC_GTEQ_472 := $(shell expr `gcc -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

答案 2 :(得分:7)

我刚遇到这个问题,我需要测试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 4.9之后发布gcc 4.10,那么需要一些sed hacking,但这仍然是可读的:

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

答案 3 :(得分:2)

您使用的是autoconf吗?

在启用了标志的情况下通过gcc调用'dummy'编译可能是值得的,如果由于编译器无法识别该标志而导致失败,则可以回退到不使用较新警告的命令行选项。

答案 4 :(得分:2)

基于上面的答案,我已经制作了一个即用型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或任何合适的

希望有所帮助。

答案 5 :(得分:1)

跟随克里斯,但使用awk

GCC_VER_GTE44 := $(shell expr $$(gcc -dumpversion | awk -F. '{print $$3+100*($$2+100*$$1)}') \>= 40400)

注释$需要与另一个$一起在Makefile中转义。

答案 6 :(得分:1)

我发现了这一点,并认为它确实很聪明。它使用更少的shell调用来实现>,> =,<和<=:

GCC_VERSION := $(shell gcc -dumpversion)
VERSION := 7.4.0

ifeq ($(VERSION),$(firstword $(sort $(GCC_VERSION) $(VERSION))))
    # stuff that requires GCC_VERSION >= VERSION
endif

此示例显示> =。您可以使用ifneq和$(lastword)的组合来实现>,<=或<。

参考:

https://lists.gnu.org/archive/html/help-make/2006-04/msg00065.html

答案 7 :(得分:0)

有时您希望显示带有额外信息的版本。

GCCVER=$(gcc --version | awk '/gcc /{print $0;exit 0;}')
echo $GCCVER

gcc(Ubuntu 4.8.1-2ubuntu1~12.04)4.8.1