【发布时间】:2019-02-09 14:15:23
【问题描述】:
我目前尝试使用 Visual Studio 15 2017 Win64 生成器将 Visual Studio 2017 的 C++ Core Guidelines Checker (CppCoreCheck) 与元构建系统 CMake 集成。
以下示例说明了我的方法(我已尝试将 CMake 源代码精简到最低限度)。
首先,我已将所有编译器开关添加到构建目标以使用 CppCoreCheck 进行分析:
cmake_minimum_required(VERSION 3.12)
project(cppcorecheck-example)
find_package(Boost REQUIRED MODULE)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE Boost::boost)
target_compile_options(app
PRIVATE
"/analyze"
"/analyze:WX-"
"/analyze:log" "cppcorecheck.xml"
"/analyze:stacksize" 16384
"/analyze:max_paths" 256
"/analyze:ruleset" "CppCoreCheckRules.ruleset"
"/analyze:plugin EspXEngine.dll"
)
我正在使用以下main.cpp:
#include <boost/system/error_code.hpp>
int main() {
int arr[10]; // warning C26494
int* p = arr; // warning C26485
{
int* q = p + 1; // warning C26481
p = q++; // warning C26481
}
}
仅此示例就足以在目标编译期间调用 CppCoreCheck:
cmake -G"Visual Studio 15 2017 Win64" -H. -B_build -DBOOST_ROOT="C:/boost-1.68.0-x64" -DBoost_USE_STATIC_LIBS=ON
cmake --build _build --target app
会生成以下警告:
"c:\dev\cppcorecheck-example\_build\app.vcxproj" (Standardziel) (1) ->
(ClCompile Ziel) ->
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(237): warning C26440: Function 'boost::system::error_category::std_category::std_category' can be declared 'noexcept' (f.6: http://go.microsoft.com/fwlink/?linkid=853927). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(244): warning C26412: Do not dereference an invalid pointer (lifetimes rule 1). 'return of name' was invalidated at line 243 by '(unknown)'.: Lines: 241, 243, 244 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(319): warning C26432: If you define or delete any default operation in the type 'class boost::system::error_category', define or delete them all (c.21: http://go.microsoft.com/fwlink/?linkid=853922). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(494): warning C26412: Do not dereference an invalid pointer (lifetimes rule 1). 'return of system_category' was invalidated at line 493 by '(unknown)'.: Lines: 491, 493, 494 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(499): warning C26412: Do not dereference an invalid pointer (lifetimes rule 1). 'return of generic_category' was invalidated at line 498 by '(unknown)'.: Lines: 496, 498, 499 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(763): warning C26490: Don't use reinterpret_cast (type.1: http://go.microsoft.com/fwlink/p/?LinkID=620417). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(753): warning C26440: Function 'boost::detail::throws' can be declared 'noexcept' (f.6: http://go.microsoft.com/fwlink/?linkid=853927). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(768): warning C26412: Do not dereference an invalid pointer (lifetimes rule 1). 'return of throws' was invalidated at line 768 by '(unknown)'.: Lines: 767, 768 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(824): warning C26472: Don't use a static_cast for arithmetic conversions. Use brace initialization, gsl::narrow_cast or gsl::narow (type.1: http://go.microsoft.com/fwlink/p/?LinkID=620417). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(825): warning C26490: Don't use reinterpret_cast (type.1: http://go.microsoft.com/fwlink/p/?LinkID=620417). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(822): warning C26440: Function 'boost::system::hash_value' can be declared 'noexcept' (f.6: http://go.microsoft.com/fwlink/?linkid=853927). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(889): warning C26499: Could not find any lifetime tracking information for '*pc2': Lines: 896, 869, 872, 874, 875, 877, 878, 880, 881, 880, 883, 886, 887, 886, 889 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(874): warning C26496: The variable 'bn' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(880): warning C26496: The variable 'bn' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(889): warning C26496: The variable 'bn' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(919): warning C26499: Could not find any lifetime tracking information for '*pc2': Lines: 930, 899, 902, 904, 905, 907, 908, 910, 911, 910, 913, 916, 917, 916, 919 [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(904): warning C26496: The variable 'bc' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(910): warning C26496: The variable 'bc' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\boost-1.68.0-x64\include\boost-1_68\boost\system\error_code.hpp(919): warning C26496: The variable 'bc' is assigned only once, mark it as const (con.4: https://go.microsoft.com/fwlink/p/?LinkID=784969). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\dev\cppcorecheck-example\main.cpp(6): warning C26494: Variable 'arr' is uninitialized. Always initialize an object (type.5: http://go.microsoft.com/fwlink/p/?LinkID=620421). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\dev\cppcorecheck-example\main.cpp(7): warning C26485: Expression 'arr': No array to pointer decay (bounds.3: http://go.microsoft.com/fwlink/p/?LinkID=620415). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\dev\cppcorecheck-example\main.cpp(10): warning C26481: Don't use pointer arithmetic. Use span instead (bounds.1: http://go.microsoft.com/fwlink/p/?LinkID=620413). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\dev\cppcorecheck-example\main.cpp(11): warning C26481: Don't use pointer arithmetic. Use span instead (bounds.1: http://go.microsoft.com/fwlink/p/?LinkID=620413). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
c:\dev\cppcorecheck-example\main.cpp(5): warning C26440: Function 'main' can be declared 'noexcept' (f.6: http://go.microsoft.com/fwlink/?linkid=853927). [c:\dev\cppcorecheck-example\_build\app.vcxproj]
24 Warnung(en)
0 Fehler
Verstrichene Zeit 00:00:05.77
为了抑制来自第三方库 Boost 的警告,必须提供额外的设置。
这里有一个问题:CppCoreCheck 依赖于 环境 变量来实现其配置的某些部分,更准确地说:
-
Esp.Extensions:应该设置为CppCoreCheck.dll -
Esp.AnnotationBuildLevel:应该设置为ignore -
CAExcludePath:应设置为要忽略的目录路径(例如C:\boost-1.68.0-x64\include\boost-1_68;C:\foo;)
有没有办法使用 CMake 为编译阶段设置环境变量?我目前不知道一种方法:
-
在
CMakeLists.txt中如下设置环境变量不起作用,因为环境变量仅在配置阶段有效:set(ENV{Esp.Extensions} "CppCoreCheck.dll") set(ENV{Esp.AnnotationBuildLevel} "ignore") set(ENV{CAExcludePath} "C:\\boost-1.68.0-x64\\include\\boost-1_68") -
在目标的构建阶段使用自定义命令似乎也不起作用:
add_custom_command(TARGET ${args_TARGET} PRE_BUILD COMMAND ${CMAKE_COMMAND} -P "${PROJECT_SOURCE_DIR}/set_cppcorecheck.cmake" )注意:
set_cppcorecheck.cmake包含上面列出的三个set命令。
如果在调用构建命令的控制台中设置了环境变量,它确实可以正常工作,例如
SET Esp.Extensions=CppCoreCheck.dll
SET Esp.AnnotationBuildLevel=ignore
SET CAExcludePath=C:\dev\native\boost\boost-1.68.0-x64\include\boost-1_68
cmake --build _build --target app
但这很丑陋并且无法扩展。原因:我的目标是由构建系统自动填充CAExcludePath。
我读过https://www.reddit.com/r/cpp/comments/6u2myo/how_to_use_the_c_core_guidelines_checker_outside,其中描述了相同的问题(没有解决方案)。
有没有人可以解决我的问题(为“正常”目标的编译阶段设置环境变量)?
【问题讨论】:
-
我认为这是不可能的(不采取极其复杂的措施,例如将所有构建命令的整个调用移动到自定义命令中),而且我不知道任何其他构建工具需要这样的东西。恕我直言,这应该是对 MSVC 人员的功能请求:使这些选项可从命令行配置。
-
是的,我想了一秒钟关于通过
add_custom_command包装所有与构建相关的命令,但很快就放弃了这个想法(这太疯狂了,imo)。感谢您提供功能请求的建议。我将在 visualstudio.uservoice.com 上请求该功能,并稍后在此处添加请求的链接。 CLI 参数或配置文件都会好得多。
标签: c++ visual-studio cmake static-code-analysis cpp-core-guidelines