Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to write improved cmake logging macro with position information?

Tags:

c++

cmake

All the time when debugging cmake code, I find myself writing things like the following:

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

In C++, I use macros to automatically log the file name and line number - is this possible in cmake? Ideally, I'd like to write a macro that with the following:

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

It would print to console:

|info   | some_filename.cmake[72] some message about what is going on here.
like image 458
rich.e Avatar asked Aug 13 '16 03:08

rich.e


2 Answers

With CMAKE_CURRENT_LIST_FILE and CMAKE_CURRENT_LIST_LINE this should be possible.
However, using CMAKE_CURRENT_LIST_LINE directly in the macro will always give you the line in the macro, not where the macro was used (at least with CMake 3.6.1). Thus you need to pass it as an argument:

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)

And use it as

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

A more advanced solution would be:

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)

Usage:

log(debug ${CMAKE_CURRENT_LIST_LINE} "debug info")
log(Info ${CMAKE_CURRENT_LIST_LINE} "info message")
log(ERROR ${CMAKE_CURRENT_LIST_LINE} "error message")
like image 140
Torbjörn Avatar answered Oct 16 '22 19:10

Torbjörn


I don't think this is possible in a general manner. CMake does not offer much help with regard to debugging or introspection.
I can imagine a macro that uses global variables which must be added by the user at the beginning of each macro or function. In the end, it wouldn't reduce the amount of manual work but clutter the code.

Maybe you can use a function / macro of your editor. Some editors can insert the current file name, the current time stamp or a pseudo-random UUID by key stroke. Whenever you want to log a message, just add the value and you can later search the code for this unique sequence. Nut sure whether this is a better workflow for you.

The best place would be a feature request for CMake. You are not the only one who could profit from such a feature. Maybe Kitware or someone else is willing to develop and upstream a log macro.

like image 33
usr1234567 Avatar answered Oct 16 '22 19:10

usr1234567