1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5CMakePrintHelpers
6-----------------
7
8Convenience functions for printing properties and variables, useful
9e.g. for debugging.
10
11::
12
13  cmake_print_properties([TARGETS target1 ..  targetN]
14                        [SOURCES source1 .. sourceN]
15                        [DIRECTORIES dir1 .. dirN]
16                        [TESTS test1 .. testN]
17                        [CACHE_ENTRIES entry1 .. entryN]
18                        PROPERTIES prop1 .. propN )
19
20This function prints the values of the properties of the given targets,
21source files, directories, tests or cache entries.  Exactly one of the
22scope keywords must be used.  Example::
23
24  cmake_print_properties(TARGETS foo bar PROPERTIES
25                         LOCATION INTERFACE_INCLUDE_DIRECTORIES)
26
27This will print the LOCATION and INTERFACE_INCLUDE_DIRECTORIES properties for
28both targets foo and bar.
29
30::
31
32  cmake_print_variables(var1 var2 ..  varN)
33
34This function will print the name of each variable followed by its value.
35Example::
36
37  cmake_print_variables(CMAKE_C_COMPILER CMAKE_MAJOR_VERSION DOES_NOT_EXIST)
38
39Gives::
40
41  -- CMAKE_C_COMPILER="/usr/bin/gcc" ; CMAKE_MAJOR_VERSION="2" ; DOES_NOT_EXIST=""
42#]=======================================================================]
43
44function(cmake_print_variables)
45  set(msg "")
46  foreach(var ${ARGN})
47    if(msg)
48      string(APPEND msg " ; ")
49    endif()
50    string(APPEND msg "${var}=\"${${var}}\"")
51  endforeach()
52  message(STATUS "${msg}")
53endfunction()
54
55
56function(cmake_print_properties)
57  set(options )
58  set(oneValueArgs )
59  set(multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES )
60
61  cmake_parse_arguments(CPP "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${ARGN})
62
63  if(CPP_UNPARSED_ARGUMENTS)
64    message(FATAL_ERROR "Unknown keywords given to cmake_print_properties(): \"${CPP_UNPARSED_ARGUMENTS}\"")
65    return()
66  endif()
67
68  if(NOT CPP_PROPERTIES)
69    message(FATAL_ERROR "Required argument PROPERTIES missing in cmake_print_properties() call")
70    return()
71  endif()
72
73  set(mode)
74  set(items)
75  set(keyword)
76
77  if(CPP_TARGETS)
78    set(items ${CPP_TARGETS})
79    set(mode ${mode} TARGETS)
80    set(keyword TARGET)
81  endif()
82
83  if(CPP_SOURCES)
84    set(items ${CPP_SOURCES})
85    set(mode ${mode} SOURCES)
86    set(keyword SOURCE)
87  endif()
88
89  if(CPP_TESTS)
90    set(items ${CPP_TESTS})
91    set(mode ${mode} TESTS)
92    set(keyword TEST)
93  endif()
94
95  if(CPP_DIRECTORIES)
96    set(items ${CPP_DIRECTORIES})
97    set(mode ${mode} DIRECTORIES)
98    set(keyword DIRECTORY)
99  endif()
100
101  if(CPP_CACHE_ENTRIES)
102    set(items ${CPP_CACHE_ENTRIES})
103    set(mode ${mode} CACHE_ENTRIES)
104    # This is a workaround for the fact that passing `CACHE` as an argument to
105    # set() causes a cache variable to be set.
106    set(keyword "")
107    string(APPEND keyword CACHE)
108  endif()
109
110  if(NOT mode)
111    message(FATAL_ERROR "Mode keyword missing in cmake_print_properties() call, must be one of TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES")
112    return()
113  endif()
114
115  list(LENGTH mode modeLength)
116  if("${modeLength}" GREATER 1)
117    message(FATAL_ERROR "Multiple mode keyword used in cmake_print_properties() call, it must be exactly one of TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES")
118    return()
119  endif()
120
121  set(msg "\n")
122  foreach(item ${items})
123
124    set(itemExists TRUE)
125    if(keyword STREQUAL "TARGET")
126      if(NOT TARGET ${item})
127      set(itemExists FALSE)
128      string(APPEND msg "\n No such TARGET \"${item}\" !\n\n")
129      endif()
130    endif()
131
132    if (itemExists)
133      string(APPEND msg " Properties for ${keyword} ${item}:\n")
134      foreach(prop ${CPP_PROPERTIES})
135
136        get_property(propertySet ${keyword} ${item} PROPERTY "${prop}" SET)
137
138        if(propertySet)
139          get_property(property ${keyword} ${item} PROPERTY "${prop}")
140          string(APPEND msg "   ${item}.${prop} = \"${property}\"\n")
141        else()
142          string(APPEND msg "   ${item}.${prop} = <NOTFOUND>\n")
143        endif()
144      endforeach()
145    endif()
146
147  endforeach()
148  message(STATUS "${msg}")
149
150endfunction()
151