繁体   English   中英

检查 Makefile 中的 gcc 版本?

[英]Checking the gcc version in a Makefile?

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

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

我不会说这很容易,但是您可以使用 GNU make 的shell函数来执行像gcc --version这样的 shell 命令,然后使用ifeq条件表达式来检查版本号并适当地设置您的CFLAGS变量。

这是一个快速示例生成文件:

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

将完整的 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输出中丢失版本的第三部分的gcc -dumpversion (在一些早期的 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

我刚遇到这个问题,我需要测试 gcc 的前两位数字,并且想要一个比上面聪明的 sed 黑客更易读的选项。 我使用 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

我根据上面的答案制作了一个现成的 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 或任何合适的

希望有帮助。

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

可能值得通过启用标志的 gcc 调用“虚拟”编译,如果由于编译器无法识别该标志而失败,您可以退回到不使用较新警告选项的命令行。

跟随克里斯,但使用 awk

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

注意$需要在 Makefile 中使用另一个$进行转义。

我发现了这个,并认为它真的很聪明。 它使用较少的 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

我认为awk是用于此目的的更好工具,因为它可以将版本字符串拆分为$1 $2$3然后在一个命令中与><>=等进行比较。

如果表达式为假, awk省略整行,这是ifdef ifdef将空字符串视为未定义。

GCC_VERSION_GT_75 = $(shell gcc -dumpfullversion -dumpversion | awk -F. '$1 > 7 && $2 > 5')
ifdef GCC_VERSION_GT_75
    # stuff that requires gcc version > 7.5
endif

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

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

gcc (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM