Как «подключиться» к команде Cmake add_executable или add_library, чтобы запустить что-то дополнительное?

Мы собираем с помощью CMake и обычных make-файлов Unix. Есть некоторые проверки статического анализа, например. Cppcheck, мы запускаем каждый файл C/C++ в проекте, чтобы отлавливать ошибки во время компиляции.

Я создал пользовательскую цель для cppcheck и прикрепил ее к цели «все». Это проверяет все файлы *.c и *.cpp в проекте.

Мы хотим запускать проверку каждый раз, когда файл изменяется и перекомпилируется, и только в этом файле. Проверка должна запускаться автоматически и пользователю не нужно добавлять дополнительные команды в CMake. По сути, проверка должна быть «привязана/подключена» к обычным командам CMake add_library() и add_executable(). Есть ли способ сделать это в CMake?

Это встроенные функции cmake. Если вам нужна пользовательская функциональность, вам обычно нужно отредактировать файл CMakeLists.txt. Вот где живет пользовательский код.

ruipacheco 17.04.2019 10:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
1 093
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Хотя add_executableadd_library) предоставляется самим CMake, вы можете определить функцию или макрос с тем же именем, который «скроет» исходную функцию CMake. Внутри вашей функции/макроса вы можете вызвать исходную функцию CMake, используя имя с префиксом подчеркивания:

function(add_executable target_name)
   # Call the original function
   _add_executable(${target_name} ${ARGN})
   ... perform additional steps...
endfunction(add_executable target_name)

Предполагая, что у вас есть список исходных файлов (что вам и нужно).

Переберите исходные файлы с помощью цикла for_each. Для каждого исходного файла используйте команду add_custom_command, которая запустит инструмент cppcheck для файла. Сделайте эту custom_command зависимой от файла в текущем цикле. Теперь у вас должны быть пользовательские команды для всех отдельных исходных файлов, которые будут срабатывать, если и только если файлы изменятся из-за инструкции DEPENDS.

Не то чтобы эти команды должны были создать какой-то выходной файл. Я предлагаю направить вывод cppcheck в файл с именем $source$_test.

Документация: https://cmake.org/cmake/help/latest/command/add_custom_command.html

Вы можете попробовать функциональность подключения из библиотеки снастей: https://sf.net/p/tacklelib/tacklelib/HEAD/tree/trunk/cmake/tacklelib/Handlers.cmake

Я не гарантирую, что это сработает для системной функции, но вы можете попробовать, следуя примерам из тестов: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/cmake_tests/unit/01_script_mode/11_Handlers/

Некоторые примеры из тестов:

include(tacklelib/Handlers)
include(tacklelib/Props)

# handler we want to attach
macro(custom_pre_handler)
  tkl_test_assert_true("a STREQUAL \"111\"" "1 call context variables is not visible: a=${a}")

  tkl_append_global_prop(. call_sequence -1)
endmacro()

# macro function where the handler should be attached
macro(custom_macro)
  tkl_test_assert_true("a STREQUAL \"111\"" "2 call context variables is not visible: a=${a}")

  tkl_append_global_prop(. call_sequence 0)
endmacro()

# registering context for target to attach
tkl_enable_handlers(PRE_POST function custom_macro)

# attaching, PRE - before the call
tkl_add_last_handler(PRE custom_macro custom_pre_handler)

# testing attachment, custom_pre_handler must be called before custom_macro
set(a 111)

custom_macro()

# the last state
tkl_get_global_prop(call_sequence call_sequence 0)

# the call order test
tkl_test_assert_true("call_sequence STREQUAL \"-1;0\"" "call sequence is invalid: call_sequence=${call_sequence}")

# a cmake test internally wrapped into a function
return()

tkl_test_assert_true(0 "unreachable code")

Хотя эти ссылки полезны, лучше включить части существенный из этих источников в сам ответ на пост. Ссылка может со временем устареть, и ваш ответ станет менее полезным. Если возможно, приведите пример использования.

Kevin 13.02.2020 13:54

@squareskittles На самом деле здесь слишком много исходного кода, чтобы включать его. Я могу привести здесь лишь крошечный пример, который в любом случае мало что покажет. С другой стороны, пример со временем может измениться и потерять актуальность.

Andry 13.02.2020 15:02

Другие вопросы по теме