Checking the gcc version in a Makefile?
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 ?
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.
Here's a quick example 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
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
To transform full 3-part gcc version (not only first digit) into numerical format, suitable for comparison (e.g. 40701
) use
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/'
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 -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
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
I found this and thought it was really clever. It implements >, >=, <, and <= with fewer shell calls:
GCC_VERSION := $(shell gcc -dumpversion)
VERSION := 7.4.0
ifeq ($(VERSION),$(firstword $(sort $(GCC_VERSION) $(VERSION))))
# stuff that requires GCC_VERSION >= VERSION
endif
This example shows >=. You can implement >, <=, or < using combinations of ifneq and $(lastword).
References:
https://lists.gnu.org/archive/html/help-make/2006-04/msg00065.html
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.