Integrate cppcheck and clang-tidy within the CMake project (#5730)

This commit is contained in:
Alessandro Gario 2019-10-08 18:17:11 +02:00 committed by GitHub
parent 846c392903
commit 225bbaf992
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 253 additions and 8 deletions

View File

@ -25,10 +25,26 @@ include(cmake/options.cmake)
include(cmake/flags.cmake)
include(cmake/packaging.cmake)
if (OSQUERY_TOOLCHAIN_SYSROOT AND NOT DEFINED PLATFORM_LINUX)
if(OSQUERY_TOOLCHAIN_SYSROOT AND NOT DEFINED PLATFORM_LINUX)
message(FATAL_ERROR "The custom toolchain can only be used with Linux, undefine OSQUERY_TOOLCHAIN_SYSROOT and specify a compiler to use")
endif()
# clang-tidy needs to be initialized in global scope, before any
# target is created
if(OSQUERY_ENABLE_CLANG_TIDY)
find_package(clang-tidy)
if(TARGET clang-tidy::clang-tidy)
foreach(language C CXX)
set("CMAKE_${language}_CLANG_TIDY"
"${CLANG-TIDY_EXECUTABLE};${OSQUERY_CLANG_TIDY_CHECKS}"
)
endforeach()
else()
message(WARNING "clang-tidy: Disabled because it was not found")
endif()
endif()
function(main)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Shared libraries: ${BUILD_SHARED_LIBS}")
@ -55,10 +71,7 @@ function(main)
add_subdirectory("plugins")
add_subdirectory("tools")
add_subdirectory("specs")
if(OSQUERY_BUILD_TESTS)
add_subdirectory("tests")
endif()
add_subdirectory("tests")
identifyPackagingSystem()
generateInstallTargets()

View File

@ -20,7 +20,7 @@ jobs:
vmImage: 'Ubuntu-16.04'
container:
image: trailofbits/osquery:ubuntu-18.04-toolchain-v2
image: trailofbits/osquery:ubuntu-18.04-toolchain-v3
options: --privileged
timeoutInMinutes: 120
@ -67,6 +67,12 @@ jobs:
workingDirectory: $(Build.BinariesDirectory)/build
cmakeArgs: --build . -j 3
- task: CMake@1
displayName: "Run cppcheck"
inputs:
workingDirectory: $(Build.BinariesDirectory)/build
cmakeArgs: --build . --target cppcheck
- script: |
ctest --build-nocmake -V
displayName: "Run tests"

View File

@ -0,0 +1,68 @@
# Copyright (c) 2014-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed in accordance with the terms specified in
# the LICENSE file found in the root directory of this source tree.
function(findClangTidy)
# Look for the clang-tidy executable
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(executable_name "clang-tidy")
set(optional_path_suffix_list
PATH_SUFFIXES bin usr/bin
)
if(NOT "${OSQUERY_TOOLCHAIN_SYSROOT}" STREQUAL "")
set(optional_path_list
PATHS "${OSQUERY_TOOLCHAIN_SYSROOT}"
)
endif()
else()
set(executable_name "clang-tidy.exe")
endif()
find_program("CLANG-TIDY_EXECUTABLE"
NAMES "${executable_name}"
DOC "clang-tidy executable path"
${optional_path_list}
${optional_path_suffix_list}
)
if("${CLANG-TIDY_EXECUTABLE}" STREQUAL "CLANG-TIDY_EXECUTABLE-NOTFOUND")
return()
endif()
# Get the version string
execute_process(
COMMAND "${CLANG-TIDY_EXECUTABLE}" --version
OUTPUT_VARIABLE version_output
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" "" version_output "${version_output}")
string(REPLACE " " ";" version_output_as_list "${version_output}")
list(GET version_output_as_list 5 clang_tidy_version)
set(CLANG-TIDY_VERSION_STRING "${clang_tidy_version}" PARENT_SCOPE)
# Create an imported target
add_executable(clang-tidy::clang-tidy IMPORTED)
set_target_properties(
clang-tidy::clang-tidy PROPERTIES
IMPORTED_LOCATION "${CLANG-TIDY_EXECUTABLE}"
)
endfunction()
findClangTidy("CLANG-TIDY_EXECUTABLE")
mark_as_advanced("CLANG-TIDY_EXECUTABLE")
find_package(PackageHandleStandardArgs REQUIRED)
find_package_handle_standard_args(clang-tidy
REQUIRED_VARS "CLANG-TIDY_EXECUTABLE"
VERSION_VAR "CLANG-TIDY_VERSION_STRING"
)

View File

@ -0,0 +1,65 @@
# Copyright (c) 2014-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed in accordance with the terms specified in
# the LICENSE file found in the root directory of this source tree.
function(FindCppcheck)
# Look for the cppcheck executable
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(executable_name "cppcheck")
set(optional_path_suffix_list
PATH_SUFFIXES bin usr/bin
)
if(NOT "${OSQUERY_TOOLCHAIN_SYSROOT}" STREQUAL "")
set(optional_path_list
PATHS "${OSQUERY_TOOLCHAIN_SYSROOT}"
)
endif()
else()
set(executable_name "cppcheck.exe")
endif()
find_program("CPPCHECK_EXECUTABLE"
NAMES "${executable_name}"
DOC "Cppcheck executable path"
${optional_path_list}
${optional_path_suffix_list}
)
if("${CPPCHECK_EXECUTABLE}" STREQUAL "CPPCHECK_EXECUTABLE-NOTFOUND")
return()
endif()
# Get the version string
execute_process(
COMMAND "${CPPCHECK_EXECUTABLE}" --version
OUTPUT_VARIABLE version_output
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "Cppcheck " "" version_output "${version_output}")
set(CPPCHECK_VERSION_STRING "${version_output}" PARENT_SCOPE)
# Create an imported target
add_executable(cppcheck::cppcheck IMPORTED)
set_target_properties(
cppcheck::cppcheck PROPERTIES
IMPORTED_LOCATION "${CPPCHECK_EXECUTABLE}"
)
endfunction()
FindCppcheck("CPPCHECK_EXECUTABLE")
mark_as_advanced("CPPCHECK_EXECUTABLE")
find_package(PackageHandleStandardArgs REQUIRED)
find_package_handle_standard_args(cppcheck
REQUIRED_VARS "CPPCHECK_EXECUTABLE"
VERSION_VAR "CPPCHECK_VERSION_STRING"
)

View File

@ -71,6 +71,9 @@ option(OSQUERY_BUILD_TESTS "Whether to enable and build tests or not")
option(OSQUERY_FUZZ "Whether to build fuzzing harnesses")
option(OSQUERY_ENABLE_CLANG_TIDY "Enables clang-tidy support")
set(OSQUERY_CLANG_TIDY_CHECKS "-checks=cert-*,cppcoreguidelines-*,performance-*,portability-*,readability-*,modernize-*,bugprone-*" CACHE STRING "List of checks performed by clang-tidy")
# Unfortunately, due glog always enabling BUILD_TESTING, we have to force it off, so that tests won't be built
overwrite_cache_variable("BUILD_TESTING" "BOOL" "OFF")
@ -82,6 +85,7 @@ else()
set(third_party_source_list "source_migration;facebook")
endif()
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" CACHE STRING "A list of paths containing CMake module files")
set(OSQUERY_THIRD_PARTY_SOURCE "${third_party_source_list}" CACHE STRING "Sources used to acquire third-party dependencies")
# This is the default S3 storage used by Facebook to store 3rd party dependencies; it

View File

@ -158,6 +158,29 @@ A "single" test case often still involves dozens or hundreds of unit tests. To r
GTEST_FILTER=sharedMemory.* ctest -R <testName> -V #runs just the sharedMemory tests under the <testName> set.
```
## Running Cppcheck (Linux only)
1. Install it from the distro repository: `apt install cppcheck`
2. Build the **cppcheck** target `cmake --build . --target cppcheck`
## Running clang-tidy (Linux only)
The clang-tidy executable is shipped along with the osquery toolchain, and it is the recommended way to run it. It is however possible to use the system one, provided it's accessible from the PATH environment variable.
1. When configuring, pass `-DOSQUERY_ENABLE_CLANG_TIDY=ON` to CMake
2. Configure the checks: `-DOSQUERY_CLANG_TIDY_CHECKS=check1,check2` **(optional)**
3. Build osquery
By default, the following checks are enabled:
1. cert-*
2. cppcoreguidelines-*
3. performance-*
4. portability-*
5. readability-*
6. modernize-*
7. bugprone-*
# Building with Buck
Building and testing is the same on all platforms. Each platform section below describes how to install the required tools and dependencies.

View File

@ -22,6 +22,7 @@ function(librariesMain)
list(APPEND module_path_list "${third_party_source_path}")
endforeach()
list(INSERT module_path_list 0 ${CMAKE_MODULE_PATH})
overwrite_cache_variable("CMAKE_MODULE_PATH" STRING "${module_path_list}")
add_library(thirdparty_cxx_settings INTERFACE)

View File

@ -187,6 +187,10 @@ function(importSourceSubmodule)
endif()
endif()
# Make sure we don't run clang-tidy on the source modules
unset(CMAKE_C_CLANG_TIDY)
unset(CMAKE_CXX_CLANG_TIDY)
add_subdirectory(
"${directory_path}"
"${CMAKE_BINARY_DIR}/libs/src/${ARGS_NAME}"

View File

@ -5,9 +5,12 @@
# the LICENSE file found in the root directory of this source tree.
function(testsMain)
add_subdirectory("integration/tables")
add_subdirectory("cppcheck")
generateTestsHelper()
if(OSQUERY_BUILD_TESTS)
add_subdirectory("integration/tables")
generateTestsHelper()
endif()
endfunction()
function(generateTestsHelper)

View File

@ -0,0 +1,49 @@
# Copyright (c) 2014-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed in accordance with the terms specified in
# the LICENSE file found in the root directory of this source tree.
cmake_minimum_required(VERSION 3.13.3)
include(ProcessorCount)
function(cppcheckMain)
find_package(cppcheck)
if(NOT CPPCHECK_FOUND)
message(STATUS "cppcheck: The executable was not found")
return()
endif()
if(NOT CMAKE_EXPORT_COMPILE_COMMANDS)
message(STATUS "cppcheck: CMAKE_EXPORT_COMPILE_COMMANDS must be enabled")
return()
endif()
message(STATUS "cppcheck: Enabled with ${CPPCHECK_EXECUTABLE}")
ProcessorCount(job_count)
math(EXPR job_count "${job_count} + 1")
set(multithread_options
-j ${job_count}
)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/suppressions_list.txt"
cppcheck_suppressions_list
)
string(REPLACE "\n" ", " cppcheck_suppressions_list "${cppcheck_suppressions_list}")
# We don't care if multithreading disables the unusedFunction check, since that would turn off
# suppressions (and we don't want to waste time analyzing the source modules)
add_custom_target(
cppcheck
COMMAND "${CMAKE_COMMAND}" -E echo "Suppression list: '${cppcheck_suppressions_list}'"
COMMAND cppcheck::cppcheck "--suppressions-list=${CMAKE_CURRENT_SOURCE_DIR}/suppressions_list.txt" "--library=${CMAKE_CURRENT_SOURCE_DIR}/libraries/googletest.cfg" ${multithread_options} --enable=all --platform=unix64 "--project=${CMAKE_BINARY_DIR}/compile_commands.json" --quiet
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Running Cppcheck ${CPPCHECK_VERSION_STRING}"
VERBATIM
)
endfunction()
cppcheckMain()

View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<def version="2">
<define name="TEST(A,B)" value="void __ ## A ## _ ## B ( )"/>
<define name="TEST_F(A,B)" value="void __ ## A ## _ ## B ( )"/>
<define name="GTEST_TEST(A,B)" value="void __ ## A ## _ ## B ( )"/>
</def>

View File

@ -0,0 +1,2 @@
*:*/libraries/*
*:*/patched-source/*

View File

@ -3,6 +3,7 @@ COPY *.deb ./
RUN apt update -q -y && apt upgrade -q -y && apt install -q -y --no-install-recommends \
git \
make \
cppcheck \
ccache \
python \
python3 \