Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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()
  292.