aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dmitry Shevchenko <dmishe@google.com>2016-04-22 20:46:07 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-04-22 21:21:02 +0000
commit2036dbd666a3e6430480bcbe333c77376d35bc63 (patch)
tree4f36f6cabb108be6b67cd16a40899c39462bdfee
parente7be839c1ce7df2048b86bc956207f86db4e5b65 (diff)
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
-rw-r--r--examples/BUILD1
-rw-r--r--examples/swift/BUILD19
-rw-r--r--examples/swift/BarLib/BUILD15
-rw-r--r--examples/swift/BarLib/mul.swift8
-rw-r--r--examples/swift/constants.swift4
-rw-r--r--examples/swift/foo.swift9
-rw-r--r--src/test/shell/bazel/BUILD10
-rwxr-xr-xsrc/test/shell/bazel/bazel_apple_test.sh42
-rw-r--r--tools/BUILD2
-rw-r--r--tools/build_defs/apple/shared.bzl19
-rw-r--r--tools/build_defs/apple/swift.bzl110
11 files changed, 239 insertions, 0 deletions
diff --git a/examples/BUILD b/examples/BUILD
index 8bfbc19524..781c81a46c 100644
--- a/examples/BUILD
+++ b/examples/BUILD
@@ -11,5 +11,6 @@ filegroup(
"//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 0000000000..e2cbb195e2
--- /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 0000000000..d575a879f1
--- /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 0000000000..1f1df40512
--- /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 0000000000..6c16d34a82
--- /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 0000000000..067c6730cd
--- /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 49112206f4..cccd7874e6 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -94,6 +94,16 @@ sh_test(
)
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 0000000000..89141110a3
--- /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 302e3b7766..c55c0ad9e1 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -10,6 +10,7 @@ filegroup(
"//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 @@ filegroup(
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 70c6ae6239..bebfb7a9ad 100644
--- a/tools/build_defs/apple/shared.bzl
+++ b/tools/build_defs/apple/shared.bzl
@@ -37,6 +37,9 @@ DARWIN_EXECUTION_REQUIREMENTS = {"requires-darwin": ""}
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 @@ def apple_action(ctx, **kw):
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 0000000000..8f0eda18bb
--- /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.
+"""