如何在不使 CMake 缓存无效的情况下更改 GCC 显示的错误数?
How can I change the number of errors GCC displays without invaliding the CMake cache?
我有一个使用 GCC 和 CMake 构建的 C++ 项目。
一般我喜欢用-fmax-errors=1
编译。我的正常工作流程是修复第一个错误,然后重建,因为后续错误通常是由第一个错误引起的。
但不幸的是,对于 C++20,涉及约束失败的错误通常被 GCC 视为多个“错误”。为了了解约束失败的原因,我需要查看不止一个错误。
所以偶尔我喜欢把-fmax-errors
设置成一个更大的数字,可能是2
,当出现这样的错误时
但是更改编译器标志(通过手动更改 CMakeLists.txt
或在命令行上将缓存变量传递给 cmake
)会使 CMake 缓存无效并使构建从头开始。
这种行为通常是有道理的;任意配置更改可能需要重建。但我们人类明白,改变编译器的错误格式化行为并不需要重建。有没有办法向 CMake 表达这种区别?
或者,如果失败了,是否有解决此问题的巧妙方法?我想在调用编译器时让 CMake 读取环境变量(而不是在 cmake
为 运行 时),但我找不到任何文档表明这实际上是可能的.
(我可能会创建一个脚本,将其大部分参数转发给 g++
,但也会添加 -fmax-errors="$MY_COOL_ENV_VARIABLE"
,然后告诉 CMake 所讨论的脚本是用于构建的 C++ 编译器,但是我想这可能会违反 CMake 对“编译器”的一些期望。)
在 Marc Glisse 的建议下,我尝试了问题末尾括号中假设的方法。这实际上效果很好。
我现在在项目的顶级目录中有一个名为 invoke_compiler.py
的 Python 脚本。我以指定 C++ 编译器的通常方式将 CMake 指向脚本。
set(CMAKE_CXX_COMPILER ${PROJECT_SOURCE_DIR}/invoke_compiler.py)
现在为了说明起见,我在这个问题上实际上有点简洁。实际上,我经常使用 GCC 和 Clang 构建这个项目。所以我希望能够在调用 cmake
.
时将 C++ 编译器指定给 CMake
cmake my-src-dir -DCMAKE_CXX_COMPILER=g++
因此 invoke_compiler.py
必须采用一些额外的命令行标志,--my-project-cxx-compiler
和 --my-project-num-errors-flag
。
然后脚本调用编译器(其可执行文件是由 --my-project-cxx-compiler
指定的),转发其所有命令行参数,除了上面提到的额外参数并添加 f"{num_errors_flag}={os.environ.get('MY_PROJECT_NUM_ERRORS', 1)}"
。 (指定要显示的错误数的编译器标志的名称本身必须作为参数传递给脚本,因为 GCC 和 Clang 分别调用标志 --fmax-errors
和 --ferror-limit
。)
诀窍很简单,CMakeLists.txt
中的逻辑确定要传递给 invoke_compiler.py
的参数需要在 CMAKE_CXX_COMPILER
被覆盖之前执行。
用户只需像往常一样与 CMake 交互并随时更改 MY_PROJECT_NUM_ERRORS
变量的值,以便从编译器获得不同数量的错误。
我有一个使用 GCC 和 CMake 构建的 C++ 项目。
一般我喜欢用-fmax-errors=1
编译。我的正常工作流程是修复第一个错误,然后重建,因为后续错误通常是由第一个错误引起的。
但不幸的是,对于 C++20,涉及约束失败的错误通常被 GCC 视为多个“错误”。为了了解约束失败的原因,我需要查看不止一个错误。
所以偶尔我喜欢把-fmax-errors
设置成一个更大的数字,可能是2
,当出现这样的错误时
但是更改编译器标志(通过手动更改 CMakeLists.txt
或在命令行上将缓存变量传递给 cmake
)会使 CMake 缓存无效并使构建从头开始。
这种行为通常是有道理的;任意配置更改可能需要重建。但我们人类明白,改变编译器的错误格式化行为并不需要重建。有没有办法向 CMake 表达这种区别?
或者,如果失败了,是否有解决此问题的巧妙方法?我想在调用编译器时让 CMake 读取环境变量(而不是在 cmake
为 运行 时),但我找不到任何文档表明这实际上是可能的.
(我可能会创建一个脚本,将其大部分参数转发给 g++
,但也会添加 -fmax-errors="$MY_COOL_ENV_VARIABLE"
,然后告诉 CMake 所讨论的脚本是用于构建的 C++ 编译器,但是我想这可能会违反 CMake 对“编译器”的一些期望。)
在 Marc Glisse 的建议下,我尝试了问题末尾括号中假设的方法。这实际上效果很好。
我现在在项目的顶级目录中有一个名为 invoke_compiler.py
的 Python 脚本。我以指定 C++ 编译器的通常方式将 CMake 指向脚本。
set(CMAKE_CXX_COMPILER ${PROJECT_SOURCE_DIR}/invoke_compiler.py)
现在为了说明起见,我在这个问题上实际上有点简洁。实际上,我经常使用 GCC 和 Clang 构建这个项目。所以我希望能够在调用 cmake
.
cmake my-src-dir -DCMAKE_CXX_COMPILER=g++
因此 invoke_compiler.py
必须采用一些额外的命令行标志,--my-project-cxx-compiler
和 --my-project-num-errors-flag
。
然后脚本调用编译器(其可执行文件是由 --my-project-cxx-compiler
指定的),转发其所有命令行参数,除了上面提到的额外参数并添加 f"{num_errors_flag}={os.environ.get('MY_PROJECT_NUM_ERRORS', 1)}"
。 (指定要显示的错误数的编译器标志的名称本身必须作为参数传递给脚本,因为 GCC 和 Clang 分别调用标志 --fmax-errors
和 --ferror-limit
。)
诀窍很简单,CMakeLists.txt
中的逻辑确定要传递给 invoke_compiler.py
的参数需要在 CMAKE_CXX_COMPILER
被覆盖之前执行。
用户只需像往常一样与 CMake 交互并随时更改 MY_PROJECT_NUM_ERRORS
变量的值,以便从编译器获得不同数量的错误。