Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
# Utility functions for packaging an LLVM distribution. See the
2
# BuildingADistribution documentation for more details.
3
 
4
# These functions assume a number of conventions that are common across all LLVM
5
# subprojects:
6
# - The generated CMake exports file for ${project} is called ${project}Targets
7
#   (except for LLVM where it's called ${project}Exports for legacy reasons).
8
# - The build target for the CMake exports is called ${project}-cmake-exports
9
#   (except LLVM where it's just cmake-exports).
10
# - The ${PROJECT}${distribution}_HAS_EXPORTS global property holds whether a
11
#   project has any exports for a particular ${distribution} (where ${PROJECT}
12
#   is the project name in uppercase).
13
# - The ${PROJECT}_CMAKE_DIR variable is computed by ${project}Config.cmake to
14
#   hold the path of the installed CMake modules directory.
15
# - The ${PROJECT}_INSTALL_PACKAGE_DIR variable contains the install destination
16
#   for the project's CMake modules.
17
 
18
include_guard(GLOBAL)
19
 
20
if(LLVM_DISTRIBUTION_COMPONENTS AND LLVM_DISTRIBUTIONS)
21
  message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS and LLVM_DISTRIBUTIONS cannot be specified together")
22
endif()
23
 
24
if(LLVM_DISTRIBUTION_COMPONENTS OR LLVM_DISTRIBUTIONS)
25
  if(LLVM_ENABLE_IDE)
26
    message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS cannot be specified with multi-configuration generators (i.e. Xcode or Visual Studio)")
27
  endif()
28
endif()
29
 
30
# Build the map of targets to distributions that's used to look up the
31
# distribution for a target later. The distribution for ${target} is stored in
32
# the global property LLVM_DISTRIBUTION_FOR_${target}.
33
function(llvm_distribution_build_target_map)
34
  foreach(target ${LLVM_DISTRIBUTION_COMPONENTS})
35
    # CMake doesn't easily distinguish between properties that are unset and
36
    # properties that are empty (you have to do a second get_property call with
37
    # the SET option, which is unergonomic), so just use a special marker to
38
    # denote the default (unnamed) distribution.
39
    set_property(GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target} "<DEFAULT>")
40
  endforeach()
41
 
42
  foreach(distribution ${LLVM_DISTRIBUTIONS})
43
    foreach(target ${LLVM_${distribution}_DISTRIBUTION_COMPONENTS})
44
      # By default, we allow a target to be in multiple distributions, and use
45
      # the last one to determine its export set. We disallow this in strict
46
      # mode, emitting a single error at the end for readability.
47
      if(LLVM_STRICT_DISTRIBUTIONS)
48
        get_property(current_distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target})
49
        if(current_distribution AND NOT current_distribution STREQUAL distribution)
50
          set_property(GLOBAL APPEND_STRING PROPERTY LLVM_DISTRIBUTION_ERRORS
51
            "Target ${target} cannot be in multiple distributions \
52
             ${distribution} and ${current_distribution}\n"
53
            )
54
        endif()
55
      endif()
56
      set_property(GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target} ${distribution})
57
    endforeach()
58
  endforeach()
59
endfunction()
60
 
61
# The include guard ensures this will only be called once. The rest of this file
62
# only defines other functions (i.e. it doesn't execute any more code directly).
63
llvm_distribution_build_target_map()
64
 
65
# Look up the distribution a particular target belongs to.
66
# - target: The target to look up.
67
# - in_distribution_var: The variable with this name is set in the caller's
68
#   scope to indicate if the target is in any distribution. If no distributions
69
#   have been configured, this will always be set to true.
70
# - distribution_var: The variable with this name is set in the caller's scope
71
#   to indicate the distribution name for the target. If the target belongs to
72
#   the default (unnamed) distribution, or if no distributions have been
73
#   configured, it's set to the empty string.
74
# - UMBRELLA: The (optional) umbrella target that the target is a part of. For
75
#   example, all LLVM libraries have the umbrella target llvm-libraries.
76
function(get_llvm_distribution target in_distribution_var distribution_var)
77
  if(NOT LLVM_DISTRIBUTION_COMPONENTS AND NOT LLVM_DISTRIBUTIONS)
78
    set(${in_distribution_var} YES PARENT_SCOPE)
79
    set(${distribution_var} "" PARENT_SCOPE)
80
    return()
81
  endif()
82
 
83
  cmake_parse_arguments(ARG "" UMBRELLA "" ${ARGN})
84
  get_property(distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target})
85
  if(ARG_UMBRELLA)
86
    get_property(umbrella_distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${ARG_UMBRELLA})
87
    if(LLVM_STRICT_DISTRIBUTIONS AND distribution AND umbrella_distribution AND
88
        NOT distribution STREQUAL umbrella_distribution)
89
      set_property(GLOBAL APPEND_STRING PROPERTY LLVM_DISTRIBUTION_ERRORS
90
        "Target ${target} has different distribution ${distribution} from its \
91
         umbrella target's (${ARG_UMBRELLA}) distribution ${umbrella_distribution}\n"
92
        )
93
    endif()
94
    if(NOT distribution)
95
      set(distribution ${umbrella_distribution})
96
    endif()
97
  endif()
98
 
99
  if(distribution)
100
    set(${in_distribution_var} YES PARENT_SCOPE)
101
    if(distribution STREQUAL "<DEFAULT>")
102
      set(distribution "")
103
    endif()
104
    set(${distribution_var} "${distribution}" PARENT_SCOPE)
105
  else()
106
    set(${in_distribution_var} NO PARENT_SCOPE)
107
  endif()
108
endfunction()
109
 
110
# Get the EXPORT argument to use for an install command for a target in a
111
# project. As explained at the top of the file, the project export set for a
112
# distribution is named ${project}{distribution}Targets (except for LLVM where
113
# it's named ${project}{distribution}Exports for legacy reasons). Also set the
114
# ${PROJECT}_${DISTRIBUTION}_HAS_EXPORTS global property to mark the project as
115
# having exports for the distribution.
116
# - target: The target to get the EXPORT argument for.
117
# - project: The project to produce the argument for. IMPORTANT: The casing of
118
#   this argument should match the casing used by the project's Config.cmake
119
#   file. The correct casing for the LLVM projects is Clang, Flang, LLD, LLVM,
120
#   and MLIR.
121
# - export_arg_var The variable with this name is set in the caller's scope to
122
#   the EXPORT argument for the target for the project.
123
# - UMBRELLA: The (optional) umbrella target that the target is a part of. For
124
#   example, all LLVM libraries have the umbrella target llvm-libraries.
125
function(get_target_export_arg target project export_arg_var)
126
  string(TOUPPER "${project}" project_upper)
127
  if(project STREQUAL "LLVM")
128
    set(suffix "Exports") # legacy
129
  else()
130
    set(suffix "Targets")
131
  endif()
132
 
133
  get_llvm_distribution(${target} in_distribution distribution ${ARGN})
134
 
135
  if(in_distribution)
136
    set(${export_arg_var} EXPORT ${project}${distribution}${suffix} PARENT_SCOPE)
137
    if(distribution)
138
      string(TOUPPER "${distribution}" distribution_upper)
139
      set_property(GLOBAL PROPERTY ${project_upper}_${distribution_upper}_HAS_EXPORTS True)
140
    else()
141
      set_property(GLOBAL PROPERTY ${project_upper}_HAS_EXPORTS True)
142
    endif()
143
  else()
144
    set(${export_arg_var} "" PARENT_SCOPE)
145
  endif()
146
endfunction()
147
 
148
# Produce a string of CMake include() commands to include the exported targets
149
# files for all distributions. See the comment at the top of this file for
150
# various assumptions made.
151
# - project: The project to produce the commands for. IMPORTANT: See the comment
152
#   for get_target_export_arg above for the correct casing of this argument.
153
# - includes_var: The variable with this name is set in the caller's scope to
154
#   the string of include commands.
155
function(get_config_exports_includes project includes_var)
156
  string(TOUPPER "${project}" project_upper)
157
  set(prefix "\${${project_upper}_CMAKE_DIR}/${project}")
158
  if(project STREQUAL "LLVM")
159
    set(suffix "Exports.cmake") # legacy
160
  else()
161
    set(suffix "Targets.cmake")
162
  endif()
163
 
164
  if(NOT LLVM_DISTRIBUTIONS)
165
    set(${includes_var} "include(\"${prefix}${suffix}\")" PARENT_SCOPE)
166
  else()
167
    set(includes)
168
    foreach(distribution ${LLVM_DISTRIBUTIONS})
169
      list(APPEND includes "include(\"${prefix}${distribution}${suffix}\" OPTIONAL)")
170
    endforeach()
171
    string(REPLACE ";" "\n" includes "${includes}")
172
    set(${includes_var} "${includes}" PARENT_SCOPE)
173
  endif()
174
endfunction()
175
 
176
# Create the install commands and targets for the distributions' CMake exports.
177
# The target to install ${distribution} for a project is called
178
# ${project}-${distribution}-cmake-exports, where ${project} is the project name
179
# in lowercase and ${distribution} is the distribution name in lowercase, except
180
# for LLVM, where the target is just called ${distribution}-cmake-exports. See
181
# the comment at the top of this file for various assumptions made.
182
# - project: The project. IMPORTANT: See the comment for get_target_export_arg
183
#   above for the correct casing of this argument.
184
function(install_distribution_exports project)
185
  string(TOUPPER "${project}" project_upper)
186
  string(TOLOWER "${project}" project_lower)
187
  if(project STREQUAL "LLVM")
188
    set(prefix "")
189
    set(suffix "Exports") # legacy
190
  else()
191
    set(prefix "${project_lower}-")
192
    set(suffix "Targets")
193
  endif()
194
  set(destination "${${project_upper}_INSTALL_PACKAGE_DIR}")
195
 
196
  if(NOT LLVM_DISTRIBUTIONS)
197
    get_property(has_exports GLOBAL PROPERTY ${project_upper}_HAS_EXPORTS)
198
    if(has_exports)
199
      install(EXPORT ${project}${suffix} DESTINATION "${destination}"
200
              COMPONENT ${prefix}cmake-exports)
201
    endif()
202
  else()
203
    foreach(distribution ${LLVM_DISTRIBUTIONS})
204
      string(TOUPPER "${distribution}" distribution_upper)
205
      get_property(has_exports GLOBAL PROPERTY ${project_upper}_${distribution_upper}_HAS_EXPORTS)
206
      if(has_exports)
207
        string(TOLOWER "${distribution}" distribution_lower)
208
        set(target ${prefix}${distribution_lower}-cmake-exports)
209
        install(EXPORT ${project}${distribution}${suffix} DESTINATION "${destination}"
210
                COMPONENT ${target})
211
        if(NOT LLVM_ENABLE_IDE)
212
          add_custom_target(${target})
213
          add_llvm_install_targets(install-${target} COMPONENT ${target})
214
        endif()
215
      endif()
216
    endforeach()
217
  endif()
218
endfunction()
219
 
220
# Create the targets for installing the configured distributions. The
221
# ${distribution} target builds the distribution, install-${distribution}
222
# installs it, and install-${distribution}-stripped installs a stripped version,
223
# where ${distribution} is the distribution name in lowercase, or "distribution"
224
# for the default distribution.
225
function(llvm_distribution_add_targets)
226
  # This function is called towards the end of LLVM's CMakeLists.txt, so all
227
  # errors will have been seen by now.
228
  if(LLVM_STRICT_DISTRIBUTIONS)
229
    get_property(errors GLOBAL PROPERTY LLVM_DISTRIBUTION_ERRORS)
230
    if(errors)
231
      string(PREPEND errors
232
        "Strict distribution errors (turn off LLVM_STRICT_DISTRIBUTIONS to bypass):\n"
233
        )
234
      message(FATAL_ERROR "${errors}")
235
    endif()
236
  endif()
237
 
238
  set(distributions "${LLVM_DISTRIBUTIONS}")
239
  if(NOT distributions)
240
    # CMake seemingly doesn't distinguish between an empty list and a list
241
    # containing one element which is the empty string, so just use a special
242
    # marker to denote the default (unnamed) distribution and fix it in the
243
    # loop.
244
    set(distributions "<DEFAULT>")
245
  endif()
246
 
247
  get_property(LLVM_DRIVER_TOOL_SYMLINKS GLOBAL PROPERTY LLVM_DRIVER_TOOL_SYMLINKS)
248
 
249
  foreach(distribution ${distributions})
250
    if(distribution STREQUAL "<DEFAULT>")
251
      set(distribution_target distribution)
252
      # Preserve legacy behavior for LLVM_DISTRIBUTION_COMPONENTS.
253
      set(distribution_components ${LLVM_DISTRIBUTION_COMPONENTS} ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})
254
    else()
255
      string(TOLOWER "${distribution}" distribution_lower)
256
      set(distribution_target ${distribution_lower}-distribution)
257
      set(distribution_components ${LLVM_${distribution}_DISTRIBUTION_COMPONENTS})
258
    endif()
259
 
260
    add_custom_target(${distribution_target})
261
    add_custom_target(install-${distribution_target})
262
    add_custom_target(install-${distribution_target}-stripped)
263
 
264
    foreach(target ${distribution_components})
265
      # Note that some distribution components may not have an actual target, but only an install-FOO target.
266
      # This happens for example if a target is an INTERFACE target.
267
      if(TARGET ${target})
268
        add_dependencies(${distribution_target} ${target})
269
      endif()
270
 
271
      if(TARGET install-${target})
272
        add_dependencies(install-${distribution_target} install-${target})
273
      elseif(TARGET install-llvm-driver AND ${target} IN_LIST LLVM_DRIVER_TOOL_SYMLINKS)
274
        add_dependencies(install-${distribution_target} install-llvm-driver)
275
      else()
276
        message(SEND_ERROR "Specified distribution component '${target}' doesn't have an install target")
277
      endif()
278
 
279
      if(TARGET install-${target}-stripped)
280
        add_dependencies(install-${distribution_target}-stripped install-${target}-stripped)
281
      elseif(TARGET install-llvm-driver-stripped AND ${target} IN_LIST LLVM_DRIVER_TOOL_SYMLINKS)
282
        add_dependencies(install-${distribution_target}-stripped install-llvm-driver-stripped)
283
      else()
284
        message(SEND_ERROR
285
                "Specified distribution component '${target}' doesn't have an install-stripped target."
286
                " Its installation target creation should be changed to use add_llvm_install_targets,"
287
                " or you should manually create the 'install-${target}-stripped' target.")
288
      endif()
289
    endforeach()
290
  endforeach()
291
endfunction()