Checking the gcc version in a Makefile?

2020-02-02 13:34发布

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

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

7条回答
姐就是有狂的资本
2楼-- · 2020-02-02 13:41

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_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_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楼-- · 2020-02-02 13:47

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

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).

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

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
查看更多
做个烂人
4楼-- · 2020-02-02 13:51

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

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)

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

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

Hope that helps.

查看更多
手持菜刀,她持情操
5楼-- · 2020-02-02 13:53

Are you using something like 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.

查看更多
Explosion°爆炸
6楼-- · 2020-02-02 13:53

Following Chris, but using awk

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

note $ needs to be escaped in Makefile with another $.

查看更多
唯我独甜
7楼-- · 2020-02-02 13:53

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

查看更多
登录 后发表回答