Commit 7cf79f44 authored by Alex Turbov's avatar Alex Turbov Committed by Craig Scott

message: Support logging a context with each message

parent 5bf85e25
......@@ -63,11 +63,22 @@ To make a log level persist between CMake runs, the
:variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can be set instead.
Note that the command line option takes precedence over the cache variable.
Messages of log levels ``NOTICE`` and below will also have each line preceded
Messages of log levels ``NOTICE`` and below will have each line preceded
by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
a single string by concatenating its list items). For ``STATUS`` to ``TRACE``
messages, this indenting content will be inserted after the hyphens.
Messages of log levels ``NOTICE`` and below can also have each line preceded
with context of the form ``[some.context.example]``. The content between the
square brackets is obtained by converting the :variable:`CMAKE_MESSAGE_CONTEXT`
list variable to a dot-separated string. The message context will always
appear before any indenting content but after any automatically added leading
hyphens. By default, message context is not shown, it has to be explicitly
enabled by giving the :manual:`cmake <cmake(1)>` ``--log-context``
command-line option or by setting the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
variable to true. See the :variable:`CMAKE_MESSAGE_CONTEXT` documentation for
usage examples.
CMake Warning and Error message text displays using a simple markup
language. Non-indented text is formatted in line-wrapped paragraphs
delimited by newlines. Indented text is considered pre-formatted.
......@@ -204,6 +204,8 @@ Variables that Change Behavior
/variable/CMAKE_LINK_DIRECTORIES_BEFORE
/variable/CMAKE_MFC_FLAG
/variable/CMAKE_MAXIMUM_RECURSION_DEPTH
/variable/CMAKE_MESSAGE_CONTEXT
/variable/CMAKE_MESSAGE_CONTEXT_SHOW
/variable/CMAKE_MESSAGE_INDENT
/variable/CMAKE_MESSAGE_LOG_LEVEL
/variable/CMAKE_MODULE_PATH
......
......@@ -214,6 +214,16 @@ Options
For backward compatibility reasons, ``--loglevel`` is also accepted as a
synonym for this option.
``--log-context``
Enable the :command:`message` command outputting context attached to each
message.
This option turns on showing context for the current CMake run only.
To make showing the context persistent for all subsequent CMake runs, set
:variable:`CMAKE_MESSAGE_CONTEXT_SHOW` as a cache variable instead.
When this command line option is given, :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
is ignored.
``--debug-trycompile``
Do not delete the :command:`try_compile` build tree.
Only useful on one :command:`try_compile` at a time.
......
......@@ -4,3 +4,8 @@ feature-CMAKE_MESSAGE_CONTEXT
* The :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can now be used
to persist a log level between CMake runs, unlike the ``--log-level``
command line option which only applies to that particular run.
* The :command:`message` command learned to output context provided in
the :variable:`CMAKE_MESSAGE_CONTEXT` variable for log levels
``NOTICE`` and below. Enable this output with the new ``--log-context``
command-line option or :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable.
CMAKE_MESSAGE_CONTEXT
---------------------
When enabled by the :manual:`cmake <cmake(1)>` ``--log-context`` command line
option or the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable, the
:command:`message` command converts the ``CMAKE_MESSAGE_CONTEXT`` list into a
dot-separated string surrounded by square brackets and prepends it to each line
for messages of log levels ``NOTICE`` and below.
For logging contexts to work effectively, projects should generally
``APPEND`` and ``POP_BACK`` an item to the current value of
``CMAKE_MESSAGE_CONTEXT`` rather than replace it.
Projects should not assume the message context at the top of the source tree
is empty, as there are scenarios where the context might have already been set
(e.g. hierarchical projects).
.. warning::
Valid context names are restricted to anything that could be used
as a CMake variable name. All names that begin with an underscore
or the string ``cmake_`` are also reserved for use by CMake and
should not be used by projects.
Example:
.. code-block:: cmake
function(bar)
list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
message(VERBOSE "bar VERBOSE message")
endfunction()
function(baz)
list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
message(DEBUG "baz DEBUG message")
endfunction()
function(foo)
list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
bar()
message(TRACE "foo TRACE message")
baz()
endfunction()
list(APPEND CMAKE_MESSAGE_CONTEXT "top")
message(VERBOSE "Before `foo`")
foo()
message(VERBOSE "After `foo`")
list(POP_BACK CMAKE_MESSAGE_CONTEXT)
Which results in the following output:
.. code-block:: none
-- [top] Before `foo`
-- [top.foo.bar] bar VERBOSE message
-- [top.foo] foo TRACE message
-- [top.foo.baz] baz DEBUG message
-- [top] After `foo`
CMAKE_MESSAGE_CONTEXT_SHOW
--------------------------
Setting this variable to true enables showing a context with each line
logged by the :command:`message` command (see :variable:`CMAKE_MESSAGE_CONTEXT`
for how the context itself is specified).
This variable is an alternative to providing the ``--log-context`` option
on the :manual:`cmake <cmake(1)>` command line. Whereas the command line
option will apply only to that one CMake run, setting
``CMAKE_MESSAGE_CONTEXT_SHOW`` to true as a cache variable will ensure that
subsequent CMake runs will continue to show the message context.
Projects should not set ``CMAKE_MESSAGE_CONTEXT_SHOW``. It is intended for
users so that they may control whether or not to include context with messages.
......@@ -112,16 +112,25 @@ bool cmMessageCommand(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
if (cmake::LogLevel::LOG_NOTICE <= level) {
// Check if any indentation has requested:
// `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
// to be joined and prepended to the message lines.
auto indent =
cmJoin(cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT")), "");
// Make every line of the `message` indented
// NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
// here cuz it appends `\n` to the EOM ;-(
cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
message = indent + message;
if (!indent.empty()) {
cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
message = indent + message;
}
const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
if (showContext) {
// Output the current context (if any)
auto context = cmJoin(
cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT")), ".");
if (!context.empty()) {
context = "[" + context + "] ";
cmSystemTools::ReplaceString(message, "\n", "\n" + context);
message = context + message;
}
}
}
switch (level) {
......
......@@ -746,6 +746,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetLogLevel(logLevel);
this->LogLevelWasSetViaCLI = true;
} else if (arg == "--log-context") {
this->SetShowLogContext(true);
} else if (arg.find("--trace-expand", 0) == 0) {
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
......
......@@ -391,6 +391,10 @@ public:
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
//! Should `message` command display context.
bool GetShowLogContext() const { return this->LogContext; }
void SetShowLogContext(bool b) { this->LogContext = b; }
//! Do we want trace output during the cmake run.
bool GetTrace() { return this->Trace; }
void SetTrace(bool b) { this->Trace = b; }
......@@ -590,6 +594,7 @@ private:
LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
bool LogLevelWasSetViaCLI = false;
bool LogContext = false;
void UpdateConversionPathTable();
......
......@@ -73,6 +73,7 @@ const char* cmDocumentationOptions[][2] = {
{ "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
"Set the verbosity of messages from CMake files. "
"--loglevel is also accepted for backward compatibility reasons." },
{ "--log-context", "Prepend log messages with context, if given" },
{ "--debug-trycompile",
"Do not delete the try_compile build tree. Only "
"useful on one try_compile at a time." },
......
......@@ -68,3 +68,18 @@ run_cmake_command(
message-indent-multiline
${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent-multiline.cmake
)
run_cmake_command(
message-context-cli
${CMAKE_COMMAND} --log-level=trace --log-context -P ${RunCMake_SOURCE_DIR}/message-context.cmake
)
run_cmake_command(
message-context-cache
${CMAKE_COMMAND} -DCMAKE_MESSAGE_LOG_LEVEL=TRACE -DCMAKE_MESSAGE_CONTEXT_SHOW=ON -P ${RunCMake_SOURCE_DIR}/message-context.cmake
)
run_cmake_command(
message-context-cli-wins-cache
${CMAKE_COMMAND} --log-level=verbose --log-context -DCMAKE_MESSAGE_CONTEXT_SHOW=OFF -P ${RunCMake_SOURCE_DIR}/message-context.cmake
)
-- Begin context output test
-- \[top\] Top: before
-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
-- \[top\.foo\] foo TRACE message
-- \[top\.foo\.baz\] This is the multi-line
\[top\.foo\.baz\] baz DEBUG message
-- \[top\] Top: after
-- End of context output test
-- Begin context output test
-- \[top\] Top: before
-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
-- \[top\.foo\] foo TRACE message
-- \[top\.foo\.baz\] This is the multi-line
\[top\.foo\.baz\] baz DEBUG message
-- \[top\] Top: after
-- End of context output test
-- Begin context output test
-- \[top\] Top: before
-- \[top\.foo\.bar\] <-- indent -->bar VERBOSE message
-- \[top\] Top: after
-- End of context output test
function(bar)
list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
list(APPEND CMAKE_MESSAGE_INDENT "<-- indent -->")
message(VERBOSE "bar VERBOSE message")
endfunction()
function(baz)
list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
message(DEBUG "This is the multi-line\nbaz DEBUG message")
endfunction()
function(foo)
list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
bar()
message(TRACE "foo TRACE message")
baz()
endfunction()
message(STATUS "Begin context output test")
list(APPEND CMAKE_MESSAGE_CONTEXT "top")
message(STATUS "Top: before")
foo()
message(STATUS "Top: after")
list(POP_BACK CMAKE_MESSAGE_CONTEXT)
message(STATUS "End of context output test")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment