可以使用位置信息编写改进的cmake日志宏

Possible to write improved cmake logging macro with position information?

本文关键字:cmake 日志 位置 信息 可以使      更新时间:2023-10-16

在调试cmake代码时,我发现自己总是这样写:

message( "[some_filename.cmake]: some message about what is going on here." )

在c++中,我使用宏来自动记录文件名和行号-这在cmake中可能吗?理想情况下,我想写一个宏,具有以下内容:

log_info( "some message about what is going on here." )

输出到控制台:

|info   | some_filename.cmake[72] some message about what is going on here.

对于CMAKE_CURRENT_LIST_FILECMAKE_CURRENT_LIST_LINE,这应该是可能的。
然而,在宏中直接使用CMAKE_CURRENT_LIST_LINE总是会给你宏中的行,而不是宏被使用的地方(至少在CMake 3.6.1中)。因此,您需要将其作为参数传递:

macro(log_info _line)
  # get the path of the CMakeLists file evaluating this macro
  #  relative to the project's root source directory 
  file(RELATIVE_PATH _curr_file
       "${PROJECT_SOURCE_DIR}"
       "${CMAKE_CURRENT_LIST_FILE}")
  message("|info   | ${_curr_file}[${_line}] ${ARGN}")
endmacro(log_info)

使用

log_info(${CMAKE_CURRENT_LIST_LINE} "a info message")

更高级的解决方案是:

macro(log _level _line)
  # get the path of the CMakeLists file evaluating this macro
  #  relative to the project's root source directory 
  file(RELATIVE_PATH _curr_file
       "${PROJECT_SOURCE_DIR}"
       "${CMAKE_CURRENT_LIST_FILE}")
  set(level_padded "      ")
  if("${_level}" MATCHES [Dd][Ee][Bb][Uu][Gg])
    set(level_padded "debug ")
  elseif("${_level}" MATCHES [Ii][Nn][Ff][Oo])
    set(level_padded "info  ")
  elseif("${_level}" MATCHES [Ee][Rr][Rr][Oo][Rr])
    set(level_padded "error ")
  endif()
  message("|${level_padded} | ${_curr_file}[${_line}] ${ARGN}")
endmacro(log)

用法:

log(debug ${CMAKE_CURRENT_LIST_LINE} "debug info")
log(Info ${CMAKE_CURRENT_LIST_LINE} "info message")
log(ERROR ${CMAKE_CURRENT_LIST_LINE} "error message")

我认为这在一般情况下是不可能的。CMake在调试或自省方面没有提供太多帮助。
我可以想象一个使用全局变量的宏,这些全局变量必须由用户在每个宏或函数的开头添加。最后,它不会减少手工工作的数量,反而会使代码混乱。

也许你可以使用你的编辑器的函数/宏。一些编辑器可以通过按键插入当前文件名、当前时间戳或伪随机UUID。每当您想要记录一条消息时,只需添加该值,然后就可以在代码中搜索这个唯一序列。我不确定这是不是一个更好的工作流程。

最好的地方是CMake的功能请求。您并不是唯一一个可以从这种特性中获利的人。也许Kitware或其他人愿意开发和上游log