Index: compiler-rt/trunk/cmake/Modules/CompilerRTUtils.cmake
===================================================================
--- compiler-rt/trunk/cmake/Modules/CompilerRTUtils.cmake
+++ compiler-rt/trunk/cmake/Modules/CompilerRTUtils.cmake
@@ -36,6 +36,16 @@
   endif()
 endmacro()
 
+# Appends values to list if it isn't already there
+macro(append_list_unique list)
+  foreach(val ${ARGN})
+    list(FIND ${list} ${val} idx)
+    if(idx EQUAL -1)
+      list(APPEND ${list} ${val})
+    endif()
+  endforeach()
+endmacro()
+
 # Appends value to all strings in ARGN, if the condition is true.
 macro(append_string_if condition value)
   if(${condition})
@@ -67,3 +77,12 @@
     endif()
   endforeach()
 endmacro()
+
+macro(check_list_contains outvar list input)
+  list(FIND ${list} ${input} idx)
+  if(idx GREATER -1)
+    set(${outvar} True)
+  else()
+    set(${outvar} False)
+  endif()
+endmacro()
Index: compiler-rt/trunk/cmake/config-ix.cmake
===================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake
+++ compiler-rt/trunk/cmake/config-ix.cmake
@@ -505,78 +505,82 @@
 if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
     (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD" OR
     (OS_NAME MATCHES "Windows" AND MSVC)))
-  set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE)
-else()
-  set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE)
+  list(APPEND DEFAULT_RUNTIMES sanitizer_common)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND
-    (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
-  set(COMPILER_RT_HAS_INTERCEPTION TRUE)
-else()
-  set(COMPILER_RT_HAS_INTERCEPTION FALSE)
+if (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)
+  list(APPEND DEFAULT_RUNTIMES interception)
+  list(APPEND REQUIRES_COMMON interception)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND
+if (ASAN_SUPPORTED_ARCH AND
     (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4))
-  set(COMPILER_RT_HAS_ASAN TRUE)
-else()
-  set(COMPILER_RT_HAS_ASAN FALSE)
+  list(APPEND DEFAULT_RUNTIMES asan)
+  list(APPEND REQUIRES_COMMON asan)
 endif()
 
 if (OS_NAME MATCHES "Linux|FreeBSD|Windows")
-  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE)
-else()
-  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE)
+  set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME On)
 endif()
 
 # TODO: Add builtins support.
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND
+if (DFSAN_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Linux")
-  set(COMPILER_RT_HAS_DFSAN TRUE)
-else()
-  set(COMPILER_RT_HAS_DFSAN FALSE)
+  list(APPEND DEFAULT_RUNTIMES dfsan)
+  list(APPEND REQUIRES_COMMON dfsan)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND
-    OS_NAME MATCHES "Linux|FreeBSD")
-  set(COMPILER_RT_HAS_LSAN TRUE)
-else()
-  set(COMPILER_RT_HAS_LSAN FALSE)
+if (LSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|FreeBSD")
+  list(APPEND DEFAULT_RUNTIMES lsan)
+  list(APPEND REQUIRES_COMMON lsan)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND
+if (MSAN_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Linux")
-  set(COMPILER_RT_HAS_MSAN TRUE)
-else()
-  set(COMPILER_RT_HAS_MSAN FALSE)
+  list(APPEND DEFAULT_RUNTIMES msan)
+  list(APPEND REQUIRES_COMMON msan)
 endif()
 
 if (PROFILE_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Darwin|Linux|FreeBSD")
-  set(COMPILER_RT_HAS_PROFILE TRUE)
-else()
-  set(COMPILER_RT_HAS_PROFILE FALSE)
+  list(APPEND DEFAULT_RUNTIMES profile)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND
+if (TSAN_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Darwin|Linux|FreeBSD")
-  set(COMPILER_RT_HAS_TSAN TRUE)
-else()
-  set(COMPILER_RT_HAS_TSAN FALSE)
+  list(APPEND DEFAULT_RUNTIMES tsan)
+  list(APPEND REQUIRES_COMMON tsan)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
+if (UBSAN_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows")
-  set(COMPILER_RT_HAS_UBSAN TRUE)
-else()
-  set(COMPILER_RT_HAS_UBSAN FALSE)
+  list(APPEND DEFAULT_RUNTIMES ubsan)
+  list(APPEND REQUIRES_COMMON ubsan)
 endif()
+list(APPEND DEFAULT_RUNTIMES cfi)
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND
+if (SAFESTACK_SUPPORTED_ARCH AND
     OS_NAME MATCHES "Darwin|Linux|FreeBSD")
-  set(COMPILER_RT_HAS_SAFESTACK TRUE)
-else()
-  set(COMPILER_RT_HAS_SAFESTACK FALSE)
+  list(APPEND DEFAULT_RUNTIMES safestack)
+  list(APPEND REQUIRES_COMMON safestack)
+endif()
+
+set(COMPILER_RT_RUNTIMES_TO_BUILD "all"
+    CACHE STRING "Semicolon-separated list of runtimes to build, or \"all\".")
+
+if(COMPILER_RT_RUNTIMES_TO_BUILD STREQUAL "all")
+  set(COMPILER_RT_RUNTIMES_TO_BUILD ${DEFAULT_RUNTIMES})
+endif()
+
+# Several of the runtimes produce object libraries that are consumed by other
+# runtimes (i.e. asan relies on ubsan). If you're building a library that relies
+# on common bits we need to build this full set of libraries.
+list_union(SHOULD_BUILD_COMMON REQUIRES_COMMON COMPILER_RT_RUNTIMES_TO_BUILD)
+
+if(SHOULD_BUILD_COMMON)
+  append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD sanitizer_common)
+  append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD lsan)
+  append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD ubsan)
+  append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD interception)
 endif()
Index: compiler-rt/trunk/lib/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/lib/CMakeLists.txt
+++ compiler-rt/trunk/lib/CMakeLists.txt
@@ -9,40 +9,9 @@
 endif()
 
 if(COMPILER_RT_BUILD_SANITIZERS)
-  if(COMPILER_RT_HAS_INTERCEPTION)
-    add_subdirectory(interception)
-  endif()
-
-  if(COMPILER_RT_HAS_SANITIZER_COMMON)
-    add_subdirectory(sanitizer_common)
-    add_subdirectory(lsan)
-    add_subdirectory(ubsan)
-  endif()
-
-  add_subdirectory(cfi)
-
-  if(COMPILER_RT_HAS_ASAN)
-    add_subdirectory(asan)
-  endif()
-
-  if(COMPILER_RT_HAS_DFSAN)
-    add_subdirectory(dfsan)
-  endif()
-
-  if(COMPILER_RT_HAS_MSAN)
-    add_subdirectory(msan)
-  endif()
-
-  if(COMPILER_RT_HAS_PROFILE)
-    add_subdirectory(profile)
-  endif()
-
-  if(COMPILER_RT_HAS_TSAN)
-    add_subdirectory(tsan)
-    add_subdirectory(tsan/dd)
-  endif()
-
-  if(COMPILER_RT_HAS_SAFESTACK)
-    add_subdirectory(safestack)
-  endif()
+  message(STATUS "Adding runtimes...")
+  foreach(runtime ${COMPILER_RT_RUNTIMES_TO_BUILD})
+    message(STATUS "Adding runtime: ${runtime}")
+    add_subdirectory(${runtime})
+  endforeach()
 endif()
Index: compiler-rt/trunk/lib/lsan/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/lib/lsan/CMakeLists.txt
+++ compiler-rt/trunk/lib/lsan/CMakeLists.txt
@@ -24,6 +24,7 @@
     SOURCES ${LSAN_COMMON_SOURCES}
     CFLAGS ${LSAN_CFLAGS})
 
+check_list_contains(COMPILER_RT_HAS_LSAN COMPILER_RT_RUNTIMES_TO_BUILD lsan)
 if(COMPILER_RT_HAS_LSAN)
   foreach(arch ${LSAN_SUPPORTED_ARCH})
     add_compiler_rt_runtime(clang_rt.lsan
Index: compiler-rt/trunk/lib/tsan/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/lib/tsan/CMakeLists.txt
+++ compiler-rt/trunk/lib/tsan/CMakeLists.txt
@@ -213,3 +213,5 @@
 if(COMPILER_RT_INCLUDE_TESTS)
   add_subdirectory(tests)
 endif()
+
+add_subdirectory(dd)
Index: compiler-rt/trunk/lib/ubsan/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/lib/ubsan/CMakeLists.txt
+++ compiler-rt/trunk/lib/ubsan/CMakeLists.txt
@@ -1,5 +1,7 @@
 # Build for the undefined behavior sanitizer runtime support library.
 
+check_list_contains(COMPILER_RT_HAS_UBSAN COMPILER_RT_RUNTIMES_TO_BUILD ubsan)
+
 set(UBSAN_SOURCES
   ubsan_diag.cc
   ubsan_init.cc
Index: compiler-rt/trunk/test/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/test/CMakeLists.txt
+++ compiler-rt/trunk/test/CMakeLists.txt
@@ -36,37 +36,9 @@
 # Run sanitizer tests only if we're sure that clang would produce
 # working binaries.
 if(COMPILER_RT_CAN_EXECUTE_TESTS)
-  if(COMPILER_RT_HAS_ASAN)
-    add_subdirectory(asan)
-  endif()
-  if(COMPILER_RT_HAS_DFSAN)
-    add_subdirectory(dfsan)
-  endif()
-  if(COMPILER_RT_HAS_LSAN)
-    add_subdirectory(lsan)
-  endif()
-  if(COMPILER_RT_HAS_MSAN)
-    add_subdirectory(msan)
-  endif()
-  if(COMPILER_RT_HAS_PROFILE)
-    add_subdirectory(profile)
-  endif()
-  if(COMPILER_RT_HAS_SANITIZER_COMMON)
-    add_subdirectory(sanitizer_common)
-  endif()
-  if(COMPILER_RT_HAS_TSAN)
-    add_subdirectory(tsan)
-  endif()
-  if(COMPILER_RT_HAS_UBSAN)
-    add_subdirectory(ubsan)
-  endif()
-  # CFI tests require diagnostic mode, which is implemented in UBSan.
-  if(COMPILER_RT_HAS_UBSAN)
-    add_subdirectory(cfi)
-  endif()
-  if(COMPILER_RT_HAS_SAFESTACK)
-    add_subdirectory(safestack)
-  endif()
+  foreach(runtime ${COMPILER_RT_RUNTIMES_TO_BUILD})
+    add_subdirectory(${runtime})
+  endforeach()
 endif()
 
 if(COMPILER_RT_STANDALONE_BUILD)
@@ -79,3 +51,4 @@
     ${LLVM_LIT_TESTSUITES}
     DEPENDS ${LLVM_LIT_DEPENDS})
 endif()
+ 
Index: compiler-rt/trunk/test/cfi/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/test/cfi/CMakeLists.txt
+++ compiler-rt/trunk/test/cfi/CMakeLists.txt
@@ -1,3 +1,9 @@
+check_list_contains(HAS_UBSAN COMPILER_RT_RUNTIMES_TO_BUILD ubsan)
+# CFI tests require diagnostic mode, which is implemented in UBSan.
+if(NOT HAS_UBSAN)
+  return()
+endif()
+
 configure_lit_site_cfg(
   ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
   ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
Index: compiler-rt/trunk/test/interception/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/test/interception/CMakeLists.txt
+++ compiler-rt/trunk/test/interception/CMakeLists.txt
@@ -0,0 +1 @@
+# Placeholder to avoid special casing.
Index: compiler-rt/trunk/test/ubsan/CMakeLists.txt
===================================================================
--- compiler-rt/trunk/test/ubsan/CMakeLists.txt
+++ compiler-rt/trunk/test/ubsan/CMakeLists.txt
@@ -20,6 +20,10 @@
   darwin_filter_host_archs(UBSAN_SUPPORTED_ARCH UBSAN_TEST_ARCH)
 endif()
 
+check_list_contains(HAS_ASAN COMPILER_RT_RUNTIMES_TO_BUILD asan)
+check_list_contains(HAS_MSAN COMPILER_RT_RUNTIMES_TO_BUILD msan)
+check_list_contains(HAS_TSAN COMPILER_RT_RUNTIMES_TO_BUILD tsan)
+
 foreach(arch ${UBSAN_TEST_ARCH})
   set(UBSAN_TEST_TARGET_ARCH ${arch})
   if(${arch} MATCHES "arm|aarch64")
@@ -31,13 +35,17 @@
   endif()
   add_ubsan_testsuite("Standalone" ubsan ${arch})
 
-  if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+  check_list_contains(ASAN_HAS_ARCH ASAN_SUPPORTED_ARCH ${arch})
+  check_list_contains(MSAN_HAS_ARCH MSAN_SUPPORTED_ARCH ${arch})
+  check_list_contains(TSAN_HAS_ARCH TSAN_SUPPORTED_ARCH ${arch})
+
+  if(HAS_ASAN AND ASAN_HAS_ARCH)
     add_ubsan_testsuite("AddressSanitizer" asan ${arch})
   endif()
-  if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+  if(HAS_MSAN AND MSAN_HAS_ARCH)
     add_ubsan_testsuite("MemorySanitizer" msan ${arch})
   endif()
-  if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};")
+  if(HAS_TSAN AND TSAN_HAS_ARCH)
     add_ubsan_testsuite("ThreadSanitizer" tsan ${arch})
   endif()
 endforeach()