如何“挂钩”到Cmake命令add_executable或add_library来运行额外的东西?

qjp7pelc  于 2023-05-17  发布在  其他
关注(0)|答案(3)|浏览(152)

我们使用CMake和普通的Unix makefile进行构建。有一些静态分析检查,例如:Cppcheck,我们在项目中的每个C/C++文件上运行,以在编译时捕获错误。
我已经为cppcheck创建了一个自定义目标,并将其附加到“all”目标中。这将检查项目中的所有 *.c和 *.cpp文件。
我们希望在每次文件被更改和重新编译时都运行一次检查,并且只在该文件上运行。检查应该自动运行,用户不必在CMake中添加额外的命令。本质上,检查应该“附加/挂钩”到普通的CMake命令add_library()add_executable()。有没有办法在CMake中做到这一点?

mftmpeh8

mftmpeh81#

虽然add_executable(和add_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)
jc3wubiy

jc3wubiy2#

假设你有一个源文件列表(你应该有)。
使用for_each循环迭代源文件。对于每个源文件,使用add_custom_command对文件运行cppcheck工具。使custom_command依赖于当前循环中的文件。现在,您应该有针对所有单个源文件的自定义命令,当且仅当文件因DEPENDS指令而更改时,才会触发这些命令。
并不是说这些命令必须创建某种输出文件。我建议将cppcheck的输出通过管道传输到名为$source$_test的文件中。
文件:https://cmake.org/cmake/help/latest/command/add_custom_command.html

rxztt3cl

rxztt3cl3#

您可以从tacklelib库尝试连接功能:https://github.com/andry81/tacklelib/blob/master/cmake/tacklelib/Handlers.cmake
我不保证它会对系统函数起作用,但你可以按照测试中的示例进行尝试:https://github.com/andry81/tacklelib/blob/master/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")

相关问题