aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dmitry Shevchenko <dmishe@google.com>2016-10-03 22:12:28 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-10-04 08:55:09 +0000
commitdeeeb31f8ba0f196fbc9ca2a177d59d57ea50b32 (patch)
tree999abbd9c868be741495a0fc63a3ac77b7d31deb
parent169e68f4f3fcc000cc4fedebf15a9ea9373784e4 (diff)
Add a way to select non-default Xcode toolchain
* Adds a flag --xcode_toolchain which sets TOOLCHAINS env variable for xcrun. * Updates swift_library to work with this flag when selecting Swift runtime location. * By default the flag has a null value and is not set in env. -- MOS_MIGRATED_REVID=135033093
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java44
-rwxr-xr-xsrc/tools/xcode/swiftstdlibtoolwrapper/swiftstdlibtoolwrapper.sh47
-rw-r--r--tools/build_defs/apple/swift.bzl38
6 files changed, 148 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
index 5d2830a049..3d71ca5ad8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
@@ -227,6 +227,17 @@ public class AppleCommandLineOptions extends FragmentOptions {
}
}
+ @Option(
+ name = "xcode_toolchain",
+ defaultValue = "null",
+ category = "flags",
+ help = "The identifier of an Xcode toolchain to use for builds. Currently only the toolchains "
+ + "that ship with Xcode are supported. For example, in addition to the default toolchain"
+ + " Xcode 8 has 'com.apple.dt.toolchain.Swift_2_3' which can be used for building legacy"
+ + " Swift code."
+ )
+ public String xcodeToolchain;
+
@Option(name = "apple_bitcode",
converter = AppleBitcodeMode.Converter.class,
// TODO(blaze-team): Default to embedded_markers when fully implemented.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
index 59a6fc1403..e0d242703f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
@@ -84,6 +84,7 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
private final ImmutableList<String> tvosCpus;
private final AppleBitcodeMode bitcodeMode;
private final Label xcodeConfigLabel;
+ @Nullable private final String xcodeToolchain;
@Nullable private final Label defaultProvisioningProfileLabel;
private final boolean disableNativeSwiftRules;
@@ -127,6 +128,7 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
this.xcodeConfigLabel =
Preconditions.checkNotNull(appleOptions.xcodeVersionConfig, "xcodeConfigLabel");
this.defaultProvisioningProfileLabel = appleOptions.defaultProvisioningProfile;
+ this.xcodeToolchain = appleOptions.xcodeToolchain;
this.disableNativeSwiftRules = appleOptions.disableNativeSwiftRules;
}
@@ -519,6 +521,17 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
return Joiner.on('-').join(components);
}
+ /** Returns the identifier for an Xcode toolchain to use with tools. */
+ @SkylarkCallable(
+ name = "xcode_toolchain",
+ doc = "Identifier for the custom Xcode toolchain to use in build or None if not specified",
+ allowReturnNones = true,
+ structField = true
+ )
+ public String getXcodeToolchain() {
+ return xcodeToolchain;
+ }
+
/**
* Whether the native Swift support should be disabled. Used to deprecate said functionality.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index fa16aaf3f9..8136e837ca 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -1445,9 +1445,22 @@ public final class CompilationSupport {
}
if (objcProvider.is(USES_SWIFT)) {
- commandLine
- .add("-L")
- .add(AppleToolchain.swiftLibDir(appleConfiguration.getSingleArchPlatform()));
+ // Check if there's a swift library path already. If that's not the case - fall back to
+ // the default one. This is for backwards compatibility with Swift native rules.
+ // TODO(b/30281236): Remove when native Swift is deprecated.
+ boolean swiftLibDirSet = false;
+ for (String arg : objcProvider.get(ObjcProvider.LINKOPT)) {
+ if (arg.startsWith("-L") && arg.contains("usr/lib/swift")) {
+ swiftLibDirSet = true;
+ break;
+ }
+ }
+
+ if (!swiftLibDirSet) {
+ commandLine
+ .add("-L")
+ .add(AppleToolchain.swiftLibDir(appleConfiguration.getSingleArchPlatform()));
+ }
}
for (String linkopt : attributes.linkopts()) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
index 009b3fddfe..4cf8e6264f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
@@ -1058,13 +1058,21 @@ public final class ReleaseBundlingSupport {
return;
}
- CustomCommandLine.Builder commandLine =
- CustomCommandLine.builder()
- .addPath(intermediateArtifacts.swiftFrameworksFileZip().getExecPath())
- .add("Frameworks")
- .add("--platform")
- .add(platform.getLowerCaseNameInPlist())
- .addExecPath("--scan-executable", combinedArchBinary);
+ AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
+
+ CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
+ if (appleConfiguration.getXcodeToolchain() != null) {
+ commandLine.add("--toolchain").add(appleConfiguration.getXcodeToolchain());
+ }
+
+ commandLine
+ .add("--output_zip_path")
+ .addPath(intermediateArtifacts.swiftFrameworksFileZip().getExecPath())
+ .add("--bundle_path")
+ .add("Frameworks")
+ .add("--platform")
+ .add(platform.getLowerCaseNameInPlist())
+ .addExecPath("--scan-executable", combinedArchBinary);
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext, platform)
@@ -1082,13 +1090,21 @@ public final class ReleaseBundlingSupport {
return;
}
- CustomCommandLine.Builder commandLine =
- CustomCommandLine.builder()
- .addPath(intermediateArtifacts.swiftSupportZip().getExecPath())
- .add("SwiftSupport/" + platform.getLowerCaseNameInPlist())
- .add("--platform")
- .add(platform.getLowerCaseNameInPlist())
- .addExecPath("--scan-executable", combinedArchBinary);
+ AppleConfiguration configuration = ruleContext.getFragment(AppleConfiguration.class);
+
+ CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
+ if (configuration.getXcodeToolchain() != null) {
+ commandLine.add("--toolchain").add(configuration.getXcodeToolchain());
+ }
+
+ commandLine
+ .add("--output_zip_path")
+ .addPath(intermediateArtifacts.swiftSupportZip().getExecPath())
+ .add("--bundle_path")
+ .add("SwiftSupport/" + platform.getLowerCaseNameInPlist())
+ .add("--platform")
+ .add(platform.getLowerCaseNameInPlist())
+ .addExecPath("--scan-executable", combinedArchBinary);
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext, platform)
diff --git a/src/tools/xcode/swiftstdlibtoolwrapper/swiftstdlibtoolwrapper.sh b/src/tools/xcode/swiftstdlibtoolwrapper/swiftstdlibtoolwrapper.sh
index 7197cdc32e..d4f2f4fc60 100755
--- a/src/tools/xcode/swiftstdlibtoolwrapper/swiftstdlibtoolwrapper.sh
+++ b/src/tools/xcode/swiftstdlibtoolwrapper/swiftstdlibtoolwrapper.sh
@@ -17,7 +17,9 @@
# swiftstdlibtoolwrapper runs swift-stdlib-tool and zips up the output.
# This script only runs on darwin and you must have Xcode installed.
#
-# $1 OUTZIP - the path to place the output zip file.
+# --output_zip_path - the path to place the output zip file.
+# --bundle_path - the path inside of the archive to where libs will be copied.
+# --toolchain - toolchain identifier to use with xcrun.
set -eu
@@ -25,15 +27,50 @@ MY_LOCATION=${MY_LOCATION:-"$0.runfiles/bazel_tools/tools/objc"}
REALPATH="${MY_LOCATION}/realpath"
WRAPPER="${MY_LOCATION}/xcrunwrapper.sh"
-OUTZIP=$("${REALPATH}" "$1")
-PATH_INSIDE_ZIP="$2"
-shift 2
+TOOL_ARGS=()
+while [[ $# -gt 0 ]]; do
+ ARG="$1"
+ shift
+ case "${ARG}" in
+ --output_zip_path)
+ ARG="$1"
+ shift
+ OUTZIP=$("${REALPATH}" "${ARG}")
+ ;;
+ --bundle_path)
+ ARG="$1"
+ shift
+ PATH_INSIDE_ZIP="$ARG"
+ ;;
+ --toolchain)
+ ARG="$1"
+ shift
+ TOOLCHAIN=${ARG}
+ ;;
+ # Remaining args are swift-stdlib-tool args
+ *)
+ TOOL_ARGS+=("$ARG")
+ ;;
+ esac
+done
+
+
TEMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/swiftstdlibtoolZippingOutput.XXXXXX")
trap "rm -rf \"$TEMPDIR\"" EXIT
FULLPATH="$TEMPDIR/$PATH_INSIDE_ZIP"
-$WRAPPER swift-stdlib-tool --copy --verbose --destination "$FULLPATH" "$@"
+XCRUN_ARGS=()
+
+if [ -n "${TOOLCHAIN:-}" ]; then
+ XCRUN_ARGS+=(--toolchain "$TOOLCHAIN")
+fi
+
+XCRUN_ARGS+=(swift-stdlib-tool --copy --verbose )
+XCRUN_ARGS+=(--destination "$FULLPATH")
+XCRUN_ARGS+=( "${TOOL_ARGS[@]}" )
+
+$WRAPPER "${XCRUN_ARGS[@]}"
# Need to push/pop tempdir so it isn't the current working directory
# when we remove it via the EXIT trap.
diff --git a/tools/build_defs/apple/swift.bzl b/tools/build_defs/apple/swift.bzl
index 9b496688a7..3cc22fe44b 100644
--- a/tools/build_defs/apple/swift.bzl
+++ b/tools/build_defs/apple/swift.bzl
@@ -78,6 +78,39 @@ def _module_name(ctx):
"""Returns a module name for the given rule context."""
return ctx.label.package.lstrip("//").replace("/", "_") + "_" + ctx.label.name
+def _swift_lib_dir(ctx):
+ """Returns the location of swift runtime directory to link against."""
+ # TODO(dmishe): Expose this template from native code.
+ developer_dir = "__BAZEL_XCODE_DEVELOPER_DIR__"
+ platform_str = ctx.fragments.apple.single_arch_platform.name_in_plist.lower()
+
+ toolchain_name = "XcodeDefault"
+ if hasattr(ctx.fragments.apple, "xcode_toolchain"):
+ toolchain = ctx.fragments.apple.xcode_toolchain
+
+ # We cannot use non Xcode-packaged toolchains, and the only one non-default
+ # toolchain known to exist (as of Xcode 8.1) is this one.
+ # TODO(b/29338444): Write an integration test when Xcode 8 is available.
+ if toolchain == "com.apple.dt.toolchain.Swift_2_3":
+ toolchain_name = "Swift_2.3"
+
+ return "{0}/Toolchains/{1}.xctoolchain/usr/lib/swift/{2}".format(
+ developer_dir, toolchain_name, platform_str)
+
+def _swift_linkopts(ctx):
+ """Returns additional linker arguments for the given rule context."""
+ return set(["-L" + _swift_lib_dir(ctx)])
+
+def _swift_xcrun_args(ctx):
+ """Returns additional arguments that should be passed to xcrun."""
+ # TODO(dmishe): Remove this check when xcode_toolchain is available by default
+ args = []
+ if hasattr(ctx.fragments.apple, "xcode_toolchain"):
+ if ctx.fragments.apple.xcode_toolchain:
+ args += ["--toolchain", ctx.fragments.apple.xcode_toolchain]
+
+ return args
+
def _swift_library_impl(ctx):
"""Implementation for swift_library Skylark rule."""
# TODO(b/29772303): Assert xcode version.
@@ -202,7 +235,7 @@ def _swift_library_impl(ctx):
# https://llvm.org/bugs/show_bug.cgi?id=19501
+ ["-fmodule-map-file=%s" % x.path for x in objc_module_maps])
- args = [
+ args = _swift_xcrun_args(ctx) + [
"swiftc",
"-emit-object",
"-emit-module-path",
@@ -253,7 +286,8 @@ def _swift_library_impl(ctx):
library=set([output_lib] + dep_libs),
header=set([output_header]),
providers=objc_providers,
- uses_swift=True)
+ linkopt=_swift_linkopts(ctx),
+ uses_swift=True,)
return struct(
swift=struct(