【问题标题】:How can I make the Microsoft C++ compiler treat unknown flags as errors rather than warnings?如何使 Microsoft C++ 编译器将未知标志视为错误而不是警告?
【发布时间】:2013-02-21 23:23:00
【问题描述】:

出于各种原因,我希望能够编写脚本来检测 MS C++ 编译器是否支持特定标志。我正在使用来自 Windows 7.1 SDK 的编译器:

C:\> cl /version
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

假设我想知道这个编译器是否支持标志/GLEFGB(它不支持,因为它不存在):

C:\>cl /c ./foo.cc /GLEFBG
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '/GEFBG'
foo.cc

好的,好的开始,但它是一个警告,它不会将退出状态设置为无效:

C:\>echo %errorLevel%
0

所以如果我们使用/WX 将警告作为错误打开,我们应该完成,对吧?

C:\>cl /c ./foo.cc /WX /GLEFBG

Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '/GEFBG'
foo.cc

错了。这越来越令人失望。也许由于某种原因,/WX 没有捕获 D9002?也许我们可以通过将/we 与该代码一起使用来明确地将其设为错误?想知道这是否可行吗?

C:\>cl /c ./foo.cc /WX /weD9002 /GLEFBG
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line error D8021 : invalid numeric argument '/weD9002'

不,现在我们出错了,因为这个编译器警告的标记显然不是/we 的合法参数。我也试过/we9002,也不管用。

所以,现在我没有想法了。如果传递了一个无效标志,关于如何说服cl 以非零退出状态出错有什么想法吗?如果没有这种行为,真的很难询问编译器是否支持标志。

【问题讨论】:

  • 警告选项仅适用于编译器解析的代码,不适用于命令行参数。没有办法让它以这种方式失败。
  • 好的,那么如何确定编译器是否支持给定标志?
  • 我如何以编程方式确定编译器是否支持给定标志?
  • @HansPassant 不,这并不傻。这实际上非常重要:许多构建系统在开始时都有一个类似“配置”的阶段,在此阶段它们会检测工具链是否提供某些功能。执行此操作的常见方法是尝试使用标志调用编译器,并检查退出状态,根据编译器将拒绝无效标志并出现错误的理论。这个编译器不提供这种行为的事实是有问题的。
  • 这是一个 XY 问题。你永远不会以你希望的方式实现它。更新您的问题以描述您想要完成的任务。并且一定要包含这样一个构建系统的示例,包含它的 [tag],以便知道它的人可以解释他们是如何为 MSVC 编译器做的。

标签: visual-studio visual-c++ build build-process


【解决方案1】:

我遇到了同样的问题。虽然cl 没有报告它们,但您也许可以检查cl 的输出。

我最终编写了一个执行另一个程序的 python 脚本,如果该程序返回错误或程序向stderr 写入任何内容,则脚本报告失败(即退出代码 1):

#!/usr/bin/python3
import subprocess
import sys

proc = subprocess.Popen(sys.argv[1:], stderr=subprocess.PIPE)

got_error = False

for l in proc.stderr:
    try:
        print(str(l, errors="replace"), end="")
    except TypeError:
        print(str(l), end="")
    got_error = True

proc.wait()

if got_error or proc.poll() != 0:
    sys.exit(1)

我在cygwin下试过了,但是在dos提示下也应该可以工作(也许你必须用python解释器专门调用它):

python3 chkerr cl /c ./foo.cc /GLEFBG

chkerr 是我给脚本起的名字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    相关资源
    最近更新 更多