Интеграция CMake с Visual Studio 2017 C ++ Core Guidelines Checker (CppCoreCheck) - PullRequest
0 голосов
/ 04 сентября 2018

В настоящее время я пытаюсь интегрировать C ++ Core Guidelines Checker (CppCoreCheck) Visual Studio 2017 с системой мета-сборки CMake с использованием генератора Visual Studio 15 2017 Win64.

Следующий пример иллюстрирует мой подход (я попытался сократить исходный код 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? В настоящее время я не знаю о подходе:

  1. Установка переменных среды следующим образом в 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")
    
  2. Использование пользовательской команды на этапе сборки цели тоже не работает:

    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, где описана та же проблема (без решения).

У кого-нибудь есть решение моей проблемы (установка переменной среды для фазы компиляции "нормальной" цели)?

...