【问题标题】:Can I have my Makefile automatically make GCC use the most recent standard it supports?我可以让我的 Makefile 自动让 GCC 使用它支持的最新标准吗?
【发布时间】:2016-11-14 17:35:55
【问题描述】:

我的 C++03 项目需要升级到 C++11,我可以保证至少在我想使用的所有 GCC 中都提供对它的实验性支持。

但是,这可能是-std=c++0x,也可能是来自较新 GCC 的实际 -std=c++11。有一天它会是-std=c++14(当 CentOS 赶上来时……)。

如何形成一个 GNU Makefile,将“最佳”标志添加到 CXXFLAGS,这取决于哪个会成功?

我可以说“好吧,我最早使用的 GCC 仍然没有生产就绪的 C++11 支持,所以我应该坚持使用 C++03”,但是嗯。

【问题讨论】:

  • -std=c++0x 在较新的版本中工作,作为-std=c++11 的同义词,所以你可以使用它
  • 尊重将 C++03 迁移到您的开发流中。
  • @Bathsheba:我们花了很长时间!当他们认为这只是一个轻弹开关的情况时,管理层的支持很容易哈哈
  • @JonathanWakely:.....哦。不过,当我可以访问 C++14 编译器时,我希望能够继续这种趋势,所以......我希望我的 Makefile 能够针对最新可用的受支持语言标准进行编译,然后(我猜)使用使代码本身“可移植”的宏。我稍微调整了措辞。
  • 我想知道你从中获得了什么。您的代码要么需要-std=c++14,要么不需要。在第一种情况下,旧的 GCC 版本已经过时;在后一种情况下,您可以使用-std=c++11。也就是说,GCC 确实需要 -std=c++now 并将其作为默认值。

标签: c++ c++11 gcc c++14 gnu-make


【解决方案1】:

这将选择$(CXX) 编译器支持的最佳选项:

CXX_MODE.42 := -std=c++98
CXX_MODE.43 := $(CXX_MODE.42)
CXX_MODE.44 := $(CXX_MODE.43)
CXX_MODE.45 := $(CXX_MODE.44)
CXX_MODE.46 := -std=c++0x
# Unnecessary, since -std=c++0x still works, but hey why not:
CXX_MODE.47 := -std=c++11
CXX_MODE.48 := $(CXX_MODE.47)
CXX_MODE.49 := $(CXX_MODE.48)
CXX_MODE.5 := -std=c++14
CXX_MODE.6 := $(CXX_MODE.5)
GXX_VERSION := $(shell $(CXX) -dumpversion | awk -F. '$$1<5{print $$1$$2} $$1>=5{print $$1}')
CXX_MODE := $(CXX_MODE.$(GXX_VERSION))
CXXFLAGS += $(CXX_MODE)

为了获得更多乐趣,您可以根据其他一些变量在 c++ 和 gnu++ 模式之间进行选择:

CXX_MODE.42 := 98
CXX_MODE.43 := $(CXX_MODE.42)
CXX_MODE.44 := $(CXX_MODE.43)
CXX_MODE.45 := $(CXX_MODE.44)
CXX_MODE.46 := 0x
# Unnecessary, since -std=c++0x still works, but hey why not:
CXX_MODE.47 := 11
CXX_MODE.48 := $(CXX_MODE.47)
CXX_MODE.49 := $(CXX_MODE.48)
CXX_MODE.5 := 14
CXX_MODE.6 := $(CXX_MODE.5)
GXX_VERSION := $(shell $(CXX) -dumpversion | awk -F. '$$1<5{print $$1$$2} $$1>=5{print $$1}')
CXX_MODE := $(CXX_MODE.$(GXX_VERSION))
ifneq($(STRICT),)
CXXFLAGS += -std=c++$(CXX_MODE) -pedantic -pedantic-errors
else
CXXFLAGS += -std=gnu++$(CXX_MODE)
endif

【讨论】:

  • 有趣。这个“点”语法是否记录在某处?有链接吗?
  • 我记得 gcc 定义了一个宏来指示它实现的 Cxx 修订级别。更邪恶的实现会运行 gcc,转储该宏,然后使用它来选择正确的选项。
  • @SamVarshavchik 如果你的意思是 __cplusplus,这是标准要求的,但直到 GCC 4.7 才准确设置,所以你会得到错误的答案。
  • @kebs 他们只是做变量。点是变量名中的有效字符。如果您愿意,可以使用下划线。我所做的只是连接CXX_MODE. 和$(GXX_VERSION),然后引用该名称的变量$(CXX_MODE.$(GXX_VERSION)),这是上面定义的变量之一。点没有做任何特别的事情,只是名称的固定部分和扩展另一个变量的部分之间的分隔符,使其在视觉上不同。
【解决方案2】:

不完全是一个答案,因为它不提供自动选择,但我认为它还是有用的。

你可以使用 make 命令行选项来选择你想要的:

ifeq($(CPP11),Y)
    CXXFLAGS+=-std=c++11
endif

ifeq($(CPP14),Y)
    CXXFLAGS+=-std=c++14
endif

调用会以这种方式完成:

make <target> CPP11=Y

或

make <target> CPP14=Y

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多