diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -906,6 +906,7 @@
 set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
 
 include(AddLLVM)
+include(LLVMComponents)
 include(TableGen)
 
 if( MINGW AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -404,10 +404,6 @@
 #     Suppress default RPATH settings in shared libraries.
 #   PLUGIN_TOOL
 #     The tool (i.e. cmake target) that this plugin will link against
-#   COMPONENT_LIB
-#      This is used to specify that this is a component library of
-#      LLVM which means that the source resides in llvm/lib/ and it is a
-#      candidate for inclusion into libLLVM.so.
 #   )
 function(llvm_add_library name)
   cmake_parse_arguments(ARG
@@ -517,11 +513,6 @@
     add_library(${name} STATIC ${ALL_FILES})
   endif()
 
-  if(ARG_COMPONENT_LIB)
-    set_target_properties(${name} PROPERTIES LLVM_COMPONENT TRUE)
-    set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${name})
-  endif()
-
   if(NOT ARG_NO_INSTALL_RPATH)
     if(ARG_MODULE OR ARG_SHARED)
       llvm_setup_rpath(${name})
@@ -613,7 +604,7 @@
   if(ARG_MODULE AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS AND ARG_PLUGIN_TOOL AND (WIN32 OR CYGWIN))
     # On DLL platforms symbols are imported from the tool by linking against it.
     set(llvm_libs ${ARG_PLUGIN_TOOL})
-  elseif (NOT ARG_COMPONENT_LIB)
+  else()
     if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
       set(llvm_libs LLVM)
     else()
@@ -622,21 +613,6 @@
        ${LLVM_LINK_COMPONENTS}
        )
     endif()
-  else()
-    # Components have not been defined explicitly in CMake, so add the
-    # dependency information for this library through their name, and let
-    # LLVMBuildResolveComponentsLink resolve the mapping.
-    #
-    # It would be nice to verify that we have the dependencies for this library
-    # name, but using get_property(... SET) doesn't suffice to determine if a
-    # property has been set to an empty value.
-    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})
-
-    # These two properties are internal properties only used to make sure the
-    # link step applied in LLVMBuildResolveComponentsLink uses the same
-    # properties as the target_link_libraries call below.
-    set_property(TARGET ${name} PROPERTY LLVM_LINK_LIBS ${ARG_LINK_LIBS})
-    set_property(TARGET ${name} PROPERTY LLVM_LIBTYPE ${libtype})
   endif()
 
   target_link_libraries(${name} ${libtype}
@@ -724,13 +700,32 @@
 # to link extra component into an existing group.
 function(add_llvm_component_group name)
   cmake_parse_arguments(ARG "HAS_JIT" "" "LINK_COMPONENTS" ${ARGN})
-  add_custom_target(${name})
-  if(ARG_HAS_JIT)
-    set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON)
-  endif()
-  if(ARG_LINK_COMPONENTS)
-    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
-  endif()
+
+  set(_COMPONENT_NAME ${name})
+  set(_DUMMY_CPP_FILE ${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp)
+
+  # Map legacy component libs.
+  llvm_map_components_to_libnames(_component_libs
+    ${ARG_LINK_COMPONENTS})
+
+  llvm_component_add_library(${name}
+    ${ARG_UNPARSED_ARGUMENTS}
+    "${_DUMMY_CPP_FILE}"
+    PARTIAL_SOURCES_INTENDED
+    ADD_TO_COMPONENT ${_COMPONENT_NAME}
+    LINK_LIBS ${_component_libs}
+    DEPENDS ${LLVM_COMMON_DEPENDS})
+
+  # TODO: LLVM_LIBS here is actually components.
+  set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${_COMPONENT_NAME} )
+
+  # add_custom_target(${name})
+  # if(ARG_HAS_JIT)
+  #   set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON)
+  # endif()
+  # if(ARG_LINK_COMPONENTS)
+  #   set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
+  # endif()
 endfunction()
 
 # An LLVM component is a cmake target with the following cmake properties
@@ -746,20 +741,38 @@
   cmake_parse_arguments(ARG
     ""
     "COMPONENT_NAME;ADD_TO_COMPONENT"
-    ""
+    "LINK_LIBS;DEPENDS;LINK_COMPONENTS"
     ${ARGN})
-  add_llvm_library(${name} COMPONENT_LIB ${ARG_UNPARSED_ARGUMENTS})
-  string(REGEX REPLACE "^LLVM" "" component_name ${name})
-  set_property(TARGET ${name} PROPERTY LLVM_COMPONENT_NAME ${component_name})
-
+  set(_COMPONENT_NAME)
   if(ARG_COMPONENT_NAME)
-    set_property(GLOBAL PROPERTY LLVM_COMPONENT_NAME_${ARG_COMPONENT_NAME} ${component_name})
+    # TODO: Why does it need the prefix?
+    set(_COMPONENT_NAME LLVM${ARG_COMPONENT_NAME})
   endif()
-
-  if(ARG_ADD_TO_COMPONENT)
-    set_property(TARGET ${ARG_ADD_TO_COMPONENT} APPEND PROPERTY LLVM_LINK_COMPONENTS ${component_name})
+  if(NOT _COMPONENT_NAME)
+    set(_COMPONENT_NAME ${ARG_ADD_TO_COMPONENT})
+  endif()
+  if(NOT _COMPONENT_NAME)
+    # Default to the library name for the component name (i.e LLVMDemangle).
+    set(_COMPONENT_NAME ${name})
   endif()
 
+  # Map legacy component libs.
+  llvm_map_components_to_libnames(_component_libs
+    ${ARG_LINK_COMPONENTS}
+    ${LLVM_LINK_COMPONENTS}
+    )
+
+  llvm_component_add_library(${name}
+    ${ARG_UNPARSED_ARGUMENTS}
+    ADD_TO_COMPONENT ${_COMPONENT_NAME}
+    DEPENDS ${ARG_DEPENDS} ${LLVM_COMMON_DEPENDS}
+    LINK_LIBS ${_component_libs} ${ARG_LINK_LIBS})
+
+  # Usually done by add_llvm_library but managed separately here.
+  # Needed in order to map some component name forms.
+  # TODO: LLVM_LIBS here is actually components.
+  set_property(GLOBAL APPEND PROPERTY LLVM_LIBS ${_COMPONENT_NAME})
+  set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${_COMPONENT_NAME})
 endfunction()
 
 macro(add_llvm_library name)
@@ -899,13 +912,20 @@
     add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
   endif(LLVM_EXPORTED_SYMBOL_FILE)
 
-  if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
-    set(USE_SHARED USE_SHARED)
-  endif()
-
   set(EXCLUDE_FROM_ALL OFF)
   set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
-  llvm_config( ${name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} )
+
+  # Force static linkage.
+  if (ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
+    set_property(TARGET ${name} PROPERTY LLVM_LINK_STATIC ON)
+  endif()
+
+  # Link components.
+  llvm_map_components_to_libnames(_llvm_component_libs
+    ${LLVM_LINK_COMPONENTS}
+  )
+  target_link_libraries(${name} PRIVATE ${_llvm_component_libs})
+
   if( LLVM_COMMON_DEPENDS )
     add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
   endif( LLVM_COMMON_DEPENDS )
diff --git a/llvm/cmake/modules/LLVM-Build.cmake b/llvm/cmake/modules/LLVM-Build.cmake
--- a/llvm/cmake/modules/LLVM-Build.cmake
+++ b/llvm/cmake/modules/LLVM-Build.cmake
@@ -5,13 +5,19 @@
 
   # Write C header
   #################
+  # Components machinery appends the component name to LLVM_COMPONENT_LIBS for
+  # each library that makes up a component (which can cause duplicates).
   get_property(llvmbuild_components GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
-  foreach(llvmbuild_component ${llvmbuild_components})
-    string(REGEX REPLACE "^LLVM" "" component_name ${llvmbuild_component})
-    list(APPEND all_component_libdeps ${component_name})
-  endforeach()
+  list(REMOVE_DUPLICATES llvmbuild_components)
+
+  # Compute the list of components to include for the special "all" moniker.
+  # Note that the "config" components all omit the leading "LLVM" prefix
+  # (i.e. "support").
+  set(all_component_libdeps ${llvmbuild_components})
+  list(TRANSFORM all_component_libdeps REPLACE "^LLVM" "")
+
   list(APPEND llvmbuild_components all)
-  foreach(llvm_component all-targets Engine Native NativeCodeGen ${LLVM_TARGETS_TO_BUILD})
+  foreach(llvm_component all-targets Engine Native NativeCodeGen)
     list(APPEND llvmbuild_components ${llvm_component})
     list(APPEND all_component_libdeps ${llvm_component})
   endforeach()
@@ -23,8 +29,11 @@
     /// The name of the component.
     const char *Name;
 
-    /// The name of the library for this component (or NULL).
-    const char *Library;
+    /// The name of the static library for this component (or NULL).
+    const char *StaticLibrary;
+
+    /// The name of the shared library for this component (or NULL).
+    const char *SharedLibrary;
 
     /// Whether the component is installed.
     bool IsInstalled;
@@ -36,21 +45,66 @@
 
   foreach(llvmbuild_component ${llvmbuild_components})
     if(llvmbuild_component STREQUAL "all")
-      unset(llvmbuild_libname)
+      set(llvmbuild_libname "all")
       set(llvmbuild_libdeps ${all_component_libdeps})
     else()
-      get_property(llvmbuild_libname TARGET ${llvmbuild_component} PROPERTY LLVM_COMPONENT_NAME)
-      get_property(llvmbuild_libdeps TARGET ${llvmbuild_component} PROPERTY LLVM_LINK_COMPONENTS)
-    endif()
-    string(TOLOWER ${llvmbuild_component} llvmbuild_componentname)
-
-    if(NOT llvmbuild_libname)
-      set(llvmbuild_llvmlibname nullptr)
-      string(TOLOWER ${llvmbuild_component} llvmbuild_libname)
-    else()
-      set(llvmbuild_llvmlibname "\"LLVM${llvmbuild_libname}\"")
+      # The config "libname" is just the component name with the "LLVM" prefix
+      # stripped (all component names in the LLVM project are prefixed with
+      # "LLVM" but llvm-config presents them without prefix) and lower cased.
+      string(REGEX REPLACE "^LLVM" "" llvmbuild_libname "${llvmbuild_component}")
       string(TOLOWER ${llvmbuild_libname} llvmbuild_libname)
+
+      # Compute the list of component libraries that the component links
+      # against. Note that we only support those added explicitly as part of
+      # creating a component, matching them by name to the list of known
+      # components to decide on inclusion. The list can contain duplicates
+      # because it is assembled from each constituent library. Making it
+      # fully normative for a link line is the job of the llvm-config tool,
+      # so we only lightly sanitize it.
+      llvm_component_get_target_property(
+        llvmbuild_linklibs "${llvmbuild_component}"
+        LLVM_COMPONENT_LINK_LIBS)
+      set(llvmbuild_libdeps)
+      if(llvmbuild_linklibs)
+        # Remove all but last duplicate of each library.
+        list(REVERSE llvmbuild_linklibs)
+        list(REMOVE_DUPLICATES llvmbuild_linklibs)
+        list(REVERSE llvmbuild_linklibs)
+
+        foreach(llvmbuild_linklib ${llvmbuild_linklibs})
+          if(llvmbuild_linklib IN_LIST llvmbuild_components)
+            # Strip the LLVM prefix and lower-case to match how it is written
+            # to the file.
+            string(REGEX REPLACE "^LLVM" "" llvmbuild_linklib "${llvmbuild_linklib}")
+            string(TOLOWER ${llvmbuild_linklib} llvmbuild_linklib)
+            list(APPEND llvmbuild_libdeps "${llvmbuild_linklib}")
+          endif()
+        endforeach()
+      endif()
+
+      # Compute the link name for the static target.
+      llvm_component_get_target_property(
+        llvm_build_static_libname "${llvmbuild_component}"
+        LLVM_COMPONENT_STATIC_LINK_NAME)
+      if(llvm_build_static_libname)
+        string(CONCAT llvm_build_static_libname
+          "\"" "${llvm_build_static_libname}" "\"")
+      else()
+        set(llvm_build_static_libname nullptr)
+      endif()
+
+      # Compute the link name for the shared target.
+      llvm_component_get_target_property(
+        llvm_build_shared_libname "${llvmbuild_component}"
+        LLVM_COMPONENT_SHARED_LINK_NAME)
+      if(llvm_build_shared_libname)
+        string(CONCAT llvm_build_shared_libname
+          "\"" "${llvm_build_shared_libname}" "\"")
+      else()
+        set(llvm_build_shared_libname nullptr)
+      endif()
     endif()
+    string(TOLOWER ${llvmbuild_component} llvmbuild_componentname)
 
     set(llvmbuild_clibdeps "")
     foreach(llvmbuild_libdep ${llvmbuild_libdeps})
@@ -66,7 +120,7 @@
     list(TRANSFORM llvmbuild_clibdeps PREPEND "\"")
     list(TRANSFORM llvmbuild_clibdeps APPEND "\"")
     list(JOIN llvmbuild_clibdeps ", " llvmbuild_clibdeps_joint)
-    list(APPEND llvmbuild_centries "{ \"${llvmbuild_libname}\", ${llvmbuild_llvmlibname}, true, {${llvmbuild_clibdeps_joint}} },\n")
+    list(APPEND llvmbuild_centries "{ \"${llvmbuild_libname}\", ${llvm_build_static_libname}, ${llvm_build_shared_libname}, true, {${llvmbuild_clibdeps_joint}} },\n")
   endforeach()
 
   list(SORT llvmbuild_centries)
@@ -75,30 +129,3 @@
   endforeach()
   file(APPEND ${ARG_OUTPUT} "};")
 endfunction()
-
-# Resolve cross-component dependencies, for each available component.
-function(LLVMBuildResolveComponentsLink)
-
-  # the native target may not be enabled when cross compiling
-  if(TARGET ${LLVM_NATIVE_ARCH})
-    get_property(llvm_has_jit_native TARGET ${LLVM_NATIVE_ARCH} PROPERTY LLVM_HAS_JIT)
-  else()
-    set(llvm_has_jit_native OFF)
-  endif()
-
-  if(llvm_has_jit_native)
-    set_property(TARGET Engine APPEND PROPERTY LLVM_LINK_COMPONENTS "MCJIT" "Native")
-  else()
-    set_property(TARGET Engine APPEND PROPERTY LLVM_LINK_COMPONENTS "Interpreter")
-  endif()
-
-  get_property(llvm_components GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
-  foreach(llvm_component ${llvm_components})
-    get_property(link_components TARGET ${llvm_component} PROPERTY LLVM_LINK_COMPONENTS)
-    llvm_map_components_to_libnames(llvm_libs ${link_components})
-    if(llvm_libs)
-      get_property(libtype TARGET ${llvm_component} PROPERTY LLVM_LIBTYPE)
-      target_link_libraries(${llvm_component} ${libtype} ${llvm_libs})
-    endif()
-  endforeach()
-endfunction()
diff --git a/llvm/cmake/modules/LLVM-Config.cmake b/llvm/cmake/modules/LLVM-Config.cmake
--- a/llvm/cmake/modules/LLVM-Config.cmake
+++ b/llvm/cmake/modules/LLVM-Config.cmake
@@ -66,36 +66,6 @@
   endif()
 endfunction()
 
-macro(llvm_config executable)
-  cmake_parse_arguments(ARG "USE_SHARED" "" "" ${ARGN})
-  set(link_components ${ARG_UNPARSED_ARGUMENTS})
-
-  if(ARG_USE_SHARED)
-    # If USE_SHARED is specified, then we link against libLLVM,
-    # but also against the component libraries below. This is
-    # done in case libLLVM does not contain all of the components
-    # the target requires.
-    #
-    # Strip LLVM_DYLIB_COMPONENTS out of link_components.
-    # To do this, we need special handling for "all", since that
-    # may imply linking to libraries that are not included in
-    # libLLVM.
-
-    if (DEFINED link_components AND DEFINED LLVM_DYLIB_COMPONENTS)
-      if("${LLVM_DYLIB_COMPONENTS}" STREQUAL "all")
-        set(link_components "")
-      else()
-        list(REMOVE_ITEM link_components ${LLVM_DYLIB_COMPONENTS})
-      endif()
-    endif()
-
-    target_link_libraries(${executable} PRIVATE LLVM)
-  endif()
-
-  explicit_llvm_config(${executable} ${link_components})
-endmacro(llvm_config)
-
-
 function(explicit_llvm_config executable)
   set( link_components ${ARGN} )
 
@@ -124,83 +94,50 @@
 # handling. Also does not cover 'all' as we only have a list of the libnames
 # available and not a list of the components.
 function(llvm_expand_pseudo_components out_components)
+  # Targets were originally much more fine-grained and we supported linking
+  # at that granularity. Now these all just alias to the target library.
+  set(_all_targets_aliases AllTargets AllTargetsCodeGens
+      AllTargetsAsmParsers AllTargetsDescs AllTargetsDisassemblers
+      AllTargetsInfos)
+
   set( link_components ${ARGN} )
   foreach(c ${link_components})
     # add codegen, asmprinter, asmparser, disassembler
     list(FIND LLVM_TARGETS_TO_BUILD ${c} idx)
     if( NOT idx LESS 0 )
       if( TARGET LLVM${c}CodeGen )
+        # TODO: Still needed? Remove?
         list(APPEND expanded_components "${c}CodeGen")
       else()
-        if( TARGET LLVM${c} )
-          list(APPEND expanded_components "${c}")
+        if( TARGET LLVMTarget${c} )
+          list(APPEND expanded_components "Target${c}")
         else()
           message(FATAL_ERROR "Target ${c} is not in the set of libraries.")
         endif()
       endif()
-      if( TARGET LLVM${c}AsmPrinter )
-        list(APPEND expanded_components "${c}AsmPrinter")
-      endif()
-      if( TARGET LLVM${c}AsmParser )
-        list(APPEND expanded_components "${c}AsmParser")
-      endif()
-      if( TARGET LLVM${c}Desc )
-        list(APPEND expanded_components "${c}Desc")
-      endif()
-      if( TARGET LLVM${c}Disassembler )
-        list(APPEND expanded_components "${c}Disassembler")
-      endif()
-      if( TARGET LLVM${c}Info )
-        list(APPEND expanded_components "${c}Info")
-      endif()
-      if( TARGET LLVM${c}Utils )
-        list(APPEND expanded_components "${c}Utils")
-      endif()
     elseif( c STREQUAL "nativecodegen" )
-      if( TARGET LLVM${LLVM_NATIVE_ARCH}CodeGen )
-        list(APPEND expanded_components "${LLVM_NATIVE_ARCH}CodeGen")
-      endif()
-      if( TARGET LLVM${LLVM_NATIVE_ARCH}Desc )
-        list(APPEND expanded_components "${LLVM_NATIVE_ARCH}Desc")
+      if( TARGET LLVMTarget${LLVM_NATIVE_ARCH} )
+        list(APPEND expanded_components "Target${LLVM_NATIVE_ARCH}")
       endif()
-      if( TARGET LLVM${LLVM_NATIVE_ARCH}Info )
-        list(APPEND expanded_components "${LLVM_NATIVE_ARCH}Info")
-      endif()
-    elseif( c STREQUAL "AllTargetsCodeGens" )
-      # Link all the codegens from all the targets
-      foreach(t ${LLVM_TARGETS_TO_BUILD})
-        if( TARGET LLVM${t}CodeGen)
-          list(APPEND expanded_components "${t}CodeGen")
-        endif()
-      endforeach(t)
-    elseif( c STREQUAL "AllTargetsAsmParsers" )
-      # Link all the asm parsers from all the targets
+    elseif("${c}" IN_LIST _all_targets_aliases)
+      # Link all target libraries.
       foreach(t ${LLVM_TARGETS_TO_BUILD})
-        if( TARGET LLVM${t}AsmParser )
-          list(APPEND expanded_components "${t}AsmParser")
-        endif()
-      endforeach(t)
-    elseif( c STREQUAL "AllTargetsDescs" )
-      # Link all the descs from all the targets
-      foreach(t ${LLVM_TARGETS_TO_BUILD})
-        if( TARGET LLVM${t}Desc )
-          list(APPEND expanded_components "${t}Desc")
-        endif()
-      endforeach(t)
-    elseif( c STREQUAL "AllTargetsDisassemblers" )
-      # Link all the disassemblers from all the targets
-      foreach(t ${LLVM_TARGETS_TO_BUILD})
-        if( TARGET LLVM${t}Disassembler )
-          list(APPEND expanded_components "${t}Disassembler")
-        endif()
-      endforeach(t)
-    elseif( c STREQUAL "AllTargetsInfos" )
-      # Link all the infos from all the targets
-      foreach(t ${LLVM_TARGETS_TO_BUILD})
-        if( TARGET LLVM${t}Info )
-          list(APPEND expanded_components "${t}Info")
+        if( TARGET LLVMTarget${t})
+          list(APPEND expanded_components "Target${t}")
+        else()
+          message(WARNING "Target library LLVMTarget${t} not found. Skipping.")
         endif()
-      endforeach(t)
+      endforeach()
+    elseif("${c}" STREQUAL "ScalarOpts")
+      # TODO: Many things refer to a component named "ScalarOpts", but that
+      # is a library of the component. Replace these occurences and remove this
+      # exception.
+      list(APPEND expanded_components "Scalar")
+    elseif("${c}" STREQUAL "ObjCARCOpts")
+      # TODO: Many things refer to a component named "ObjCARCOpts", but that
+      # is a library of the component. Replace these occurences and remove this
+      # exception.
+      list(APPEND expanded_components "ObjCARC")
     else()
       list(APPEND expanded_components "${c}")
     endif()
diff --git a/llvm/cmake/modules/LLVMComponents.cmake b/llvm/cmake/modules/LLVMComponents.cmake
new file mode 100644
--- /dev/null
+++ b/llvm/cmake/modules/LLVMComponents.cmake
@@ -0,0 +1,446 @@
+# LLVMComponents.cmake
+#
+# In the LLVM build system, a "component" is essentially a public library that
+# can either be statically or dynamically linked. In the latter case, the
+# consumer of a component will be transparently directed to the appropriate
+# shared library (or DLL) that houses the component (which may, and likely
+# is different from how the library is physically defined in the build
+# system).
+#
+# Using components:
+# =================
+#
+# Linking to components:
+# ----------------------
+# Consumers link to a component in one of two ways:
+#   a) By linking to the interface library named the same as the component
+#      name. This will automatically link in the correct static or dynamic
+#      way, depending on the build configuration and settings of the final
+#      executable or shared library.
+#   b) For "classic" LLVM component aliases (such as "Support", "Core", etc),
+#      the following mechanisms will expand component aliases and add them to
+#      the target_link_libraries as above:
+#      - By listing is in `LINK_COMPONENTS` of an llvm_add_library derived macro.
+#      - By setting a variable `LLVM_LINK_COMPONENTS` in the scope prior to
+#        calling a macro/function that creates an LLVM library or executable.
+#
+# Static vs dynamic linkage:
+# --------------------------
+# If the global `LLVM_BUILD_SHARED_COMPONENTS` option is enabled, then shared
+# libraries (or DLLs) will be created for all components that support shared
+# linkage on the platform, and by default, executables will link against these
+# shared libraries.
+#
+# Individual executables can opt in to always link statically by setting
+# a target property `LLVM_LINK_STATIC` to true. Example:
+#   `set_target_properties(FileCheck PROPERTIES LLVM_LINK_STATIC ON)`
+#
+# Per-component shared-libraries vs aggregate:
+# --------------------------------------------
+# By default if `LLVM_BUILD_SHARED_COMPONENTS` is enabled, every component will
+# be built into its own shared library. Various other groupings are possible.
+# As an example, `LLVM_BUILD_LLVM_DYLIB` will redirect many of the core LLVM
+# components into a libLLVM.so file instead of breaking them into individual
+# libraries. This is implemented on top of the Component Redirection feature
+# (see below).
+#
+# "Classic" LLVM components:
+# --------------------------
+# The wrappers `add_llvm_component_group` and `add_llvm_component_library`
+# exist for components under `llvm/lib` defined with classic naming (i.e.
+# "Core", "Support", etc). The naming is transparently mapped to underlying
+# calls to `llvm_component_add_library`.
+#
+# Visibility:
+# -----------
+# When a library is added to a shared component, it is annotated as either
+# "export all symbols" or "export explicit symbols". The former is the
+# traditional default when building shared libraries on Unix-like systems and
+# the latter is the default behavior when building Windows DLLs. We default
+# all libraries to "export all symbols" mode and allow opt-in to explicit mode
+# with the flag EXPORT_EXPLICIT_SYMBOLS.
+#
+# On Unix, in "export all symbols" mode when performing a shared build,
+# libraries are built with their VISIBILITY_PRESET left as "default" (takes
+# any cmake global configure default that may be defined). It will be set to
+# "hidden" when in EXPORT_EXPLICIT_SYMBOLS mode. Note that if built with default
+# visibility globally set to hidden, then shared library builds may not
+# function. However, if this is being done, it is assumed that the user knows
+# what they intend (there are cases where such things are useful, if not
+# particularly well defined).
+#
+# On Windows, in EXPORT_ALL_SYMBOLS mode, special care is taken to generate
+# appropriate def files to mimic the Unix-like EXPORT_ALL_SYMBOLS behavior to
+# the extent possible. A number of caveats apply.
+#
+# By making this an explicit toggle, libraries can progressively opt-in to more
+# granulary visibility controls in a portable way, which generally leads to
+# smaller, better optimized shared libraries with less private-API leakage.
+#
+# Mapping to LLVM_LINK_COMPONENTS:
+# --------------------------------
+# LLVM_LINK_COMPONENTS is implemented on top of this feature and is retained
+# as-is within the llvm/lib tree for compatibility. There is a global (TODO)
+# that switches between building a mondo libLLVM.so or emitting fine grained
+# shared components that map to top-level link components.
+#
+# Implementing components:
+# ========================
+#
+# Internally, components are an abstraction disjoint from the libraries that
+# make them up. Multiple libraries can contribute to a single, named component,
+# although, in many common cases, there is a 1:1 correspondance between library
+# and component. The namespace is laid out to accomodate this.
+#
+# Adding a library to a component is done by invoking
+# `llvm_component_add_library` and specifying an `ADD_TO_COMPONENT <foo>`
+# parameter. As long as one such library is added to a given component name,
+# then the `llvm_component::<foo>` alias will be available to link against it.
+#
+# Internally, a component consists of a number of targets, with a few available
+# for external use:
+#   * Compilation targets: Can be used to set compilation flags. Obtain via
+#     `llvm_component_get_compile_targets` once a component has been
+#     instantiated.
+#   * Linkage targets: Can be used to set linkage flags. Obtain via
+#     `llvm_component_get_link_targets`.
+#   * Property target: Generic target that is safe to stash any properties on
+#     related to the component. Get via `llvm_component_get_props_target`.
+#
+# The library name specified in the `llvm_component_add_library` call should
+# be considered an implementation detail and is generally only useful for
+# setting compiler definitions directly on the objects that comprise this
+# part of the component. Note that it is illegal to depend on one library that
+# makes up a component from another in the same component (and unnecessary,
+# since their objects will participate in the same shared or static library
+# link at the component level).
+#
+# Internal layout:
+# ----------------
+# Internally, a number of targets are created. In the below `${libname}` refers
+# to the library `name` passed to `llvm_component_add_library` and
+# `${componentname}` refers to the argument `ADD_TO_COMPONENT`.
+#
+#   * `${libname}_objs`: An object library containing the objects that should be
+#     contributed to the component.
+#   * `${componentname}`: INTERFACE library that represents the component.
+#   * `${componentname}_props` : Custom property target for the component.
+#   * `${componentname}_shared` (on disk as `${componentname}`) :
+#     The shared library for the component (if not redirected to an aggregate
+#     library).
+#   * `${componentname}_static` (on disk as `${componentname}_static`) :
+#     The static library for the component. This library does not participate
+#     in shared library redirection and will be used by executables and
+#     libraries configured for static linking.
+#
+# These should all be considered implementation details and not depended on.
+
+# Adds a library that is part of a component.
+function(llvm_component_add_library name)
+  cmake_parse_arguments(ARG
+    "EXPORT_EXPLICIT_SYBMOLS"
+    "ADD_TO_COMPONENT"
+    "ADDITIONAL_HEADERS;DEPENDS;LINK_LIBS"
+    ${ARGN})
+  # Validate arguments.
+  if(ARG_ADD_TO_COMPONENT)
+    set(_COMPONENT_NAME ${ARG_ADD_TO_COMPONENT})
+  else()
+    message(FATAL_ERROR "ADD_TO_COMPONENT is required for ${name}")
+  endif()
+
+  # The main component implementation (object) library.
+  set(_OBJS_TARGET ${name}_objs)
+  llvm_process_sources(_all_src_files
+    ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS})
+  add_library(${_OBJS_TARGET} OBJECT EXCLUDE_FROM_ALL
+    ${_all_src_files}
+  )
+  llvm_update_compile_flags(${_OBJS_TARGET})
+  set_target_properties(${_OBJS_TARGET} PROPERTIES FOLDER "Object Libraries")
+  # Set a marker to indicate that the library is a component. This is used
+  # by some validity checks to enforce depending on it in the right way.
+  set_target_properties(${_OBJS_TARGET} PROPERTIES
+    LLVM_LIBRARY_IS_NEWCOMPONENT_LIB TRUE)
+
+  # Explicit depends.
+  if(ARG_DEPENDS)
+    # TODO: Object library deps are non transitive.
+    add_dependencies(${_OBJS_TARGET} ${ARG_DEPENDS})
+  endif()
+  if(ARG_LINK_LIBS)
+    # TODO: Object library deps are non transitive.
+    target_link_libraries(${_OBJS_TARGET} PRIVATE ${ARG_LINK_LIBS})
+  endif()
+
+  # Set export visibility at the library level.
+  if(ARG_EXPORT_EXPLICIT_SYBMOLS)
+    set_property(TARGET ${_OBJS_TARGET} CXX_VISIBILITY_PRESET "hidden")
+    set_property(TARGET ${_OBJS_TARGET} C_VISIBILITY_PRESET "hidden")
+  endif()
+
+  # Get or create the component.
+  # Note that the component is created by the first library that is added to it.
+  set(_COMPONENT_PROPS_TARGET ${_COMPONENT_NAME}_props)
+  set(_COMPONENT_INTERFACE_TARGET ${_COMPONENT_NAME})
+  if(NOT TARGET ${_COMPONENT_INTERFACE_TARGET})
+    # Create the component.
+    llvm_component_create(${_COMPONENT_NAME})
+  endif()
+
+  # Resolve the static and shared library sub-targets from the component.
+  get_target_property(_COMPONENT_SHARED_TARGET
+    ${_COMPONENT_PROPS_TARGET} LLVM_COMPONENT_SHARED_TARGET)
+  get_target_property(_COMPONENT_STATIC_TARGET
+    ${_COMPONENT_PROPS_TARGET} LLVM_COMPONENT_STATIC_TARGET)
+
+  # Add the impl library to component static and link libraries as needed.
+  if(_COMPONENT_SHARED_TARGET)
+    _llvm_component_populate_exported_library(
+      EXPORTED_TARGET "${_COMPONENT_SHARED_TARGET}"
+      OBJECTLIB_TARGET "${_OBJS_TARGET}"
+      DEPENDS ${ARG_DEPENDS}
+      LINK_LIBS ${ARG_LINK_LIBS}
+    )
+  endif()
+  if(_COMPONENT_STATIC_TARGET)
+    _llvm_component_populate_exported_library(
+      EXPORTED_TARGET "${_COMPONENT_STATIC_TARGET}"
+      OBJECTLIB_TARGET "${_OBJS_TARGET}"
+      DEPENDS ${ARG_DEPENDS}
+      LINK_LIBS ${ARG_LINK_LIBS}
+    )
+  endif()
+
+  # Remember explicitly provided link libs in a way that can be queried
+  # later (the CMake LINK_LIBRARIES property of a target allows generators
+  # and mangles libraries based on where they were added).
+  set_property(TARGET ${_COMPONENT_PROPS_TARGET}
+    APPEND PROPERTY LLVM_COMPONENT_LINK_LIBS ${ARG_LINK_LIBS}
+  )
+
+  # The compile targets are responsible for compiling the sources, and the
+  # link targets are what is ultimately performing the link. In degenerate
+  # cases, there can be multiples of each (i.e. on windows where libraries
+  # destined for a DLL are compiled differently from those that are not).
+  set_property(TARGET ${_COMPONENT_PROPS_TARGET}
+    APPEND PROPERTY LLVM_COMPONENT_COMPILE_TARGETS ${_OBJS_TARGET}
+  )
+
+  # Extend the interface link libraries appropriately.
+  # Static linking just links directly against the static library.
+  target_link_libraries(${_COMPONENT_INTERFACE_TARGET} INTERFACE
+    $<$<BOOL:$<TARGET_PROPERTY:LLVM_LINK_STATIC>>:${_COMPONENT_STATIC_TARGET}>
+  )
+
+  # Shared linking will either link against component shared library, if
+  # it exists, or the TODO
+  set(_ACTUAL_SHARED_TARGET ${_COMPONENT_SHARED_TARGET})
+  if(NOT _COMPONENT_SHARED_TARGET)
+    set(_ACTUAL_SHARED_TARGET ${_COMPONENT_STATIC_TARGET})
+  endif()
+  target_link_libraries(${_COMPONENT_INTERFACE_TARGET} INTERFACE
+    $<$<NOT:$<BOOL:$<TARGET_PROPERTY:LLVM_LINK_STATIC>>>:${_ACTUAL_SHARED_TARGET}>
+  )
+endfunction()
+
+# Auxiliary helper for populating the dependencies, sources, and link libraries
+# of either the static or shared exported library from a constituent object
+# library target.
+function(_llvm_component_populate_exported_library)
+  cmake_parse_arguments(ARG
+    ""
+    "EXPORTED_TARGET;OBJECTLIB_TARGET"
+    "DEPENDS;LINK_LIBS"
+    ${ARGN})
+
+  if(ARG_DEPENDS)
+    add_dependencies(${ARG_EXPORTED_TARGET} ${ARG_DEPENDS})
+  endif()
+  target_sources(${ARG_EXPORTED_TARGET}
+    PRIVATE $<TARGET_OBJECTS:${ARG_OBJECTLIB_TARGET}>)
+  target_link_libraries(${ARG_EXPORTED_TARGET}
+    PRIVATE ${ARG_LINK_LIBS})
+endfunction()
+
+function(llvm_component_create component_name)
+  set(_COMPONENT_PROPS_TARGET ${component_name}_props)
+  set(_COMPONENT_INTERFACE_TARGET ${component_name})
+
+  # Create if not exists.
+  if(TARGET ${_COMPONENT_PROPS_TARGET} OR
+     TARGET ${_COMPONENT_INTERFACE_TARGET})
+    message(FATAL_ERROR "Attempted to create component ${component_name} multiple times")
+  else()
+    # Create the interface library for the component.
+    add_library(${_COMPONENT_INTERFACE_TARGET} INTERFACE)
+
+    # Add a dummy target that is just for holding component properties.
+    # This is because INTERFACE libraries cannot have custom properties, and
+    # we prefer to not randomly pollute the global namespace.
+    add_custom_target(${_COMPONENT_PROPS_TARGET})
+
+    # Set the interface target on the property target.
+    set_target_properties(${_COMPONENT_PROPS_TARGET} PROPERTIES
+      LLVM_COMPONENT_INTERFACE_TARGET ${_COMPONENT_INTERFACE_TARGET}
+    )
+
+    # Locate the component shared library target that corresponds to this
+    # component name.
+    llvm_component_ensure_libraries(${component_name})
+
+    # Exports and creates install targets for the component.
+    llvm_component_install(${component_name})
+  endif()
+endfunction()
+
+# Finds the shared library target that corresponds to the requested
+# `component_name`.
+function(llvm_component_ensure_libraries component_name)
+  set(_COMPONENT_PROPS_TARGET ${component_name}_props)
+  set(_DUMMY_CPP_FILE ${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp)
+
+  # Ensure the shared target.
+  get_target_property(_COMPONENT_SHARED_TARGET
+    ${_COMPONENT_PROPS_TARGET} LLVM_COMPONENT_SHARED_TARGET)
+  if(NOT _COMPONENT_SHARED_TARGET)
+    # See if there is a redirection entry for the component (i.e. specifying
+    # that the component goes into a dedicated shared library).
+    get_property(_COMPONENT_SHARED_TARGET GLOBAL
+      PROPERTY LLVM_COMPONENT_${component_name}_REDIRECT_SHARED_TARGET)
+
+    # Neither. Go ahead and create the default association now.
+    if(NOT _COMPONENT_SHARED_TARGET)
+      set(_COMPONENT_SHARED_TARGET "${component_name}_shared")
+    endif()
+
+    # Memorialize the decision.
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET} PROPERTY
+      LLVM_COMPONENT_SHARED_TARGET ${_COMPONENT_SHARED_TARGET})
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET} APPEND PROPERTY
+      LLVM_COMPONENT_LINK_TARGETS ${_COMPONENT_SHARED_TARGET})
+  endif()
+
+  if(NOT TARGET ${_COMPONENT_SHARED_TARGET})
+    # Not yet created. Do so now.
+    # TODO: This doesn't quite work yet for redirection. Need to not set the
+    # OUTPUT_NAME in that case.
+    add_library(${_COMPONENT_SHARED_TARGET} SHARED
+      # Dummy file needed to make empty library function.
+      "${_DUMMY_CPP_FILE}")
+    set_property(TARGET ${_COMPONENT_SHARED_TARGET}
+      PROPERTY OUTPUT_NAME ${component_name})
+    # Notate the name that we want outside parties to link to (in case if
+    # being used outside of CMake), which should be any symlink sources, if
+    # applicable.
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET}
+      PROPERTY LLVM_COMPONENT_SHARED_LINK_NAME ${component_name})
+  endif()
+
+  # Ensure the static target. Static targets are always per-component and do
+  # not participate in redirection.
+  get_target_property(_COMPONENT_STATIC_TARGET
+    ${_COMPONENT_PROPS_TARGET} LLVM_COMPONENT_STATIC_TARGET)
+  if(NOT _COMPONENT_STATIC_TARGET)
+    # Latch it.
+    set(_COMPONENT_STATIC_TARGET "${component_name}_static")
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET} PROPERTY
+      LLVM_COMPONENT_STATIC_TARGET ${_COMPONENT_STATIC_TARGET})
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET} APPEND PROPERTY
+      LLVM_COMPONENT_LINK_TARGETS ${_COMPONENT_SHARED_TARGET})
+  endif()
+
+  if(NOT TARGET ${_COMPONENT_STATIC_TARGET})
+    add_library(${_COMPONENT_STATIC_TARGET} STATIC
+      "${_DUMMY_CPP_FILE}")
+    # Notate the name that we want outside parties to link to (in case if
+    # being used outside of CMake), which should be any symlink sources, if
+    # applicable.
+    set_property(TARGET ${_COMPONENT_PROPS_TARGET}
+      PROPERTY LLVM_COMPONENT_STATIC_LINK_NAME ${_COMPONENT_STATIC_TARGET})
+  endif()
+endfunction()
+
+function(llvm_component_install component_name)
+  set(_COMPONENT_PROPS_TARGET ${component_name}_props)
+  get_target_property(_COMPONENT_INTERFACE_TARGET ${_COMPONENT_PROPS_TARGET}
+    LLVM_COMPONENT_INTERFACE_TARGET)
+  get_target_property(_COMPONENT_STATIC_TARGET ${_COMPONENT_PROPS_TARGET}
+    LLVM_COMPONENT_STATIC_TARGET)
+  get_target_property(_COMPONENT_SHARED_TARGET ${_COMPONENT_PROPS_TARGET}
+    LLVM_COMPONENT_SHARED_TARGET)
+
+  set(export_to_llvmexports EXPORT LLVMExports)
+  set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True)
+
+  # Create the main install target for the interface library.
+  install(TARGETS ${_COMPONENT_INTERFACE_TARGET}
+    ${export_to_llvmexports}
+    LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${component_name}
+    ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${component_name}
+    RUNTIME DESTINATION bin COMPONENT ${component_name})
+
+  if (NOT LLVM_ENABLE_IDE)
+    add_llvm_install_targets(install-${component_name}
+                              DEPENDS
+                                ${_COMPONENT_INTERFACE_TARGET}
+                              COMPONENT ${component_name})
+  endif()
+  set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${_COMPONENT_INTERFACE_TARGET})
+
+  # Generate install targets for each sub-library.
+  foreach(t ${_COMPONENT_SHARED_TARGET} ${_COMPONENT_STATIC_TARGET})
+    install(TARGETS ${t}
+      ${export_to_llvmexports}
+      LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${t}
+      ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${t}
+      RUNTIME DESTINATION bin COMPONENT ${t})
+
+    if (NOT LLVM_ENABLE_IDE)
+      add_llvm_install_targets(install-${t}
+                                DEPENDS
+                                  ${t}
+                                COMPONENT ${t})
+      add_dependencies(install-${component_name} install-${t})
+      add_dependencies(install-${component_name}-stripped install-${t}-stripped)
+    endif()
+    set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${t})
+  endforeach()
+endfunction()
+
+# Gets a target property for an entire component. One cannot just use
+# get_target_property on a component as it is an interface library. This
+# performs the equivalent for a named component.
+function(llvm_component_get_target_property out_var component_name property)
+  get_target_property(_value "${component_name}_props" ${property})
+  set(${out_var} ${_value} PARENT_SCOPE)
+endfunction()
+
+# Gets the list of compilation targets that a component produces. Compilation
+# affecting properties should be manipulated on these targets.
+function(llvm_component_get_compile_targets out_targets name)
+  llvm_component_get_target_property(_COMPILE_TARGETS ${name} LLVM_COMPONENT_COMPILE_TARGETS)
+  if(NOT _COMPILE_TARGETS)
+    message(SEND_ERROR "Could not get component compile targets for ${name} (is it a component library?)")
+  endif()
+  set(${out_targets} "${_COMPILE_TARGETS}" PARENT_SCOPE)
+endfunction()
+
+# Gets the list of linkable targets that a component produces. Link-affecting
+# properties should be manipulated on these targets.
+function(llvm_component_get_link_targets out_targets name)
+  llvm_component_get_target_property(_LINK_TARGETS ${name} LLVM_COMPONENT_LINK_TARGETS)
+  if(NOT _LINK_TARGETS)
+    message(SEND_ERROR "Could not get component link targets for ${name} (is it a component library?)")
+  endif()
+  set(${out_targets} "${_LINK_TARGETS}" PARENT_SCOPE)
+endfunction()
+
+# Short-cut to call 'target_include_dirs' for all compilation targets in a
+# component.
+function(llvm_component_include_dirs name)
+  llvm_component_get_compile_targets(_COMPILE_TARGETS ${name})
+  foreach(_target in ${_COMPILE_TARGETS})
+    target_include_directories(${_COMPILE_TARGETS} ${ARGN})
+  endforeach()
+endfunction()
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -57,5 +57,4 @@
 endif()
 
 # Component post-processing
-LLVMBuildResolveComponentsLink()
 LLVMBuildGenerateCFragment(OUTPUT ${LLVMCONFIGLIBRARYDEPENDENCIESINC})
diff --git a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
--- a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
@@ -24,10 +24,3 @@
   OrcTargetProcess
   Support
   )
- 
-target_link_libraries(LLVMJITLink
-  PRIVATE
-  LLVMObject
-  LLVMOrcTargetProcess
-  LLVMSupport
-)
diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
@@ -32,6 +32,9 @@
   intrinsics_gen
 
   LINK_COMPONENTS
+  Analysis
+  BitReader
+  BitWriter
   Core
   ExecutionEngine
   JITLink
@@ -48,11 +51,3 @@
 
 add_subdirectory(Shared)
 add_subdirectory(TargetProcess)
-
-target_link_libraries(LLVMOrcJIT
-  PRIVATE
-  LLVMAnalysis
-  LLVMBitReader
-  LLVMBitWriter
-  LLVMPasses
-  )
diff --git a/llvm/lib/FileCheck/CMakeLists.txt b/llvm/lib/FileCheck/CMakeLists.txt
--- a/llvm/lib/FileCheck/CMakeLists.txt
+++ b/llvm/lib/FileCheck/CMakeLists.txt
@@ -3,6 +3,7 @@
 
   ADDITIONAL_HEADER_DIRS
   "${LLVM_MAIN_INCLUDE_DIR}/llvm/FileCheck"
-)
 
-target_link_libraries(LLVMFileCheck LLVMSupport)
+  LINK_COMPONENTS
+  Support
+)
diff --git a/llvm/lib/Frontend/OpenACC/CMakeLists.txt b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
--- a/llvm/lib/Frontend/OpenACC/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
@@ -12,7 +12,8 @@
   DEPENDS
   acc_gen
   acc_cpp
-)
 
-target_link_libraries(LLVMFrontendOpenACC LLVMSupport)
+  LINK_COMPONENTS
+  Support
+)
 
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -235,6 +235,9 @@
   Demangle
   )
 
+llvm_component_get_compile_targets(_compile_targets LLVMSupport)
+llvm_component_get_link_targets(_link_targets LLVMSupport)
+
 set(llvm_system_libs ${system_libs})
 
 # This block is only needed for llvm-config. When we deprecate llvm-config and
@@ -257,22 +260,22 @@
   set(llvm_system_libs ${llvm_system_libs} "${terminfo_library}")
 endif()
 
-set_property(TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS "${llvm_system_libs}")
+set_property(TARGET ${_prop_target} PROPERTY LLVM_SYSTEM_LIBS "${llvm_system_libs}")
 
 
 if(LLVM_INTEGRATED_CRT_ALLOC)
   if(LLVM_INTEGRATED_CRT_ALLOC MATCHES "snmalloc$")
-    set_property(TARGET LLVMSupport PROPERTY CXX_STANDARD 17)
+    set_property(TARGET ${_compile_targets} PROPERTY CXX_STANDARD 17)
     add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
     if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND
         "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64")
-      set_property(TARGET LLVMSupport PROPERTY COMPILE_FLAGS "-mcx16")
+      set_property(TARGET ${_compile_targets} PROPERTY COMPILE_FLAGS "-mcx16")
     endif()
   endif()
 endif()
 
 if(LLVM_WITH_Z3)
-  target_include_directories(LLVMSupport SYSTEM
+  llvm_component_include_dirs(LLVMSupport SYSTEM
     PRIVATE
     ${Z3_INCLUDE_DIR}
     )
diff --git a/llvm/lib/Target/X86/AsmParser/CMakeLists.txt b/llvm/lib/Target/X86/AsmParser/CMakeLists.txt
--- a/llvm/lib/Target/X86/AsmParser/CMakeLists.txt
+++ b/llvm/lib/Target/X86/AsmParser/CMakeLists.txt
@@ -5,9 +5,7 @@
   MC
   MCParser
   Support
-  X86Desc
-  X86Info
 
   ADD_TO_COMPONENT
-  X86
+  LLVMTargetX86
   )
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_component_group(X86 HAS_JIT)
+add_llvm_component_group(LLVMTargetX86 HAS_JIT)
 
 set(LLVM_TARGET_DEFINITIONS X86.td)
 
@@ -91,14 +91,12 @@
   SelectionDAG
   Support
   Target
-  X86Desc
-  X86Info
   GlobalISel
   ProfileData
   CFGuard
 
   ADD_TO_COMPONENT
-  X86
+  LLVMTargetX86
 )
 
 add_subdirectory(AsmParser)
diff --git a/llvm/lib/Target/X86/Disassembler/CMakeLists.txt b/llvm/lib/Target/X86/Disassembler/CMakeLists.txt
--- a/llvm/lib/Target/X86/Disassembler/CMakeLists.txt
+++ b/llvm/lib/Target/X86/Disassembler/CMakeLists.txt
@@ -4,8 +4,7 @@
   LINK_COMPONENTS
   MCDisassembler
   Support
-  X86Info
 
   ADD_TO_COMPONENT
-  X86
+  LLVMTargetX86
   )
diff --git a/llvm/lib/Target/X86/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/X86/MCTargetDesc/CMakeLists.txt
--- a/llvm/lib/Target/X86/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/X86/MCTargetDesc/CMakeLists.txt
@@ -18,9 +18,8 @@
   MC
   MCDisassembler
   Support
-  X86Info
   BinaryFormat
 
   ADD_TO_COMPONENT
-  X86
+  LLVMTargetX86
   )
diff --git a/llvm/lib/Target/X86/TargetInfo/CMakeLists.txt b/llvm/lib/Target/X86/TargetInfo/CMakeLists.txt
--- a/llvm/lib/Target/X86/TargetInfo/CMakeLists.txt
+++ b/llvm/lib/Target/X86/TargetInfo/CMakeLists.txt
@@ -5,5 +5,5 @@
   Support
 
   ADD_TO_COMPONENT
-  X86
+  LLVMTargetX86
   )
diff --git a/llvm/test/tools/llvm-config/libs.test b/llvm/test/tools/llvm-config/libs.test
--- a/llvm/test/tools/llvm-config/libs.test
+++ b/llvm/test/tools/llvm-config/libs.test
@@ -1,5 +1,5 @@
 RUN: llvm-config --ignore-libllvm --libs core support 2>&1 | FileCheck %s
-CHECK: LLVMCore
-CHECK: LLVMSupport
+CHECK: LLVMCore_static
+CHECK: LLVMSupport_static
 CHECK-NOT: error
 CHECK-NOT: warning
diff --git a/llvm/tools/llvm-config/CMakeLists.txt b/llvm/tools/llvm-config/CMakeLists.txt
--- a/llvm/tools/llvm-config/CMakeLists.txt
+++ b/llvm/tools/llvm-config/CMakeLists.txt
@@ -9,8 +9,9 @@
   )
 
 # Compute the substitution values for various items.
-get_property(SUPPORT_SYSTEM_LIBS TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS)
-get_property(WINDOWSMANIFEST_SYSTEM_LIBS TARGET LLVMWindowsManifest PROPERTY LLVM_SYSTEM_LIBS)
+llvm_component_get_target_property(SUPPORT_SYSTEM_LIBS LLVMSupport LLVM_SYSTEM_LIBS)
+llvm_component_get_target_property(WINDOWSMANIFEST_SYSTEM_LIBS LLVMWindowsManifest LLVM_SYSTEM_LIBS)
+
 foreach(l ${SUPPORT_SYSTEM_LIBS} ${WINDOWSMANIFEST_SYSTEM_LIBS})
   if(MSVC)
     set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}.lib")
diff --git a/llvm/tools/llvm-config/llvm-config.cpp b/llvm/tools/llvm-config/llvm-config.cpp
--- a/llvm/tools/llvm-config/llvm-config.cpp
+++ b/llvm/tools/llvm-config/llvm-config.cpp
@@ -88,7 +88,8 @@
   // Lookup the component.
   AvailableComponent *AC = ComponentMap.lookup(Name);
   if (!AC) {
-    errs() << "Can't find component: '" << Name << "' in the map. Available components are: ";
+    errs() << "Can't find component: '" << Name
+           << "' in the map. Available components are: ";
     for (const auto &Component : ComponentMap) {
       errs() << "'" << Component.first() << "' ";
     }
@@ -139,16 +140,17 @@
   }
 
   // Add to the required library list.
-  if (AC->Library) {
+  // TODO: Fix static vs shared.
+  if (AC->StaticLibrary) {
     if (Missing && GetComponentLibraryPath) {
-      std::string path = (*GetComponentLibraryPath)(AC->Library);
+      std::string path = (*GetComponentLibraryPath)(AC->StaticLibrary);
       if (DirSep == "\\") {
         std::replace(path.begin(), path.end(), '/', '\\');
       }
       if (!sys::fs::exists(path))
         Missing->push_back(path);
     }
-    RequiredLibs.push_back(AC->Library);
+    RequiredLibs.push_back(AC->StaticLibrary);
   }
 }
 
@@ -160,11 +162,13 @@
 /// \param IncludeNonInstalled - Whether non-installed components should be
 /// reported.
 /// \param GetComponentNames - True if one would prefer the component names.
-static std::vector<std::string> ComputeLibsForComponents(
-    const std::vector<StringRef> &Components, bool IncludeNonInstalled,
-    bool GetComponentNames, const std::function<std::string(const StringRef &)>
-                                *GetComponentLibraryPath,
-    std::vector<std::string> *Missing, const std::string &DirSep) {
+static std::vector<std::string>
+ComputeLibsForComponents(const std::vector<StringRef> &Components,
+                         bool IncludeNonInstalled, bool GetComponentNames,
+                         const std::function<std::string(const StringRef &)>
+                             *GetComponentLibraryPath,
+                         std::vector<std::string> *Missing,
+                         const std::string &DirSep) {
   std::vector<std::string> RequiredLibs;
   std::set<AvailableComponent *> VisitedComponents;
 
@@ -264,7 +268,8 @@
   size_t Offset = 0;
   while (true) {
     const size_t NextOffset = DyLibComponentsStr.find(';', Offset);
-    DyLibComponents.push_back(DyLibComponentsStr.substr(Offset, NextOffset-Offset));
+    DyLibComponents.push_back(
+        DyLibComponentsStr.substr(Offset, NextOffset - Offset));
     if (NextOffset == std::string::npos) {
       break;
     }
@@ -326,7 +331,7 @@
   // Compute various directory locations based on the derived location
   // information.
   std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
-              ActiveCMakeDir;
+      ActiveCMakeDir;
   std::string ActiveIncludeOption;
   if (IsInDevelopmentTree) {
     ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";
@@ -540,9 +545,10 @@
             continue;
 
           Components.push_back(AvailableComponents[j].Name);
-          if (AvailableComponents[j].Library && !IsInDevelopmentTree) {
-            std::string path(
-                GetComponentLibraryPath(AvailableComponents[j].Library, false));
+          // TODO: Fix static vs shared.
+          if (AvailableComponents[j].StaticLibrary && !IsInDevelopmentTree) {
+            std::string path(GetComponentLibraryPath(
+                AvailableComponents[j].StaticLibrary, false));
             if (DirSep == "\\") {
               std::replace(path.begin(), path.end(), '/', '\\');
             }
diff --git a/llvm/unittests/Target/X86/CMakeLists.txt b/llvm/unittests/Target/X86/CMakeLists.txt
--- a/llvm/unittests/Target/X86/CMakeLists.txt
+++ b/llvm/unittests/Target/X86/CMakeLists.txt
@@ -11,11 +11,9 @@
   MIRParser
   Support
   Target
-  X86CodeGen
-  X86Desc
-  X86Info
+  TargetX86
   )
 
 add_llvm_unittest(X86Tests
   MachineSizeOptsTest.cpp
-  )
+)