Использование clang-tidy с проектом CMake только для заголовка

Я работаю над библиотекой только для заголовков и хотел бы использовать clang-tidy, чтобы убедиться, что я соблюдаю основные принципы C ++ https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

Независимо от того, что я пытаюсь, мне кажется, что я не могу работать с библиотекой только для заголовков (вероятно, потому, что на самом деле ничего не компилируется, пока библиотека не будет использована) ... Но должен быть какой-то обходной путь, чтобы эта работа работала правильно . Наверняка кто-то еще написал библиотеку только для заголовков, в которой они хотели бы использовать clang-tidy.

Чтобы попытаться упростить проблему, я сделал небольшой тестовый проект, чтобы попытаться заставить его работать. Этот проект состоит всего из двух файлов. Файл CMakeLists.txt и файл заголовка.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.11.4)

project(my_project LANGUAGES CXX)

# This does not seem to work at all for header only libraries
# I even tried messing with the "-header-filter" parameter and had no luck
set(CMAKE_CXX_CLANG_TIDY clang-tidy;-checks=-*,cppcoreguidelines-*)

add_library(my_project INTERFACE)

target_include_directories(my_project
  INTERFACE
    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

включить / my_project.hpp:

#include <iostream>

// I know it is bad to do this in a header file.
// This is intentional to give clang-tidy something to catch
using namespace std;

template <int N>
void print()
{
    for (int i = 0; i < N; ++i)
    {
        cout << "Hello, world!" << endl;
    }
}

Когда я запускаю CMake с:

mkdir build
cd build
cmake ..
cmake --build .

Я не получаю вывода от clang-tidy. Как я могу сделать упорядоченные библиотеки синтаксического анализа только заголовков и сообщить о потенциальных проблемах?


person tjwrona1992    schedule 18.12.2020    source источник
comment
Неужто вы пишете тесты для своей библиотеки, и эти тесты являются исходными файлами? Убери их!   -  person rubenvb    schedule 21.12.2020
comment
Я пробовал это, и он работает с этими файлами .cpp, но ни один из заголовков не улавливается. Я пробовал несколько разных значений для --header-filter, и ничего не работало. (Все они находятся в папке include /.) Другая проблема заключается в том, что все тестовые файлы используют Catch2 и содержат множество макросов, которые выдают все виды предупреждений о лязгах. В идеале я бы хотел также игнорировать все, что связано с Catch2. (Или просто игнорируйте тестовые файлы, продолжая обрабатывать заголовки)   -  person tjwrona1992    schedule 21.12.2020


Ответы (2)


По умолчанию clang-tidy не проверяет ваши файлы заголовков. . Таким образом, необходимо использовать -header-filter=.*, чтобы указать корневой путь для файлов заголовков.

Не подробный clang-tidy вывод не означает, что он не выполняется. Эта конфигурация отсутствует -header-filter=.*, но даже с этим флагом, когда вы выполняете cmake --build ., он ничего не выводит. Однако, если вы найдете эту команду в пути сборки с помощью grep (например), вы должны получить что-то вроде:

❯ grep -nrw '.' -e "clang-tidy"
./CMakeFiles/my_project.dir/build.make:63:  $(CMAKE_COMMAND) -E __run_co_compile --tidy="clang-tidy;-checks=-*,cppcoreguidelines-*;-header-filter=.*" --source=/home/markoshorro/tmp/tidy/my_project.cpp -- /usr/bin/c++  $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/my_project.dir/my_project.cpp.o -c /home/markoshorro/tmp/tidy/my_project.cpp

Это означает, что рассматривается команда clang-tidy. Собственно, с вашего примера:

❯ clang-tidy my_project.hpp
❯

То есть я ничего не получаю. Взгляните на этот пример (хотя мне кажется, что ваш пример подходит) ; просто clang-tidy не о чем сообщить.

person horro    schedule 21.12.2020
comment
Хм, я предполагал, что использование пространства имен в заголовке определенно будет рассматриваться как проблема, ха-ха, я посмотрю на ваш пример и поиграю с ним в Windows, чтобы увидеть, сработает ли он для меня. - person tjwrona1992; 21.12.2020
comment
Как ни странно, если я компилирую это в среде Visual Studio IDE, он показывает предупреждения с выводом clang-tidy, но если я скомпилирую его из командной строки, я ничего не получу. - person tjwrona1992; 22.12.2020
comment
В любом случае, это настоящий проект, над которым я пытаюсь заставить это работать: github.com/tnt-coders/cpp-dsp/tree/clang-tidy Я использую предварительную версию Visual Studio 2019 в качестве среды IDE для ее компиляции, и она генерирует предупреждения только для всех тестовых файлов .cpp, но ни одного заголовков независимо от того, что я поставил для -header-filter. В конечном итоге я хочу, чтобы он игнорировал любые предупреждения, связанные с Catch2, и показывал все остальное, но я не могу найти хороший способ даже заставить его распознавать мои заголовки, не говоря уже о игнорировании конкретных предупреждений для определенных файлов. - person tjwrona1992; 22.12.2020
comment
На самом деле, переключение -header-filter на просто включение, казалось, улавливало все! ... По-прежнему существует проблема со всеми макросами Catch2, вызывающими большое количество предупреждений, которые я хотел бы подавить, хотя это не мой собственный код. - person tjwrona1992; 22.12.2020
comment
Для этого вы можете, например, использовать -exclude-header-filter=.... Другой обходной путь - set(CMAKE_CXX_CLANG_TIDY "") перед find_package и снова включить его после. - person horro; 23.12.2020
comment
Спасибо за совет! В идеале я хотел бы просто установить -header-filter на что-то вроде include/tnt/dsp, чтобы он собирал файлы только в этой конкретной папке include, но когда я добавляю /, он не может найти ВСЕ заголовки ... (Я также пробовал экранировать косую черту с помощью обратной косой черты и использовать обратную косую черту, а также использовать экранированную обратную косую черту и т.д ... lol). Это кажется неправильным, потому что другие примеры, которые я видел, могут предоставлять пути с косой чертой для фильтра заголовков, и они, по-видимому, работают нормально. - person tjwrona1992; 23.12.2020
comment
Я награждаю вас наградой, потому что этот ответ помог мне больше всего, хотя я все еще сталкиваюсь с некоторыми проблемами. На этом этапе, возможно, пришло время просто обратиться к списку рассылки разработчиков LLVM. - person tjwrona1992; 28.12.2020

У меня сработала следующая команда:

find . -type f \( -name "*.hpp" -o -name "*.cpp" \) \
   -exec clang-tidy -p . \
   --header-filter="/home/user/clang-tidy-include-headers/header.hpp" {} \;

Он ищет файлы заголовков и CPP, передает их в clang-tidy. Параметр --header-filter= принимает регулярное выражение для путей к файлам заголовков.

В вашем случае это будет:

find . -type f \( -name "*.hpp" -o -name "*.cpp" \) \
   -exec clang-tidy -p . \
   --header-filter="include/" {} \;
person fsquirrel    schedule 20.12.2020
comment
Похоже, у меня это не работает. Думаю, это потому, что я строю на Windows. Я попытался запустить clang-tidy с этими параметрами и явно указать файлы для его запуска (поскольку команда find работает иначе в Windows), и я получаю сообщение об ошибке Ошибка при попытке загрузить базу данных компиляции ... документация CMake. Я могу экспортировать json-файл базы данных компиляции, используя -DCMAKE_EXPORT_COMPILE_COMMANDS, но, похоже, это не работает с генератором Visual Studio для CMake. - person tjwrona1992; 21.12.2020
comment
@ tjwrona1992, никогда не пробовал запускать clang в Windows. Однако я уверен, что существует расширение Visual Studio, генерирующее базу данных компиляции (в конце концов, это просто файл JSON с флагами компиляции для каждой единицы компиляции). Что касается сценария bash, новые версии Windows AFAIK поддерживают bash и другие инструменты Linux. - person fsquirrel; 21.12.2020