Merge pull request #209 from tonyfreeman/signature

Fix XCTAssertThrowsError function signature
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..56edf36
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,134 @@
+Adrian-Constantin Popescu <epsilon.gamma@gmail.com> <adrian-constantin.popescu@outlook.com>
+Alex Blewitt <alblue@apple.com> <alex.blewitt@gmail.com>
+Alex Hoppen <alex@alexhoppen.de> <alex@ateamer.de>
+Alexis Beingessner <abeingessner@apple.com> <a.beingessner@gmail.com>
+Alper Çugun <github@alper.nl> <alper@users.noreply.github.com>
+Amr Aboelela <amraboelela@gmail.com> <amraboelela@users.noreply.github.com>
+Ankit Aggarwal <ankit_aggarwal@apple.com> <ankit.spd@gmail.com>
+Argyrios Kyrtzidis <kyrtzidis@apple.com> <akyrtzi@gmail.com>
+Arsen Gasparyan <to.arsen.gasparyan@gmail.com> <frootloops@users.noreply.github.com>
+Ben Cohen <ben_cohen@apple.com>
+Ben Cohen <ben_cohen@apple.com> <airspeedswift@users.noreply.github.com>
+Ben Cohen <ben_cohen@apple.com> <ben@airspeedvelocity.net>
+Ben Langmuir <blangmuir@apple.com> <ben.langmuir@gmail.com>
+Brent Royal-Gordon <brent@brentdax.com> <brent@architechies.com>
+Brian Croom <bcroom@apple.com> <brian.s.croom@gmail.com>
+Brian Gesiak <bgesiak@fb.com> <modocache@gmail.com>
+Bryan Chan <bryan.chan@ca.ibm.com> <bryanpkc@gmail.com>
+Calvin Hill <mr_j.c.h@hotmail.com> <return@users.noreply.github.com>
+Chris Bieneman <beanz@apple.com>
+Chris Bieneman <beanz@apple.com> <cbieneman@apple.com>
+Chris Lattner <clattner@nondot.org> <clattner@apple.com>
+Chris Lattner <clattner@nondot.org> <lattner@users.noreply.github.com>
+Chris Lattner <clattner@nondot.org> <sabre@iMac.local>
+Chris Williams <cwilliams@fitbit.com> <ultramiraculous@users.noreply.github.com>
+codester <sahil.profile@gmail.com> codestergit <sahil.profile@gmail.com>
+Dan Liew <dliew@apple.com> <36706441+danliew-apple@users.noreply.github.com>
+Daniel Duan <daniel@duan.org> <danmarner@gmail.com>
+Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>
+Dave <davesweeris@mac.com>
+Dave Abrahams <dabrahams@apple.com> <dave@boostpro.com>
+Dave Abrahams <dabrahams@apple.com> <dave@fripp.apple.com>
+Dave Abrahams <dabrahams@apple.com> <dave@Skree.local>
+Dave Abrahams <dabrahams@apple.com> <dave@Wingy.local>
+Dave Lee <davelee@lyft.com> <davelee.com@gmail.com>
+David Rönnqvist <david.ronnqvist@gmail.com> <david.ronnqvist@skype.net>
+David Zarzycki <dave@znu.io> <zarzycki@icloud.com>
+David Zarzycki <dave@znu.io> <zarzycki@mac.com>
+Davide Italiano <ditaliano@apple.com> <dcci@users.noreply.github.com>
+Davide Italiano <ditaliano@apple.com> <dccitaliano@gmail.com>
+Dmitri Gribenko <gribozavr@gmail.com> <dgribenko@apple.com>
+Doug Coleman <doug_coleman@apple.com> <doug.coleman@gmail.com>
+Enrico Granata <egranata@apple.com> <egranata@egranata.apple.com>
+Enrico Granata <egranata@apple.com> <granata.enrico@gmail.com>
+Erik Eckstein <eeckstein@apple.com> <eeckstein@apple.com>
+Erik Eckstein <eeckstein@apple.com> <eeckstein@rad-main.corp.apple.com>
+Erik Verbruggen <erik.verbruggen@me.com> <erikjv@users.noreply.github.com>
+Ewa Matejska <ematejska@apple.com> <ematejska@apple.com>
+Ewa Matejska <ematejska@apple.com> <ematejska@Ewas-MacBook-Pro.local>
+Ewa Matejska <ematejska@apple.com> <ewamatejska@Ewas-iMac.local>
+Florent Bruneau <florent.bruneau@intersec.com> <florent.bruneau_github@m4x.org>
+Francis Ricci <fjricci@fb.com> <francisjricci@gmail.com>
+GauravDS <er.gauravds@gmail.com> <gaurav.sharma@punchh.com>
+Graydon Hoare <ghoare@apple.com> <graydon@users.noreply.github.com>
+Greg Parker <gparker@apple.com> <gparker-github@sealiesoftware.com>
+Guillaume Lessard <dhtnstff@gmail.com> <glessard@users.noreply.github.com>
+Hamish <hamish2knight@gmail.com> <hamish2knight@gmail.com>
+Han Sangjin <tinysun@jssolution.co.kr> <tinysun.net@gmail.com>
+Harlan Haskins <harlan@apple.com> <harlan@harlanhaskins.com>
+Hitster GTD <hitstergtd@users.noreply.github.com> <hitstergtd@users.noreply.github.com>
+Huon Wilson <huon@apple.com> <dbau.pp+github@gmail.com>
+Ingmar Stein <IngmarStein@users.noreply.github.com>
+Itai Ferber <iferber@apple.com> <itai@itaiferber.net>
+Jacob Bandes-Storch <jacob@bandes-stor.ch> <jacob@bandes-storch.net>
+Jacob Mizraji <jmizraji@apple.com> <jacobmizraji@gmail.com>
+Janosch Hildebrand <jnosh@jnosh.com> <jnosh+git@jnosh.com>
+Janosch Hildebrand <jnosh@jnosh.com> <jnosh+github@jnosh.com>
+Javier Soto <jsbustos@twitch.tv> <javier.api@gmail.com>
+Javier Soto <jsbustos@twitch.tv> <javiers@twitter.com>
+Joe <joe@iachieved.it>
+Joe <joewillsher@icloud.com>
+joe DeCapo <joe@polka.cat>
+Joe Groff <jgroff@apple.com> <arcata@gmail.com>
+Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@iMac-2.local>
+Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@Joes-iMac-Pro.local>
+Johannes Weiß <johannesweiss@apple.com> <github@tux4u.de>
+John Regner <john@johnregner.com> <regnerjr@gmail.com>
+Karoy Lorentey <klorentey@apple.com> <karoly@lorentey.hu>
+Keith Smiley <k@keith.so> <keithbsmiley@gmail.com>
+Kevin Ballard <kevin@sb.org> <kevin.ballard@postmates.com>
+Kosuke Ogawa <ogawa_kousuke@aratana.jp> <koogawa.app@gmail.com>
+Kuba Mracek <mracek@apple.com> <jbrecka@apple.com>
+Luiz Fernando Silva <luizinho_mack@yahoo.com.br>
+Luqman Aden <luqman@apple.com> <luqman_aden@apple.com>
+Marcelo Fabri <me@marcelofabri.com> <marcelofabri@users.noreply.github.com>
+Mark Lacey <mark.lacey@apple.com> <rudkx@icloud.com>
+Mark Lacey <mark.lacey@apple.com> <rudkx@users.noreply.github.com>
+Matt Rajca <matt.rajca@me.com> <mattrajca@users.noreply.github.com>
+Max Moiseev <moiseev@apple.com> <maxim.moiseev@gmail.com>
+Max Moiseev <moiseev@apple.com> <moiseev@users.noreply.github.com>
+Maxwell Swadling <maxs@apple.com> <maxwellswadling@gmail.com>
+Maxwell Swadling <maxs@apple.com> <mswadling@apple.com>
+Mayur Raiturkar <mayur@mayur.xyz> <mayurkr@users.noreply.github.com>
+Michael Gottesman <mgottesman@apple.com> <gottesmm@users.noreply.github.com>
+Michael Ilseman <milseman@apple.com> <michael.ilseman@gmail.com>
+Mike Ash <mikeash@apple.com> <mike@mikeash.com>
+Mike Ferris <mferris@apple.com> <mike@lorax.com>
+Mishal Awadah <mawadah@apple.com>
+Mishal Shah <mishal_shah@apple.com> <shahmishal@users.noreply.github.com>
+Nadav Rotem <nrotem@apple.com> <nadavrot@users.noreply.github.com>
+Nate Cook <natecook@apple.com> <nate@Nates-MacBook-Pro.local>
+Nate Cook <natecook@apple.com> <natecook@gmail.com>
+Nate Cook <natecook@apple.com> <natecook1000@users.noreply.github.com>
+Nate Cook <natecook@apple.com> <nmersethcook@apple.com>
+Nathan Lanza <lanza@fb.com> <nathan@lanza.io>
+Nicole Jacque <jacque@apple.com>
+Niels Andriesse <andriesseniels@gmail.com> <nielsandriesse@users.noreply.github.com>
+Paul Meng <mno2@mno2.org> <mno2.csie@gmail.com>
+Pavel Yaskevich <pyaskevich@apple.com> <xedin@apache.org>
+Paweł Szot <pszot@pgs-soft.com>
+Paweł Szot <pszot@pgs-soft.com> <qwertyszot@gmail.com>
+Pete Cooper <peter_cooper@apple.com>
+Philip Ridgeway <pridgeway@vernier.com> <philip.ridgeway@gmail.com>
+Richard Wei <rxwei@apple.com> <rxwei@google.com>
+Rintaro Ishizaki <rishizaki@apple.com> <fs.output@gmail.com>
+Robert Widmann <rwidmann@apple.com> <devteam.codafi@gmail.com>
+Roman Levenstein <rlevenstein@apple.com> <swiftix@users.noreply.github.com>
+Ross Bayer <ross.m.bayer@gmail.com> <Rostepher@users.noreply.github.com>
+Russ Bishop <rbishopjr@apple.com> <russ@plangrid.com>
+Ryan Lovelett <ryan@lovelett.me> <RLovelett@users.noreply.github.com>
+Shawn Erickson <shawn.erickson@citrix.com> <shawnce@gmail.com>
+Slava Pestov <spestov@apple.com> <spestov@rad-main.corp.apple.com>
+Slava Pestov <spestov@apple.com> <sviatoslav.pestov@gmail.com>
+Stephen Canon <scanon@apple.com>
+Stephen Canon <scanon@apple.com> <stephentyrone@gmail.com>
+Sukolsak Sakshuwong <sukolsak@gmail.com>
+Todd Fiala <tfiala@apple.com> <todd.fiala@gmail.com>
+Toni Suter <tonisuter@me.com> <tonisuter@users.noreply.github.com>
+Vedant Kumar <vsk@apple.com> <vk@vedantk.com>
+Xi Ge <xi_ge@apple.com> <xi_ge@rad-main.corp.apple.com>
+Xin Tong <xin_tong@apple.com> <trent.xin.tong@gmail.com>
+Xin Tong <xin_tong@apple.com> <trentxintong@Xins-MacBook-Pro.local>
+Yuka Ezura <ezura@users.noreply.github.com> <2020337+ezura@users.noreply.github.com>
+Yurii Samsoniuk <ura@google.com> <mr.sigito@gmail.com>
+Zac Bowling <zbowling@google.com> <zac@zacbowling.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..0630a2c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,129 @@
+
+cmake_minimum_required(VERSION 3.4.3)
+
+list(APPEND CMAKE_MODULE_PATH
+     "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+
+project(XCTest
+        LANGUAGES
+          C)
+
+option(XCTEST_PATH_TO_LIBDISPATCH_SOURCE "Path to libdispatch source" "")
+option(XCTEST_PATH_TO_LIBDISPATCH_BUILD "Path to libdispatch build" "")
+
+option(XCTEST_PATH_TO_FOUNDATION_BUILD "Path to Foundation build" "")
+
+option(XCTEST_PATH_TO_COREFOUNDATION_BUILD "Path to CoreFoundation build" "")
+
+find_package(LLVM CONFIG)
+if(NOT LLVM_FOUND)
+  message(SEND_ERROR "Could not find LLVM; configure with -DCMAKE_PREFIX_PATH=/path/to/llvm/install")
+endif()
+message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+
+include(${LLVM_DIR}/LLVMConfig.cmake)
+
+list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})
+include(AddLLVM)
+
+include(SwiftSupport)
+include(GNUInstallDirs)
+
+set(swift_optimization_flags)
+if(CMAKE_BUILD_TYPE MATCHES Release)
+  set(swift_optimization_flags -O)
+endif()
+
+add_swift_library(XCTest
+                  MODULE_NAME
+                    XCTest
+                  MODULE_LINK_NAME
+                    XCTest
+                  MODULE_PATH
+                    ${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftmodule
+                  OUTPUT
+                    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}XCTest${CMAKE_SHARED_LIBRARY_SUFFIX}
+                  LINK_FLAGS
+                    -L${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/src -ldispatch
+                    -L${XCTEST_PATH_TO_FOUNDATION_BUILD} -lFoundation
+
+                    # compatibility with Foundation build_script.py
+                    -L${XCTEST_PATH_TO_FOUNDATION_BUILD}/Foundation
+                  SOURCES
+                    Sources/XCTest/Private/WallClockTimeMetric.swift
+                    Sources/XCTest/Private/TestListing.swift
+                    Sources/XCTest/Private/XCTestCaseSuite.swift
+                    Sources/XCTest/Private/TestFiltering.swift
+                    Sources/XCTest/Private/XCTestInternalObservation.swift
+                    Sources/XCTest/Private/ObjectWrapper.swift
+                    Sources/XCTest/Private/PerformanceMeter.swift
+                    Sources/XCTest/Private/PrintObserver.swift
+                    Sources/XCTest/Private/ArgumentParser.swift
+                    Sources/XCTest/Private/XCPredicateExpectation.swift
+                    Sources/XCTest/Public/XCTestRun.swift
+                    Sources/XCTest/Public/XCTestMain.swift
+                    Sources/XCTest/Public/XCTestCase.swift
+                    Sources/XCTest/Public/XCTestSuite.swift
+                    Sources/XCTest/Public/XCTestSuiteRun.swift
+                    Sources/XCTest/Public/XCTestErrors.swift
+                    Sources/XCTest/Public/XCTestObservation.swift
+                    Sources/XCTest/Public/XCTestCaseRun.swift
+                    Sources/XCTest/Public/XCAbstractTest.swift
+                    Sources/XCTest/Public/XCTestObservationCenter.swift
+                    Sources/XCTest/Public/XCTestCase+Performance.swift
+                    Sources/XCTest/Public/XCTAssert.swift
+                    Sources/XCTest/Public/Asynchronous/XCTestCase+NotificationExpectation.swift
+                    Sources/XCTest/Public/Asynchronous/XCTestCase+PredicateExpectation.swift
+                    Sources/XCTest/Public/Asynchronous/XCPredicateExpectationHandler.swift
+                    Sources/XCTest/Public/Asynchronous/XCWaitCompletionHandler.swift
+                    Sources/XCTest/Public/Asynchronous/XCNotificationExpectationHandler.swift
+                    Sources/XCTest/Public/Asynchronous/XCTestCase+Asynchronous.swift
+                    Sources/XCTest/Public/Asynchronous/XCTestExpectation.swift
+                  SWIFT_FLAGS
+                    ${swift_optimization_flags}
+
+                    -I${XCTEST_PATH_TO_LIBDISPATCH_SOURCE}
+                    -I${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/src/swift
+                    -Xcc -fblocks
+
+                    -I${XCTEST_PATH_TO_FOUNDATION_BUILD}/swift
+                    -Fsystem ${XCTEST_PATH_TO_COREFOUNDATION_BUILD}/System/Library/Frameworks
+
+                    # compatibility with Foundation build_script.py
+                    -I${XCTEST_PATH_TO_FOUNDATION_BUILD}/Foundation
+                    -I${XCTEST_PATH_TO_FOUNDATION_BUILD}/Foundation/usr/lib/swift)
+
+if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
+  set(LIT_COMMAND "${PYTHON_EXECUTABLE};${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py"
+      CACHE STRING "command used to spawn llvm-lit")
+else()
+  find_program(LIT_COMMAND NAMES llvm-lit lit.py lit)
+endif()
+add_custom_target(check-xctest
+                  COMMAND
+                  ${CMAKE_COMMAND} -E env
+                    BUILT_PRODUCTS_DIR=${CMAKE_BINARY_DIR}
+                    CORE_FOUNDATION_BUILT_PRODUCTS_DIR=${XCTEST_PATH_TO_COREFOUNDATION_BUILD}
+                    FOUNDATION_BUILT_PRODUCTS_DIR=${XCTEST_PATH_TO_FOUNDATION_BUILD}
+                    LIBDISPATCH_SRC_DIR=${XCTEST_PATH_TO_LIBDISPATCH_SOURCE}
+                    LIBDISPATCH_BUILD_DIR=${XCTEST_PATH_TO_LIBDISPATCH_BUILD}
+                    LIBDISPATCH_OVERLAY_DIR=${XCTEST_PATH_TO_LIBDISPATCH_BUILD}/swift
+                    SWIFT_EXEC=${CMAKE_SWIFT_COMPILER}
+                    ${LIT_COMMAND} -sv ${CMAKE_SOURCE_DIR}/Tests/Functional
+                  COMMENT
+                    "Running XCTest functional test suite"
+                  DEPENDS
+                    XCTest
+                  USES_TERMINAL)
+
+install(FILES
+          ${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftdoc
+          ${CMAKE_CURRENT_BINARY_DIR}/swift/XCTest.swiftmodule
+        DESTINATION
+          ${CMAKE_INSTALL_FULL_LIBDIR}/swift/${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR})
+install(FILES
+          ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}XCTest${CMAKE_SHARED_LIBRARY_SUFFIX}
+        DESTINATION
+          ${CMAKE_INSTALL_FULL_LIBDIR})
+
diff --git a/Sources/XCTest/Private/PerformanceMeter.swift b/Sources/XCTest/Private/PerformanceMeter.swift
index a44144a..afb3e19 100644
--- a/Sources/XCTest/Private/PerformanceMeter.swift
+++ b/Sources/XCTest/Private/PerformanceMeter.swift
@@ -190,7 +190,7 @@
     }
 
     private func recordFailures() {
-        metrics.flatMap({ $0.failureMessage() }).forEach { message in
+        metrics.compactMap({ $0.failureMessage() }).forEach { message in
             delegate.recordFailure(description: message, file: invocationFile, line: invocationLine)
         }
     }
diff --git a/Sources/XCTest/Private/TestListing.swift b/Sources/XCTest/Private/TestListing.swift
index 2d32092..dcd54f4 100644
--- a/Sources/XCTest/Private/TestListing.swift
+++ b/Sources/XCTest/Private/TestListing.swift
@@ -53,7 +53,7 @@
 extension XCTestSuite: Listable {
     private var listables: [Listable] {
         return tests
-            .flatMap({ ($0 as? Listable) })
+            .compactMap({ ($0 as? Listable) })
     }
 
     private var listingName: String {
@@ -69,7 +69,7 @@
     }
 
     func dictionaryRepresentation() -> NSDictionary {
-        let listedTests = NSArray(array: tests.flatMap({ ($0 as? Listable)?.dictionaryRepresentation() }))
+        let listedTests = NSArray(array: tests.compactMap({ ($0 as? Listable)?.dictionaryRepresentation() }))
         return NSDictionary(objects: [NSString(string: listingName),
                                       listedTests],
                             forKeys: [NSString(string: "name"),
@@ -80,7 +80,7 @@
         if name.hasSuffix(".xctest") {
             return self
         } else {
-            return tests.flatMap({ ($0 as? XCTestSuite)?.findBundleTestSuite() }).first
+            return tests.compactMap({ ($0 as? XCTestSuite)?.findBundleTestSuite() }).first
         }
     }
 }
diff --git a/Tests/Functional/lit.cfg b/Tests/Functional/lit.cfg
index dc0f86b..b047551 100644
--- a/Tests/Functional/lit.cfg
+++ b/Tests/Functional/lit.cfg
@@ -45,6 +45,7 @@
     '-Xlinker', built_products_dir,
     '-L', built_products_dir,
     '-I', built_products_dir,
+    '-I', os.path.join(built_products_dir, 'swift'),
 ]
 
 if platform.system() == 'Darwin':
@@ -76,7 +77,9 @@
         '-Xlinker', foundation_dir,
         '-L', foundation_dir,
         '-I', foundation_dir,
+        '-I', os.path.join(foundation_dir, 'swift'),
         '-I', core_foundation_dir,
+        '-F', os.path.join(core_foundation_dir, 'System', 'Library', 'Frameworks'),
     ])
     config.environment['LD_LIBRARY_PATH'] = foundation_dir
     # We also need to link swift-corelibs-libdispatch, if
@@ -92,6 +95,7 @@
                 '-I', libdispatch_src_dir,
                 '-I', libdispatch_overlay_dir,
                 '-L', libdispatch_build_dir,
+                '-L', os.path.join(libdispatch_build_dir, 'src'),
             ])
 
 # Having prepared the swiftc command, we set the substitution.
diff --git a/build_script.py b/build_script.py
index b470f01..43a477d 100755
--- a/build_script.py
+++ b/build_script.py
@@ -156,6 +156,8 @@
         build_dir = os.path.abspath(args.build_dir)
         static_lib_build_dir = GenericUnixStrategy.static_lib_build_dir(build_dir)
         foundation_build_dir = os.path.abspath(args.foundation_build_dir)
+        swift_build_dir = os.path.abspath(args.swift_build_dir)
+        arch = platform.machine()
         core_foundation_build_dir = GenericUnixStrategy.core_foundation_build_dir(
             foundation_build_dir, args.foundation_install_prefix)
         if args.libdispatch_build_dir:
@@ -200,7 +202,8 @@
                 libdispatch_args=libdispatch_args,
                 source_paths=" ".join(sourcePaths)))
         run("{swiftc} -emit-library {build_dir}/XCTest.o "
-            "-L {dispatch_build_dir} -L {foundation_build_dir} -lswiftGlibc -lswiftCore -lFoundation -lm "
+            "-L {dispatch_build_dir} -L {foundation_build_dir} -L {swift_build_dir} "
+            "-lswiftGlibc -lswiftCore -lFoundation -lm "
             # We embed an rpath of `$ORIGIN` to ensure other referenced
             # libraries (like `Foundation`) can be found solely via XCTest.
             "-Xlinker -rpath=\\$ORIGIN "
@@ -208,7 +211,8 @@
                 swiftc=swiftc,
                 build_dir=build_dir,
                 dispatch_build_dir=os.path.join(args.libdispatch_build_dir, 'src', '.libs'),
-                foundation_build_dir=foundation_build_dir))
+                foundation_build_dir=foundation_build_dir,
+                swift_build_dir=os.path.join(args.swift_build_dir, 'lib', 'swift', 'linux', arch)))
 
         # Build the static library.
         run("mkdir -p {static_lib_build_dir}".format(static_lib_build_dir=static_lib_build_dir))
@@ -432,6 +436,10 @@
              "FOUNDATION_BUILD_DIR/FOUNDATION_INSTALL_PREFIX.",
         default="/usr")
     build_parser.add_argument(
+        "--swift-build-dir",
+        help="Path to swift build products, which the built XCTest.so "
+             "will be linked against.")
+    build_parser.add_argument(
         "--libdispatch-build-dir",
         help="Path to swift-corelibs-libdispatch build products, which "
              "the built XCTest.so will be linked against.")
diff --git a/cmake/modules/SwiftSupport.cmake b/cmake/modules/SwiftSupport.cmake
new file mode 100644
index 0000000..c608419
--- /dev/null
+++ b/cmake/modules/SwiftSupport.cmake
@@ -0,0 +1,133 @@
+
+include(CMakeParseArguments)
+
+function(add_swift_target target)
+  set(options LIBRARY)
+  set(single_value_options MODULE_NAME;MODULE_LINK_NAME;MODULE_PATH;MODULE_CACHE_PATH;OUTPUT;TARGET)
+  set(multiple_value_options CFLAGS;DEPENDS;LINK_FLAGS;SOURCES;SWIFT_FLAGS)
+
+  cmake_parse_arguments(AST "${options}" "${single_value_options}" "${multiple_value_options}" ${ARGN})
+
+  set(flags ${CMAKE_SWIFT_FLAGS})
+  set(link_flags)
+
+  if(AST_TARGET)
+    list(APPEND flags -target;${AST_TARGET})
+  endif()
+  if(AST_MODULE_NAME)
+    list(APPEND flags -module-name;${AST_MODULE_NAME})
+  else()
+    list(APPEND flags -module-name;${target})
+  endif()
+  if(AST_MODULE_LINK_NAME)
+    list(APPEND flags -module-link-name;${AST_MODULE_LINK_NAME})
+  endif()
+  if(AST_MODULE_CACHE_PATH)
+    list(APPEND flags -module-cache-path;${AST_MODULE_CACHE_PATH})
+  endif()
+  if(AST_SWIFT_FLAGS)
+    foreach(flag ${AST_SWIFT_FLAGS})
+      list(APPEND flags ${flag})
+    endforeach()
+  endif()
+  if(AST_CFLAGS)
+    foreach(flag ${AST_CFLAGS})
+      list(APPEND flags -Xcc;${flag})
+    endforeach()
+  endif()
+  if(AST_LINK_FLAGS)
+    foreach(flag ${AST_LINK_FLAGS})
+      list(APPEND link_flags ${flag})
+    endforeach()
+  endif()
+  if(NOT AST_OUTPUT)
+    if(AST_LIBRARY)
+      set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX})
+    else()
+      set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${target}${CMAKE_EXECUTABLE_SUFFIX})
+    endif()
+  endif()
+
+  set(sources)
+  foreach(source ${AST_SOURCES})
+    get_filename_component(location ${source} PATH)
+    if(IS_ABSOLUTE ${location})
+      list(APPEND sources ${source})
+    else()
+      list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/${source})
+    endif()
+  endforeach()
+
+  set(objs)
+  set(mods)
+  set(docs)
+  set(i 0)
+  foreach(source ${sources})
+    get_filename_component(name ${source} NAME)
+
+    set(obj ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}${CMAKE_C_OUTPUT_EXTENSION})
+    set(mod ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.swiftmodule)
+    set(doc ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.swiftdoc)
+
+    set(all_sources ${sources})
+    list(INSERT all_sources ${i} -primary-file)
+
+    add_custom_command(OUTPUT
+                         ${obj}
+                         ${mod}
+                         ${doc}
+                       DEPENDS
+                         ${source}
+                       COMMAND
+                         ${CMAKE_SWIFT_COMPILER} -frontend ${flags} -emit-module-path ${mod} -emit-module-doc-path ${doc} -o ${obj} -c ${all_sources})
+
+    list(APPEND objs ${obj})
+    list(APPEND mods ${mod})
+    list(APPEND docs ${doc})
+
+    math(EXPR i "${i}+1")
+  endforeach()
+
+  if(AST_LIBRARY)
+    get_filename_component(module_directory ${AST_MODULE_PATH} DIRECTORY)
+
+    set(module ${AST_MODULE_PATH})
+    set(documentation ${module_directory}/${AST_MODULE_NAME}.swiftdoc)
+
+    add_custom_command(OUTPUT
+                         ${module}
+                         ${documentation}
+                       DEPENDS
+                         ${mods}
+                         ${docs}
+                       COMMAND
+                         ${CMAKE_SWIFT_COMPILER} -frontend ${flags} -sil-merge-partial-modules -emit-module ${mods} -o ${module} -emit-module-doc-path ${documentation})
+  endif()
+
+  if(AST_LIBRARY)
+    set(emit_library -emit-library)
+  endif()
+  add_custom_command(OUTPUT
+                       ${AST_OUTPUT}
+                     DEPENDS
+                       ${objs}
+                     COMMAND
+                       ${CMAKE_SWIFT_COMPILER} ${emit_library} ${link_flags} -o ${AST_OUTPUT} ${objs}
+                     COMMAND
+                       ${CMAKE_COMMAND} -E copy ${AST_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR})
+  add_custom_target(${target}
+                    ALL
+                    DEPENDS
+                       ${AST_OUTPUT}
+                       ${module}
+                       ${documentation})
+endfunction()
+
+function(add_swift_library library)
+  add_swift_target(${library} LIBRARY ${ARGN})
+endfunction()
+
+function(add_swift_executable executable)
+  add_swift_target(${executable} ${ARGN})
+endfunction()
+