summaryrefslogtreecommitdiffstats
path: root/Tests/RunCMake/property_init/util.cmake
blob: 564a2293f640810222a15035d0af1bc5d83e37c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
set(all_target_types
  "EXECUTABLE"

  "IMPORTED_EXECUTABLE"

  "INTERFACE"
  "MODULE"
  "OBJECT"
  "SHARED"
  "STATIC"

  "IMPORTED_INTERFACE"
  "IMPORTED_MODULE"
  "IMPORTED_OBJECT"
  "IMPORTED_SHARED"
  "IMPORTED_STATIC"

  "CUSTOM")

function (prepare_target_types name)
  set("${name}" "${ARGN}" PARENT_SCOPE)
  list(REMOVE_ITEM all_target_types ${ARGN})
  set("not_${name}" "${all_target_types}" PARENT_SCOPE)
endfunction ()

function (make_target name type)
  if (type STREQUAL "EXECUTABLE")
    add_executable("${name}")
    target_sources("${name}" PRIVATE ${main_sources})
  elseif (type STREQUAL "IMPORTED_EXECUTABLE")
    add_executable("${name}" IMPORTED)
    set_property(TARGET "${name}" PROPERTY IMPORTED_LOCATION "${CMAKE_COMMAND}")
  elseif (type STREQUAL "CUSTOM")
    add_custom_target("${name}" COMMAND "${CMAKE_EXECUTABLE}" -E echo "${name}")
  elseif (type MATCHES "IMPORTED_")
    string(REPLACE "IMPORTED_" "" type "${type}")
    add_library("${name}" IMPORTED ${type})
    if (NOT type STREQUAL "INTERFACE")
      set_property(TARGET "${name}" PROPERTY IMPORTED_LOCATION "${default_library_location}")
    endif ()
  else ()
    add_library("${name}" ${type})
    target_sources("${name}" PRIVATE ${library_sources})
  endif ()

  if (type MATCHES "EXECUTABLE")
    add_executable("alias::${name}" ALIAS "${name}")
  elseif (NOT type STREQUAL "CUSTOM")
    add_library("alias::${name}" ALIAS "${name}")
  endif ()
endfunction ()

function (check_property target property expected)
  if (NOT TARGET "${target}")
    message(SEND_ERROR
      "No such target '${target}'")
    return ()
  endif ()

  get_property(is_set TARGET "${target}" PROPERTY "${property}" SET)
  if (is_set)
    get_property(actual TARGET "${target}" PROPERTY "${property}")
  endif ()
  if (expected STREQUAL "<UNSET>")
    if (is_set)
      message(SEND_ERROR
        "Target '${target}' should not have '${property}' set at all, but is '${actual}'")
    endif ()
  elseif (is_set AND NOT expected STREQUAL actual)
    message(SEND_ERROR
      "Target '${target}' should have '${property}' set to '${expected}', but is '${actual}'")
  elseif (NOT is_set)
    message(SEND_ERROR
      "Target '${target}' should have '${property}' set to '${expected}', but is not set at all")
  endif ()
endfunction ()

function (prepare_properties table output_properties output_expected output_alias)
  set(_properties)
  set(_expected)
  set(_alias)

  set(variable "_properties")
  foreach (item IN LISTS "${table}")
    list(APPEND "${variable}" "${item}")
    if (variable STREQUAL "_properties")
      set(variable "_expected")
    elseif (variable STREQUAL "_expected")
      set(variable "_alias")
    elseif (variable STREQUAL "_alias")
      set(variable "_properties")
    else ()
      message(FATAL_ERROR
        "Failed to track property table parsing")
    endif ()
  endforeach ()
  if (NOT variable STREQUAL "_properties")
    message(FATAL_ERROR
      "Table does not have a multiple of 3 items")
  endif ()

  set("${output_properties}" "${_properties}" PARENT_SCOPE)
  set("${output_expected}" "${_expected}" PARENT_SCOPE)
  set("${output_alias}" "${_alias}" PARENT_SCOPE)
endfunction ()

# Contextual variables:
#   iteration: make unique target names
#   with_defaults: if set, do not set variables, but instead test internal
#                  default calculations
function (run_property_tests applied_types property_table)
  prepare_properties("${property_table}" expected_properties expected_values expected_alias)

  if (NOT with_defaults)
    foreach (property expected IN ZIP_LISTS expected_properties expected_values)
      string(REPLACE "<SEMI>" ";" expected "${expected}")
      set("CMAKE_${property}" "${expected}")
    endforeach ()
  endif ()

  foreach (target_type IN LISTS "${applied_types}")
    set(target_name "${RunCMake_TEST}${iteration}-${target_type}")
    if (with_defaults)
      string(APPEND target_name "-defaults")
    endif ()
    make_target("${target_name}" "${target_type}")
    foreach (property expected alias IN ZIP_LISTS expected_properties expected_values expected_alias)
      string(REPLACE "<SEMI>" ";" expected "${expected}")
      check_property("${target_name}" "${property}" "${expected}")
      if (NOT target_type STREQUAL "CUSTOM")
        if (alias STREQUAL "<SAME>")
          check_property("alias::${target_name}" "${property}" "${expected}")
        elseif (alias STREQUAL "<UNSET>")
          check_property("alias::${target_name}" "${property}" "<UNSET>")
        else ()
          message(FATAL_ERROR
            "Invalid `alias` entry for property '${property}': '${alias}'")
        endif ()
      endif ()
    endforeach ()
  endforeach ()

  foreach (target_type IN LISTS "not_${applied_types}")
    set(target_name "${RunCMake_TEST}${iteration}-${target_type}-unset")
    if (with_defaults)
      string(APPEND target_name "-defaults")
    endif ()
    make_target("${target_name}" "${target_type}")
    foreach (property IN LISTS expected_properties)
      check_property("${target_name}" "${property}" "<UNSET>")
      if (NOT target_type STREQUAL "CUSTOM")
        check_property("alias::${target_name}" "${property}" "<UNSET>")
      endif ()
    endforeach ()
  endforeach ()
endfunction ()