Skip to content

Commit b25da0a

Browse files
committed
Merge branch 'main' into add-build-info
2 parents 6a19863 + 1b75a30 commit b25da0a

File tree

9 files changed

+1325
-11
lines changed

9 files changed

+1325
-11
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
* `dependencies.cmake` and `dev-dependencies.cmake` scripts.
1414
* `CPM.cmake` script that downloads specified version of [CPM](https://github.com/cpm-cmake/CPM.cmake).
1515
* `fail_in_source_build()`, `extract_value()`, `requires_arguments()` and `safeguard_properties()` utils functions, in `helpers.cmake`.
16-
* `dump()` and `dd()` in `debug.cmake`.
16+
* `dump()`, `dd()` and `var_dump()` in `debug.cmake`.
1717
* ANSI utils, in `output.cmake`
1818
* `semver_parse()`, `write_version_file` and `version_from_file()` utils, in `version.cmake`.
1919
* `git_find_version_tag()` util, in `git.cmake`.
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
* `output()` helper, in `output.cmake`.
2424
* Support for ANSI, in `output.cmake`.
2525
* PSR inspired logging functions, in `logging.cmake`.
26+
* Utils for determining the datatype of a target variable or value, in `helpers.cmake`.
2627
* A "mini" testing framework for cmake modules and scripts, in `testing.cmake`.
2728
* `RSP_CMAKE_SCRIPTS_BUILD_TESTS` project option for building tests.
2829
* `tests.yaml` and `deploy-docs.yaml` GitHub Actions workflows.

cmake/rsp/debug.cmake

+165-10
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,191 @@ include_guard(GLOBAL)
88
message(VERBOSE "rsp/debug module included")
99

1010
include("rsp/output/utils")
11+
include("rsp/helpers")
1112

1213
if (NOT COMMAND "dump")
1314

1415
#! dump : Outputs given variables' name and value
1516
#
17+
# Note: function outputs using cmake's WARNING message mode
18+
#
19+
# @see https://cmake.org/cmake/help/latest/command/message.html#general-messages
20+
# @see var_dump()
21+
#
1622
# @param ... Variables to output
1723
#
1824
function(dump)
19-
foreach (var ${ARGN})
20-
message("${var} = ${${var}}")
21-
endforeach ()
25+
var_dump(OUTPUT output PROPERTIES ${ARGN})
26+
27+
# Attempt to keep the formatting - see details in rsp/output::output()
28+
string(ASCII 13 CR)
29+
set(formatted_output "${CR}${COLOR_WHITE}dump:${RESTORE}\n${output}")
30+
string(REPLACE "\n" "\n " formatted_output "${formatted_output}")
2231

23-
# Output as warning so that the developer is able to see call stack!
24-
message(WARNING " ${CMAKE_CURRENT_FUNCTION}() called from ${CMAKE_CURRENT_LIST_FILE}")
32+
message(WARNING "${formatted_output}")
2533
endfunction()
2634
endif ()
2735

2836
if (NOT COMMAND "dd")
2937

30-
#! dump and die: Outputs given variables' name and value and stops build
38+
#! dd: Outputs given variables' name and value and stops build (dump and die)
39+
#
40+
# Note: function outputs using cmake's FATAL_ERROR message mode
41+
#
42+
# @see https://cmake.org/cmake/help/latest/command/message.html#general-messages
43+
# @see var_dump()
3144
#
3245
# @param ... Variables to output
3346
#
3447
function(dd)
35-
foreach (var ${ARGN})
36-
message("${var} = ${${var}}")
48+
var_dump(OUTPUT output PROPERTIES ${ARGN})
49+
50+
# Attempt to keep the formatting - see details in rsp/output::output()
51+
string(ASCII 13 CR)
52+
set(formatted_output "${CR}${COLOR_WHITE}dd:${RESTORE}\n${output}")
53+
string(REPLACE "\n" "\n " formatted_output "${formatted_output}")
54+
55+
message(FATAL_ERROR "${formatted_output}")
56+
endfunction()
57+
endif ()
58+
59+
if (NOT COMMAND "var_dump")
60+
61+
#! var_dump : Outputs human-readable information about given properties
62+
#
63+
#
64+
# @param [OUTPUT <variable>] Optional - If specified, information is assigned to output variable
65+
# instead of being printed to stderr.
66+
# @param [PROPERTIES <variable>...] One or more variables to dump information about.
67+
# @param [WITHOUT_NAMES] Option, if given then property names are omitted from the output
68+
# @param [IGNORE_LIST] Option, if specified the variable values of the type "list" are
69+
# treated as "string".
70+
#
71+
# @return
72+
# [OUTPUT] The resulting output variable, if OUTPUT was specified.
73+
#
74+
function(var_dump)
75+
set(options WITHOUT_NAMES IGNORE_LIST)
76+
set(oneValueArgs OUTPUT)
77+
set(multiValueArgs PROPERTIES)
78+
79+
cmake_parse_arguments(INPUT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
80+
requires_arguments("PROPERTIES" INPUT)
81+
82+
# ---------------------------------------------------------------------------------------------- #
83+
84+
set(buffer "")
85+
86+
foreach (key IN LISTS INPUT_PROPERTIES)
87+
# Attempt to resolve value and it's datatype
88+
set(value "${${key}}")
89+
get_type("${key}" type)
90+
91+
# ---------------------------------------------------------------------------------------------- #
92+
93+
set(tmp_list_separator "<!list!>")
94+
if (INPUT_IGNORE_LIST AND type STREQUAL "list")
95+
# Debug
96+
#message("Ignoring list: ${key} | ${value}")
97+
98+
set(type "string")
99+
string(REPLACE ";" "${tmp_list_separator}" value "${value}")
100+
endif ()
101+
102+
# ---------------------------------------------------------------------------------------------- #
103+
104+
# If key is defined as an environment variable, the value
105+
# must be obtained via ENV{}.
106+
if (DEFINED ENV{${key}})
107+
set(value "$ENV{${key}}")
108+
get_type("${value}" type)
109+
elseif (NOT DEFINED ${key} AND type STREQUAL "string")
110+
# We ONLY deal with variables, meaning that if key isn't
111+
# defined, and the type is determined to be a string,
112+
# then we must assume that it's an undefined property!
113+
114+
set(type "${COLOR_RED}${TEXT_ITALIC}undefined${TEXT_ITALIC_RESTORE}${COLOR_DEFAULT}")
115+
endif ()
116+
117+
# Format the value...
118+
if (type STREQUAL "string")
119+
# Resolve string length, by ensuring to count the length of
120+
# the original value, without list separator replacement.
121+
set(tmp_str "${value}")
122+
string(REPLACE "${tmp_list_separator}" ";" tmp_str "${tmp_str}")
123+
string(LENGTH "${tmp_str}" str_length)
124+
125+
set(type "${type} ${str_length}")
126+
set(value "${COLOR_GREEN}\"${value}\"${RESTORE}")
127+
elseif (type STREQUAL "int" OR type STREQUAL "float")
128+
set(value "${COLOR_BRIGHT_BLUE}${value}${RESTORE}")
129+
elseif (type STREQUAL "bool")
130+
set(value "${COLOR_CYAN}${value}${RESTORE}")
131+
elseif (type STREQUAL "command")
132+
set(value "${COLOR_BLUE}${key}()${RESTORE}")
133+
elseif (type STREQUAL "list")
134+
list(LENGTH value lst_length)
135+
set(type "${type} ${lst_length}")
136+
set(list_buffer "")
137+
138+
set(i 0) # index counter
139+
foreach (item IN LISTS value)
140+
# Get property information about the "item", but without key name.
141+
# Also, ensure to ignore values of the type "list", to avoid
142+
# strange behaviour (caused by cmake's variable scopes...)
143+
set("list_item_${i}" "${item}")
144+
var_dump(OUTPUT list_item WITHOUT_NAMES IGNORE_LIST PROPERTIES "list_item_${i}")
145+
146+
# Append to list buffer and increment the "index" counter.
147+
list(APPEND list_buffer "${COLOR_MAGENTA}${i}:${RESTORE} ${list_item}")
148+
math(EXPR i "${i}+1" OUTPUT_FORMAT DECIMAL)
149+
endforeach ()
150+
151+
string(REPLACE ";" "\n " list_buffer "${list_buffer}")
152+
set(value "[ \n ${list_buffer}\n]")
153+
endif ()
154+
155+
# Mark the key as cached, if needed...
156+
if(DEFINED CACHE{${key}})
157+
set(type "${type}, ${TEXT_ITALIC}${TEXT_BOLD}cached${TEXT_BOLD_RESTORE}${TEXT_ITALIC_RESTORE}")
158+
endif ()
159+
160+
# Mark the key an environment variable, if needed...
161+
if(DEFINED ENV{${key}})
162+
set(type "${type}, ${TEXT_ITALIC}${TEXT_BOLD}ENV${TEXT_BOLD_RESTORE}${TEXT_ITALIC_RESTORE}")
163+
endif ()
164+
165+
# The output format: <key> = (<type>) <value>
166+
# Unless key is omitted.
167+
set(formatted_key "${COLOR_BRIGHT_MAGENTA}${key}${RESTORE} = ")
168+
if (INPUT_WITHOUT_NAMES)
169+
set(formatted_key "")
170+
endif ()
171+
172+
list(APPEND buffer "${formatted_key}${COLOR_WHITE}(${type}${COLOR_WHITE})${RESTORE} ${value}")
37173
endforeach ()
38174

39-
# Output as fatal error to ensure that build stops.
40-
message(FATAL_ERROR " ${CMAKE_CURRENT_FUNCTION}() called from ${CMAKE_CURRENT_LIST_FILE}")
175+
# ---------------------------------------------------------------------------------------------- #
176+
177+
string(REPLACE ";" "\n" buffer "${buffer}")
178+
179+
# Restore list value (as a string) if needed.
180+
if (INPUT_IGNORE_LIST)
181+
string(REPLACE "${tmp_list_separator}" ";" buffer "${buffer}")
182+
endif ()
183+
184+
# ---------------------------------------------------------------------------------------------- #
185+
186+
# Assign to output variable, if requested and stop any further processing.
187+
if (DEFINED INPUT_OUTPUT)
188+
set("${INPUT_OUTPUT}" "${buffer}")
189+
return(PROPAGATE "${INPUT_OUTPUT}")
190+
endif ()
191+
192+
# ---------------------------------------------------------------------------------------------- #
193+
194+
message(NOTICE "${buffer}")
195+
41196
endfunction()
42197
endif ()
43198

cmake/rsp/helpers.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ include_guard(GLOBAL)
77
# Debug
88
message(VERBOSE "rsp/helpers module included")
99

10+
include("rsp/helpers/types")
11+
1012
if (NOT COMMAND "fail_in_source_build")
1113

1214
#! fail_in_source_build : Fails when building project in the source directory

0 commit comments

Comments
 (0)