Add a Skylark rule to build Swift modules.

* Adds a swift_library rule that produces a (.a, .swiftmodule) pair. It can handle dependencies between modules and can be used as a dependency of objc_binary.
* Does not work with Objective-C yet.

--
MOS_MIGRATED_REVID=120578875
diff --git a/examples/BUILD b/examples/BUILD
index 8bfbc19..781c81a 100644
--- a/examples/BUILD
+++ b/examples/BUILD
@@ -11,5 +11,6 @@
         "//examples/py:srcs",
         "//examples/py_native:srcs",
         "//examples/shell:srcs",
+        "//examples/swift:srcs",
     ],
 )
diff --git a/examples/swift/BUILD b/examples/swift/BUILD
new file mode 100644
index 0000000..e2cbb19
--- /dev/null
+++ b/examples/swift/BUILD
@@ -0,0 +1,19 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])  # Apache 2.0
+
+load("//tools/build_defs/apple:swift.bzl", "swift_library")
+
+swift_library(
+    name = "swift_lib",
+    srcs = glob(["*.swift"]),
+    deps = ["//examples/swift/BarLib"],
+)
+
+filegroup(
+    name = "srcs",
+    srcs = glob(["**"]) + [
+        "//examples/swift/BarLib:srcs",
+    ],
+    visibility = ["//examples:__pkg__"],
+)
diff --git a/examples/swift/BarLib/BUILD b/examples/swift/BarLib/BUILD
new file mode 100644
index 0000000..d575a87
--- /dev/null
+++ b/examples/swift/BarLib/BUILD
@@ -0,0 +1,15 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])  # Apache 2.0
+
+load("//tools/build_defs/apple:swift.bzl", "swift_library")
+
+swift_library(
+    name = "BarLib",
+    srcs = ["mul.swift"],
+)
+
+filegroup(
+    name = "srcs",
+    srcs = glob(["**"]),
+)
diff --git a/examples/swift/BarLib/mul.swift b/examples/swift/BarLib/mul.swift
new file mode 100644
index 0000000..1f1df40
--- /dev/null
+++ b/examples/swift/BarLib/mul.swift
@@ -0,0 +1,8 @@
+/// Class used to multiply stuff.
+public class Multiplier {
+  public init() {}
+
+  public func multiply(a: Int, _ b: Int) -> Int {
+      return a * b
+  }
+}
diff --git a/examples/swift/constants.swift b/examples/swift/constants.swift
new file mode 100644
index 0000000..6c16d34
--- /dev/null
+++ b/examples/swift/constants.swift
@@ -0,0 +1,4 @@
+class Constants {
+  static var x = 2
+  static var y = 3
+}
\ No newline at end of file
diff --git a/examples/swift/foo.swift b/examples/swift/foo.swift
new file mode 100644
index 0000000..067c673
--- /dev/null
+++ b/examples/swift/foo.swift
@@ -0,0 +1,9 @@
+import class BarLib.Multiplier
+
+public class Foo {
+  public init() {}
+
+  public func multiply() -> Int {
+    return Multiplier().multiply(Constants.x, Constants.y)
+  }
+}
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 4911220..cccd787 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -94,6 +94,16 @@
 )
 
 sh_test(
+    name = "bazel_apple_test",
+    srcs = ["bazel_apple_test.sh"],
+    data = [
+        ":objc-deps",
+        ":test-deps",
+        "//:workspace-file",
+    ],
+)
+
+sh_test(
     name = "bazel_rules_test",
     size = "large",
     srcs = ["bazel_rules_test.sh"],
diff --git a/src/test/shell/bazel/bazel_apple_test.sh b/src/test/shell/bazel/bazel_apple_test.sh
new file mode 100755
index 0000000..8914111
--- /dev/null
+++ b/src/test/shell/bazel/bazel_apple_test.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Tests the examples provided in Bazel
+#
+
+# Load test environment
+source $(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test-setup.sh \
+  || { echo "test-setup.sh not found!" >&2; exit 1; }
+
+if [ "${PLATFORM}" != "darwin" ]; then
+  echo "This test suite requires running on OS X" >&2
+  exit 0
+fi
+
+function set_up() {
+  copy_examples
+}
+
+function test_swift_library() {
+  rm WORKSPACE
+  ln -sv ${workspace_file} WORKSPACE
+
+  local swift_lib_pkg=examples/swift
+  assert_build_output ./bazel-bin/${swift_lib_pkg}/swift_lib.a ${swift_lib_pkg}:swift_lib
+  assert_build_output ./bazel-bin/${swift_lib_pkg}/swift_lib.swiftmodule ${swift_lib_pkg}:swift_lib
+}
+
+run_suite "apple_tests"
diff --git a/tools/BUILD b/tools/BUILD
index 302e3b7..c55c0ad 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -10,6 +10,7 @@
         "//tools/android:srcs",
         "//tools/android/jack:srcs",
         "//tools/buildstamp:srcs",
+        "//tools/build_defs/apple:srcs",
         "//tools/build_defs/docker:srcs",
         "//tools/build_defs/jsonnet:srcs",
         "//tools/build_defs/pkg:srcs",
@@ -34,6 +35,7 @@
     srcs = glob(["**"]) + [
         "//tools/android/jack:srcs",
         "//tools/android:srcs",
+        "//tools/build_defs/apple:srcs",
         "//tools/build_defs/docker:srcs",
         "//tools/build_defs/jsonnet:srcs",
         "//tools/build_defs/pkg:srcs",
diff --git a/tools/build_defs/apple/shared.bzl b/tools/build_defs/apple/shared.bzl
index 70c6ae6..bebfb7a 100644
--- a/tools/build_defs/apple/shared.bzl
+++ b/tools/build_defs/apple/shared.bzl
@@ -37,6 +37,9 @@
 
 See :func:`apple_action`."""
 
+XCRUNWRAPPER_LABEL = "//external:xcrunwrapper"
+"""The label for xcrunwrapper tool."""
+
 def apple_action(ctx, **kw):
   """Creates an action that only runs on MacOS/Darwin.
 
@@ -49,3 +52,19 @@
 
   ctx.action(**kw)
 
+def xcrun_action(ctx, **kw):
+  """Creates an apple action that executes xcrunwrapper.
+
+  args:
+    ctx: The context of the rule that owns this action.
+
+  This method takes the same keyword arguments as ctx.action, however you don't
+  need to specify the executable.
+  """
+  platform = ctx.fragments.apple.ios_cpu_platform()
+  action_env = ctx.fragments.apple.target_apple_env(platform) \
+      + ctx.fragments.apple.apple_host_system_env()
+  env = kw.get('env', {})
+  kw['env'] = env + action_env
+
+  apple_action(ctx, executable=ctx.executable._xcrunwrapper, **kw)
diff --git a/tools/build_defs/apple/swift.bzl b/tools/build_defs/apple/swift.bzl
new file mode 100644
index 0000000..8f0eda1
--- /dev/null
+++ b/tools/build_defs/apple/swift.bzl
@@ -0,0 +1,110 @@
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Skylark rules for Swift."""
+
+load("shared", "xcrun_action", "XCRUNWRAPPER_LABEL")
+
+def _swift_target(cpu, sdk_version):
+  """Returns a target triplet for Swift compiler."""
+  return "%s-apple-ios%s" % (cpu, sdk_version)
+
+def _swift_library_impl(ctx):
+  """Implementation for swift_library Skylark rule."""
+  cpu = ctx.fragments.apple.ios_cpu()
+  platform = ctx.fragments.apple.ios_cpu_platform()
+  sdk_version = ctx.fragments.apple.sdk_version_for_platform(platform)
+  target = _swift_target(cpu, sdk_version)
+
+  # Collect transitive dependecies.
+  dep_modules = []
+  dep_libs = []
+  for x in ctx.attr.deps:
+    swift_provider = x.swift
+    dep_libs.append(swift_provider.library)
+    dep_libs += swift_provider.transitive_libs
+
+    dep_modules.append(swift_provider.module)
+    dep_modules += swift_provider.transitive_modules
+
+  # TODO(b/28005753): Currently this is not really a library, but an object
+  # file, does not matter to the linker, but should be replaced with proper ar
+  # call.
+  output_lib = ctx.outputs.swift_lib
+  output_module = ctx.outputs.swift_module
+
+  srcs_args = [f.path for f in ctx.files.srcs]
+
+  # TODO(b/28005582): Instead of including a dir for each dependecy, output to
+  # a shared dir and include that?
+  include_dirs = set([x.dirname for x in dep_modules])
+  include_args = ["-I%s" % d for d in include_dirs]
+
+  args = [
+      "swift",
+      "-frontend",
+      "-emit-object",
+      "-emit-module-path", output_module.path,
+      "-module-name", ctx.label.name,
+      "-parse-as-library",
+      "-target", target,
+      # TODO(b/28049126): Replace this value with apple_toolchain call.
+      "-sdk", "__BAZEL_XCODE_SDKROOT__",
+      "-o", output_lib.path,
+      ] + srcs_args + include_args
+
+  xcrun_action(ctx,
+      inputs = ctx.files.srcs + dep_modules + dep_libs,
+      outputs = (output_lib, output_module),
+      mnemonic = 'SwiftCompile',
+      arguments = args,
+      use_default_shell_env = False,
+      progress_message = ("Compiling Swift module %s (%d files)"
+                          % (ctx.label.name, len(ctx.files.srcs))))
+
+  return struct(
+      swift=struct(
+          library=output_lib,
+          module=output_module,
+          transitive_libs=dep_libs,
+          transitive_modules=dep_modules),
+      objc_export=struct(
+          library=set([output_lib] + dep_libs),
+          )
+  )
+
+swift_library = rule(
+    _swift_library_impl,
+    attrs = {
+        "srcs": attr.label_list(allow_files = FileType([".swift"])),
+        "deps": attr.label_list(providers=["swift"]),
+        "_xcrunwrapper": attr.label(
+            executable=True,
+            default=Label(XCRUNWRAPPER_LABEL))},
+    fragments = ["apple"],
+    outputs = {
+        "swift_lib": "%{name}.a",
+        "swift_module": "%{name}.swiftmodule",
+    },
+)
+"""
+Builds a Swift module.
+
+A module is a pair of static library (.a) + module header (.swiftmodule).
+Dependant targets can import this module as "import RuleName".
+
+Args:
+  srcs: Swift sources that comprise this module.
+  deps: Other Swift modules.
+"""