Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将clang tidy集成到CMake和GCC? < P> >我想将CLAN-TIGY集成到我们的C和C++,基于CMake的项目,它是使用自定义的GCC工具链编译的。_C++_Gcc_Cmake_Clang_Clang Tidy - Fatal编程技术网

如何将clang tidy集成到CMake和GCC? < P> >我想将CLAN-TIGY集成到我们的C和C++,基于CMake的项目,它是使用自定义的GCC工具链编译的。

如何将clang tidy集成到CMake和GCC? < P> >我想将CLAN-TIGY集成到我们的C和C++,基于CMake的项目,它是使用自定义的GCC工具链编译的。,c++,gcc,cmake,clang,clang-tidy,C++,Gcc,Cmake,Clang,Clang Tidy,我尝试了以下方法,设置CMAKE\u CXX\u CLANG\u TIDY。我还尝试通过将CMAKE\u EXPORT\u COMPILE\u命令设置为ON并将run-clangtidy.py指向其目录来生成编译数据库 在这两种情况下,我都遇到了(相同的)一些可能与Clang和GCC之间的差异有关的错误: 在CMake文件中启用的某些警告标志在Clang中不受支持,但在GCC中受支持(如-wllogical op)。由于编译器是GCC,因此文件构建正确,并且标志被写入编译数据库,但clangti

我尝试了以下方法,设置
CMAKE\u CXX\u CLANG\u TIDY
。我还尝试通过将
CMAKE\u EXPORT\u COMPILE\u命令设置为
ON
并将
run-clangtidy.py
指向其目录来生成编译数据库

在这两种情况下,我都遇到了(相同的)一些可能与Clang和GCC之间的差异有关的错误:

  • 在CMake文件中启用的某些警告标志在Clang中不受支持,但在GCC中受支持(如
    -wllogical op
    )。由于编译器是GCC,因此文件构建正确,并且标志被写入编译数据库,但
    clangtidy
    对此表示不满
  • ClangTidy抱怨某些定义和函数不可用,即使代码编译得很好。例如,建议使用
    O_CLOEXEC
    提高安全性并强制关闭文件,但尝试使用此定义会导致未定义的标识符错误(即使我们的GCC编译代码)。 例如,对于未找到的函数,有
    clock\u gettime
  • 我们的代码使用C11标准和C++14标准编译,没有GNU扩展:

    set(CMAKE_C_STANDARD 11)
    set(CMAKE_CXX_STANDARD 14)
    
    set(CMAKE_C_EXTENSIONS OFF)
    set(CMAKE_CXX_EXTENSIONS OFF)
    
    自定义工具链是一个在Linux上运行并编译为FreeBSD的交叉编译工具链

  • 有没有办法禁止CMake将某些旗帜传递给clang tidy?我用叮当整理错了吗
  • 我怀疑这个问题与禁用GNU扩展、使用交叉编译工具链和某些特性测试宏有关,这些宏在默认情况下不是用Clang定义的,而是用GCC定义的(例如,
    \u GNU\u SOURCE
    /
    \u POSIX\u SOURCE
    )。如果是这种情况,我如何检查?如果不是,我应该用不同的方法来使用clang tidy吗
  • 编辑

    正如@pablo285所问的,我在一个文件中得到了两个警告,然后当我添加了
    --warningas errors=*
    时,构建停止:

    error: unknown warning option '-Wlogical-op' ; did you mean '-Wlong-long'? [clang-diagnostic-error]
    
    <file path>: error: use of undeclared identifier 'O_CLOEXEC' [clang-diagnostic-error]
    O_WRONLY | O_CLOEXEC
               ^
    
    错误:未知警告选项'-WLLogical op';你是说“龙”吗?[叮当声诊断错误]
    :错误:使用未声明的标识符“O_CLOEXEC”[clang diagnostic error]
    O_WRONLY | O_CLOEXEC
    ^
    
    我决定编写一个python脚本来替换ClangTidy,从CMake接收命令行并对其进行编辑以修复各种错误。以下是我尝试过的对命令行的修改:

  • 删除none-clang编译标志
    • 这有助于像第一个警告这样的事情,因为现在我不会传递clang不知道的标志。似乎我无法配置CMake将不同的标志集传递给GCC和ClangTidy,所以如果有人熟悉这个问题的解决方案,我很乐意听到
  • 我更改了传递给clang tidy的include目录
    • 正如在文章中提到的,我使用一个定制的工具链(交叉编译)。我使用和Python提取标准include目录的列表,并将它们作为
      -isystem
      的列表添加到标志列表中。我还添加了
      -nostdinc
      ,这样clang tidy就不会试图查看自己的标题而不是我的标题
      • 这有助于解决上述问题,因为现在工具链的头中定义了各种定义,如
        O_CLOEXEC
        ,但由于我的工具链基于GCC,clang无法解析
        头,其中包括对许多编译器内部函数的调用
    • 我不确定在这种情况下什么是最好的方法

  • @shycha:谢谢你的提示,我将尝试禁用此特定检查,然后我将再次编辑此帖子

    好的,我想我有一个解决方案。过了几个晚上,我终于成功了

    一般来说,我是这样编译的

    rm -rf build
    mkdir build
    cd build
    cmake -C ../cmake-scripts/clang-tidy-all.cmake .. && make
    
    其中
    cmake脚本
    目录包含:

    clang-tidy-all.cmake
    toolchain_arm_clang.cmake
    
    下面列出了两个重要文件。 但更重要的是,您需要如何编译它

    首先,
    toolchain\u arm\u clang.cmake
    直接从
    clang tidy all.cmake
    通过
    set(cmake\u toolchain\u文件…
    引用。但是,它必须从构建目录的角度进行引用,因此如果使用多个级别的构建目录,例如:
    build/x86
    build/arm
    build/darwin
    ,则必须相应地修改该路径

    其次,
    set(CONFIG_SCRIPT_preload…
    的目的是确保配置脚本已预加载,即
    cmake-C../cmake scripts/clang-tidy-all.cmake..
    通常,您希望在
    CMakeLists.txt
    文件中的某个地方有类似的内容:

    message(STATUS "CONFIG_SCRIPT_PRELOADED: ${CONFIG_SCRIPT_PRELOADED}")
    if(NOT CONFIG_SCRIPT_PRELOADED)
        message(FATAL_ERROR "Run cmake -C /path/to/cmake.script to preload a config script!")
    endif()
    
    第三,在
    集合中有
    /lib/ld musl armhf.so.1
    硬编码(CMAKE_LINKER_ARM_COMPAT_STATIC…
    );在我使用的开发框中,它指向
    /lib/libc.so
    ,因此可以使用
    /lib/libc.sh
    。我从来没有试过

    第四,使用
    set(CMAKE\u C\u LINK\u EXECUTABLE…)
    set(CMAKE\u LINKER\u ARM\u COMPAT\u STATIC…)
    是因为CMAKE在检查编译器期间,即甚至在运行
    make
    之前,抱怨一些链接问题

    第五,我只是在编译
    C++
    代码,所以如果您需要编译一些
    C
    ,那么可能还需要正确配置
    集(CMAKE\u C\u CREATE\u SHARED\u LIBRARY…
    ),但我不知道是否有这样的配置选项

    一般意见 不要立即集成它。首先用一个库(最好是
    C++
    one)测试一些简单的CMake项目并使其工作,然后添加第二个库,但在
    C
    中,再次调整它。只有在这之后,才能将其合并到代码库中

    工具链 我在
    gcc8.3.0
    musl
    C
    库中使用了自定义工具链,因此某些文件的位置可能会
    $ clang --version
    clang version 10.0.0 (https://github.com/llvm/llvm-project.git 4650b2f36949407ef25686440e3d65ac47709deb)
    Target: x86_64-unknown-linux-gnu
    Thread model: posix
    InstalledDir: /opt/local/bin
    
    set(ALL_CXX_WARNING_FLAGS --all-warnings -Weverything -Wno-c++98-compat -Wno-c++98-c++11-compat -Wno-c++98-c++11-c++14-compat -Wno-padded -Wno-c++98-compat-pedantic)
    set(CXX_COMPILE_OPTIONS "-std=c++17;-O3;${ALL_CXX_WARNING_FLAGS}" CACHE INTERNAL "description")
    
    
    set(CMAKE_CROSSCOMPILING True)
    set(CMAKE_TOOLCHAIN_FILE "../cmake-scripts/toolchain_arm_clang.cmake" CACHE FILEPATH "CMake toolchain file")
    
    set(CONFIG_SCRIPT_PRELOADED true CACHE BOOL "Ensures that config script was preloaded")
    
    
    set(build_test False)
    
    if(build_test)
        message(STATUS "Using test mode clang-tidy checks!")
        set(extra_clang_tidy_unchecks_for_tests_only ",-google-readability-avoid-underscore-in-googletest-name,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-special-member-functions")
    endif()
    
    set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--enable-check-profile;--checks=-*,abseil-string-find-startswith,bugprone-*,cert-*,clang-analyzer-*,cppcoreguidelines-*,google-*,hicpp-*,llvm-*,misc-*,modernize-*,-modernize-use-trailing-return-type,performance-*,readability-*,-readability-static-definition-in-anonymous-namespace,-readability-simplify-boolean-expr,portability-*${extra_clang_tidy_unchecks_for_tests_only}" CACHE INTERNAL "clang-tidy")
    
    message(STATUS "build_test: ${build_test}")
    message(STATUS "extra_clang_tidy_unchecks_for_tests_only: ${extra_clang_tidy_unchecks_for_tests_only}")
    message(STATUS "CMAKE_CXX_CLANG_TIDY: ${CMAKE_CXX_CLANG_TIDY}")
    
    # We want to skip building tests when clang-tidy is run (it takes too much time and serves nothing)
    if(DEFINED CMAKE_CXX_CLANG_TIDY AND NOT build_test)
        set(DO_NOT_BUILD_TESTS true CACHE BOOL "Turns OFF building tests")
        set(DO_NOT_BUILD_BENCHMARKS true CACHE BOOL "Turns OFF building benchmarks")
    endif()
    
    
    
    unset(build_test)
    unset(extra_clang_tidy_unchecks_for_tests_only)
    set(EXPORT_PACKAGE_TO_GLOBAL_REGISTRY "OFF" CACHE INTERNAL "We don't export clang-tidy-all version to global register")
    
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_VERSION 4.14.0)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    
    
    set(gcc_version 8.3.0)
    set(x_tools "/opt/zynq/xtl")
    
    set(CMAKE_C_COMPILER "clang" CACHE INTERNAL STRING)
    set(CMAKE_CXX_COMPILER "clang++" CACHE INTERNAL STRING)
    set(CMAKE_RANLIB "llvm-ranlib" CACHE INTERNAL STRING)
    set(CMAKE_AR "llvm-ar" CACHE INTERNAL STRING)
    set(CMAKE_AS "llvm-as" CACHE INTERNAL STRING)
    set(CMAKE_LINKER "ld.lld" CACHE INTERNAL STRING)
    
    execute_process(
        COMMAND bash -c "dirname `whereis ${CMAKE_LINKER} | tr -s ' ' '\n' | grep ${CMAKE_LINKER}`"
        OUTPUT_VARIABLE cmake_linker_dir
    )
    string(REGEX REPLACE "\n$" "" cmake_linker_dir "${cmake_linker_dir}")
    set(cmake_linker_with_dir "${cmake_linker_dir}/${CMAKE_LINKER}" CACHE INTERNAL STRING)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -iwithsysroot /include/c++/${gcc_version} -iwithsysroot /include/c++/${gcc_version}/arm-linux-musleabihf" CACHE INTERNAL STRING)
    
    
    set(CMAKE_SYSROOT ${x_tools}/arm-linux-musleabihf)
    set(CMAKE_FIND_ROOT_PATH ${x_tools}/arm-linux-musleabihf)
    set(CMAKE_INSTALL_PREFIX ${x_tools}/arm-linux-musleabihf)
    
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
    
    
    
    set(triple arm-linux-musleabihf)
    set(CMAKE_LIBRARY_ARCHITECTURE ${triple})
    set(CMAKE_C_COMPILER_TARGET ${triple})
    set(CMAKE_CXX_COMPILER_TARGET ${triple})
    
    
    set(lib_path_arm ${x_tools}/arm-linux-musleabihf/lib)
    
    ## Bootstrap library stuff:
    set(Scrt1_o ${lib_path_arm}/Scrt1.o)
    set(crti_o ${lib_path_arm}/crti.o)
    set(crtn_o ${lib_path_arm}/crtn.o)
    
    set(lib_path_gcc ${x_tools}/lib/gcc/${triple}/${gcc_version})
    set(crtbeginS_o ${lib_path_gcc}/crtbeginS.o)
    set(crtendS_o ${lib_path_gcc}/crtendS.o)
    
    
    # Clang as linker
    # --no-pie disable position independent executable, which is required when building
    # statically linked executables.
    set(CMAKE_CXX_LINK_EXECUTABLE "clang++ --target=${triple} -Wl,--no-pie --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=${cmake_linker_with_dir} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o  <TARGET> ")
    set(CMAKE_CXX_CREATE_SHARED_LIBRARY "clang++ -Wl, --target=${triple} --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=${cmake_linker_with_dir} -shared <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o  <TARGET> ")
    #
    # Do not use CMAKE_CXX_CREATE_STATIC_LIBRARY -- it is created automatically
    # by cmake using ar and ranlib
    #
    #set(CMAKE_CXX_CREATE_STATIC_LIBRARY "clang++ -Wl,--no-pie,--no-export-dynamic,-v -v --target=${triple} --sysroot=${CMAKE_SYSROOT} ${CMAKE_CXX_FLAGS} -fuse-ld=ld.lld <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o  <TARGET> ")
    
    
    ## Linker as linker
    set(CMAKE_LINKER_ARM_COMPAT_STATIC "-pie -EL -z relro -X --hash-style=gnu --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-musl-armhf.so.1 ${Scrt1_o} ${crti_o} ${crtbeginS_o} -lstdc++ -lm -lgcc_s -lgcc -lc ${crtendS_o} ${crtn_o}")
    set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_LINKER} ${CMAKE_LINKER_ARM_COMPAT_STATIC} <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o  <TARGET>")
    
    
    # Debian bug 708744(?)
    #include_directories("${CMAKE_SYSROOT}/usr/include/")
    #include_directories("${CMAKE_SYSROOT}/usr/include/c++/${gcc_version}")
    #include_directories("${CMAKE_SYSROOT}/usr/include/c++/${gcc_version}/${triple}")
    
    ## Clang workarounds:
    set(toolchain_lib_dir_0 "${CMAKE_SYSROOT}/lib")
    set(toolchain_lib_dir_1 "${CMAKE_SYSROOT}/../lib")
    set(toolchain_lib_dir_2 "${CMAKE_SYSROOT}/../lib/gcc/${triple}/${gcc_version}")
    set(CMAKE_TOOLCHAIN_LINK_FLAGS "-L${toolchain_lib_dir_0} -L${toolchain_lib_dir_1} -L${toolchain_lib_dir_2}")
    
    ## CMake workarounds
    set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "exe link flags")
    set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "module link flags")
    set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_TOOLCHAIN_LINK_FLAGS} CACHE INTERNAL "shared link flags")
    
    
    
    unset(cmake_linker_with_dir)
    unset(cmake_linker_dir)