在Makefile中检查gcc版本?

时间:2022-06-26 20:08:15

I would like to use some gcc warning switchs that aren't available in older gcc versions (eg. -Wtype-limits).

我想使用一些gcc的警告开关,这些在旧的gcc版本中是不可用的。-Wtype-limits)。

Is there an easy way to check the gcc version and only add those extra options if a recent gcc is used ?

是否有一种简单的方法来检查gcc版本,只在最近使用gcc时才添加这些额外选项?

6 个解决方案

#1


39  

I wouldn't say its easy, but you can use the shell function of GNU make to execute a shell command like gcc --version and then use the ifeq conditional expression to check the version number and set your CFLAGS variable appropriately.

我不会说它很简单,但是您可以使用GNU的shell函数来执行shell命令,比如gcc—版本,然后使用ifeq条件表达式来检查版本号,并适当地设置CFLAGS变量。

Here's a quick example makefile:

这里有一个快速示例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

Edit: There is no ifgt. However, you can use the shell expr command to do a greater than comparison. Here's an example

编辑:没有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

#2


13  

To transform full 3-part gcc version (not only first digit) into numerical format, suitable for comparison (e.g. 40701) use

将完整的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/'

Which addresses the possibility of double-digit numbers in any of the version part, and possibility of missing 3-rd part of the version in output of gcc -dumpversion (which is the case in some earlier gcc versions).

它解决了在版本部分中出现两位数数字的可能性,以及在gcc -dumpversion的输出中丢失3-rd部分的可能性(在一些早期的gcc版本中是这样)。

So to test the version in makefile, use something like (note $$ inside last sed command)

因此,要在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

#3


5  

I just encountered this problem where I needed to test the first two digits of gcc and wanted a more readable option than the clever sed hackery above. I used bc to do the comparison since it supports floating point (expr treats non-integers as strings):

我刚刚遇到了这个问题,我需要测试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

If they release gcc 4.10 after gcc 4.9, then a bit of sed hacking is necessary, but this is still pretty readable:

如果他们在gcc 4.9之后释放gcc 4.10,那么就有必要进行一些sed黑客攻击,但这仍然是相当可读的:

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

#4


2  

Are you using something like autoconf?

你在使用autoconf之类的东西吗?

It might be worth invoking a 'dummy' compile via gcc with the flag enabled and if that one fails because the compiler doesn't recognise the flag, you can fall back to the command line that doesn't use the newer warning options.

它可能值得调用一个“虚拟”编译通过gcc来编译,如果这个失败了,因为编译器没有识别标记,那么您可以返回到不使用新的警告选项的命令行。

#5


1  

I've made a ready-to-use IF_GCC macro, based on the answers above:

根据上面的答案,我已经创建了一个现成的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')) 

Usage: $(call MY_IF_GCC,ge,30305,-fan_option_for_gcc_ge_3.3.5)

用法:$(-fan_option_for_gcc_ge_3.3.5叫MY_IF_GCC,通用电气,30305)

As the second argument, you can use any operator of those supported by test(1): eq, gt, lt, ge, le etc.

作为第二个参数,可以使用test(1)所支持的任何操作符:eq、gt、lt、ge、le等。

If cc -V doesn't work for you, replace it with gcc -dumpversion or whatever suitable

如果cc -V不适合你,用gcc -dumpversion替换它或者其他合适的。

Hope that helps.

希望有帮助。

#6


0  

Sometimes you want to display the version with the extra info.

有时您想要显示带有额外信息的版本。

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

gcc (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1

gcc 4.8.1(Ubuntu 4.8.1-2ubuntu1 ~ 12.04)

#1


39  

I wouldn't say its easy, but you can use the shell function of GNU make to execute a shell command like gcc --version and then use the ifeq conditional expression to check the version number and set your CFLAGS variable appropriately.

我不会说它很简单,但是您可以使用GNU的shell函数来执行shell命令,比如gcc—版本,然后使用ifeq条件表达式来检查版本号,并适当地设置CFLAGS变量。

Here's a quick example makefile:

这里有一个快速示例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

Edit: There is no ifgt. However, you can use the shell expr command to do a greater than comparison. Here's an example

编辑:没有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

#2


13  

To transform full 3-part gcc version (not only first digit) into numerical format, suitable for comparison (e.g. 40701) use

将完整的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/'

Which addresses the possibility of double-digit numbers in any of the version part, and possibility of missing 3-rd part of the version in output of gcc -dumpversion (which is the case in some earlier gcc versions).

它解决了在版本部分中出现两位数数字的可能性,以及在gcc -dumpversion的输出中丢失3-rd部分的可能性(在一些早期的gcc版本中是这样)。

So to test the version in makefile, use something like (note $$ inside last sed command)

因此,要在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

#3


5  

I just encountered this problem where I needed to test the first two digits of gcc and wanted a more readable option than the clever sed hackery above. I used bc to do the comparison since it supports floating point (expr treats non-integers as strings):

我刚刚遇到了这个问题,我需要测试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

If they release gcc 4.10 after gcc 4.9, then a bit of sed hacking is necessary, but this is still pretty readable:

如果他们在gcc 4.9之后释放gcc 4.10,那么就有必要进行一些sed黑客攻击,但这仍然是相当可读的:

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

#4


2  

Are you using something like autoconf?

你在使用autoconf之类的东西吗?

It might be worth invoking a 'dummy' compile via gcc with the flag enabled and if that one fails because the compiler doesn't recognise the flag, you can fall back to the command line that doesn't use the newer warning options.

它可能值得调用一个“虚拟”编译通过gcc来编译,如果这个失败了,因为编译器没有识别标记,那么您可以返回到不使用新的警告选项的命令行。

#5


1  

I've made a ready-to-use IF_GCC macro, based on the answers above:

根据上面的答案,我已经创建了一个现成的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')) 

Usage: $(call MY_IF_GCC,ge,30305,-fan_option_for_gcc_ge_3.3.5)

用法:$(-fan_option_for_gcc_ge_3.3.5叫MY_IF_GCC,通用电气,30305)

As the second argument, you can use any operator of those supported by test(1): eq, gt, lt, ge, le etc.

作为第二个参数,可以使用test(1)所支持的任何操作符:eq、gt、lt、ge、le等。

If cc -V doesn't work for you, replace it with gcc -dumpversion or whatever suitable

如果cc -V不适合你,用gcc -dumpversion替换它或者其他合适的。

Hope that helps.

希望有帮助。

#6


0  

Sometimes you want to display the version with the extra info.

有时您想要显示带有额外信息的版本。

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

gcc (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1

gcc 4.8.1(Ubuntu 4.8.1-2ubuntu1 ~ 12.04)