@@ -117,45 +117,59 @@ def _command_line_objc_copts(compilation_mode, objc_fragment):
117117 clang_copts = objc_fragment .copts + legacy_copts
118118 return [copt for copt in clang_copts if copt != "-g" ]
119119
120- def _platform_developer_framework_dir (apple_toolchain , apple_fragment ):
120+ def _platform_developer_framework_dir (
121+ apple_toolchain ,
122+ apple_fragment ,
123+ xcode_config ):
121124 """Returns the Developer framework directory for the platform.
122125
123126 Args:
124127 apple_fragment: The `apple` configuration fragment.
125128 apple_toolchain: The `apple_common.apple_toolchain()` object.
129+ xcode_config: The Xcode configuration.
126130
127131 Returns:
128132 The path to the Developer framework directory for the platform if one
129133 exists, otherwise `None`.
130134 """
135+
136+ # All platforms have a `Developer/Library/Frameworks` directory in their
137+ # platform root, except for watchOS prior to Xcode 12.5.
131138 platform_type = apple_fragment .single_arch_platform .platform_type
132- if platform_type == apple_common .platform_type .watchos :
139+ if (
140+ platform_type == apple_common .platform_type .watchos and
141+ not _is_xcode_at_least_version (xcode_config , "12.5" )
142+ ):
133143 return None
134144
135- # All platforms except watchOS have a `Developer/Library/Frameworks`
136- # directory in their platform root.
137145 return apple_toolchain .platform_developer_framework_dir (apple_fragment )
138146
139- def _sdk_developer_framework_dir (apple_toolchain , apple_fragment ):
147+ def _sdk_developer_framework_dir (apple_toolchain , apple_fragment , xcode_config ):
140148 """Returns the Developer framework directory for the SDK.
141149
142150 Args:
143151 apple_fragment: The `apple` configuration fragment.
144152 apple_toolchain: The `apple_common.apple_toolchain()` object.
153+ xcode_config: The Xcode configuration.
145154
146155 Returns:
147156 The path to the Developer framework directory for the SDK if one
148157 exists, otherwise `None`.
149158 """
159+
160+ # All platforms have a `Developer/Library/Frameworks` directory in their SDK
161+ # root except for macOS (all versions of Xcode so far), and watchOS (prior
162+ # to Xcode 12.5).
150163 platform_type = apple_fragment .single_arch_platform .platform_type
151- if platform_type in (
152- apple_common .platform_type .macos ,
153- apple_common .platform_type .watchos ,
164+ if (
165+ platform_type == apple_common .platform_type .macos or
166+ (
167+ platform_type == apple_common .platform_type .watchos and
168+ not _is_xcode_at_least_version (xcode_config , "12.5" )
169+ )
154170 ):
155171 return None
156172
157- # All platforms except macOS and watchOS have a
158- # `Developer/Library/Frameworks` directory in their SDK root.
159173 return paths .join (apple_toolchain .sdk_dir (), "Developer/Library/Frameworks" )
160174
161175def _default_linker_opts (
@@ -189,76 +203,37 @@ def _default_linker_opts(
189203 platform_developer_framework_dir = _platform_developer_framework_dir (
190204 apple_toolchain ,
191205 apple_fragment ,
206+ xcode_config ,
192207 )
193208 sdk_developer_framework_dir = _sdk_developer_framework_dir (
194209 apple_toolchain ,
195210 apple_fragment ,
211+ xcode_config ,
196212 )
197- linkopts = []
198-
199- uses_runtime_in_os = _is_xcode_at_least_version (xcode_config , "10.2" )
200- if uses_runtime_in_os :
201- # Starting with Xcode 10.2, Apple forbids statically linking to the
202- # Swift runtime. The libraries are distributed with the OS and located
203- # in /usr/lib/swift.
204- swift_subdir = "swift"
205- linkopts .append ("-Wl,-rpath,/usr/lib/swift" )
206- elif is_static :
207- # This branch and the branch below now only support Xcode 10.1 and
208- # below. Eventually, once we drop support for those versions, they can
209- # be deleted.
210- swift_subdir = "swift_static"
211- linkopts .extend ([
212- "-Wl,-force_load_swift_libs" ,
213- "-framework" ,
214- "Foundation" ,
215- "-lstdc++" ,
216- ])
217- else :
218- swift_subdir = "swift"
219-
220- swift_lib_dir = (
221- "{developer_dir}/Toolchains/{toolchain}.xctoolchain/" +
222- "usr/lib/{swift_subdir}/{platform}"
223- ).format (
224- developer_dir = apple_toolchain .developer_dir (),
225- platform = platform .name_in_plist .lower (),
226- swift_subdir = swift_subdir ,
227- toolchain = "XcodeDefault" ,
228- )
229-
230- # TODO(b/128303533): It's possible to run Xcode 10.2 on a version of macOS
231- # 10.14.x that does not yet include `/usr/lib/swift`. Later Xcode 10.2 betas
232- # have deleted the `swift_static` directory, so we must manually add the
233- # dylibs to the binary's rpath or those binaries won't be able to run at
234- # all. This is added after `/usr/lib/swift` above so the system versions
235- # will always be preferred if they are present. This workaround can be
236- # removed once Xcode 10.2 and macOS 10.14.4 are out of beta.
237- if uses_runtime_in_os and platform == apple_common .platform .macos :
238- linkopts .append ("-Wl,-rpath,{}" .format (swift_lib_dir ))
239-
240- linkopts .extend (
241- [
242- "-F{}" .format (path )
243- for path in compact ([
244- platform_developer_framework_dir ,
245- sdk_developer_framework_dir ,
246- ])
247- ] + [
248- "-L{}" .format (swift_lib_dir ),
249- # TODO(b/112000244): These should get added by the C++ Starlark API,
250- # but we're using the "c++-link-executable" action right now instead
251- # of "objc-executable" because the latter requires additional
252- # variables not provided by cc_common. Figure out how to handle this
253- # correctly.
254- "-ObjC" ,
255- "-Wl,-objc_abi_version,2" ,
256- ],
213+ swift_lib_dir = paths .join (
214+ apple_toolchain .developer_dir (),
215+ "Toolchains/XcodeDefault.xctoolchain/usr/lib/swift" ,
216+ platform .name_in_plist .lower (),
257217 )
258218
259- use_system_swift_libs = _is_xcode_at_least_version (xcode_config , "11.0" )
260- if use_system_swift_libs :
261- linkopts .append ("-L/usr/lib/swift" )
219+ linkopts = [
220+ "-F{}" .format (path )
221+ for path in compact ([
222+ platform_developer_framework_dir ,
223+ sdk_developer_framework_dir ,
224+ ])
225+ ] + [
226+ "-Wl,-rpath,/usr/lib/swift" ,
227+ "-L{}" .format (swift_lib_dir ),
228+ "-L/usr/lib/swift" ,
229+ # TODO(b/112000244): These should get added by the C++ Starlark API,
230+ # but we're using the "c++-link-executable" action right now instead
231+ # of "objc-executable" because the latter requires additional
232+ # variables not provided by cc_common. Figure out how to handle this
233+ # correctly.
234+ "-ObjC" ,
235+ "-Wl,-objc_abi_version,2" ,
236+ ]
262237
263238 # Frameworks in the platform's developer frameworks directory (like XCTest,
264239 # but also StoreKitTest on macOS) contain the actual binary for that
@@ -331,7 +306,8 @@ def _all_action_configs(
331306 apple_toolchain ,
332307 generated_header_rewriter ,
333308 needs_resource_directory ,
334- target_triple ):
309+ target_triple ,
310+ xcode_config ):
335311 """Returns the action configurations for the Swift toolchain.
336312
337313 Args:
@@ -348,17 +324,20 @@ def _all_action_configs(
348324 needs_resource_directory: If True, the toolchain needs the resource
349325 directory passed explicitly to the compiler.
350326 target_triple: The target triple.
327+ xcode_config: The Xcode configuration.
351328
352329 Returns:
353330 The action configurations for the Swift toolchain.
354331 """
355332 platform_developer_framework_dir = _platform_developer_framework_dir (
356333 apple_toolchain ,
357334 apple_fragment ,
335+ xcode_config ,
358336 )
359337 sdk_developer_framework_dir = _sdk_developer_framework_dir (
360338 apple_toolchain ,
361339 apple_fragment ,
340+ xcode_config ,
362341 )
363342 developer_framework_dirs = compact ([
364343 platform_developer_framework_dir ,
@@ -472,7 +451,6 @@ def _all_tool_configs(
472451 generated_header_rewriter ,
473452 swift_executable ,
474453 toolchain_root ,
475- use_param_file ,
476454 xcode_config ):
477455 """Returns the tool configurations for the Swift toolchain.
478456
@@ -487,8 +465,6 @@ def _all_tool_configs(
487465 swift_executable: A custom Swift driver executable to be used during the
488466 build, if provided.
489467 toolchain_root: The root directory of the toolchain, if provided.
490- use_param_file: If True, actions should have their arguments written to
491- param files.
492468 xcode_config: The `apple_common.XcodeVersionConfig` provider.
493469
494470 Returns:
@@ -514,7 +490,7 @@ def _all_tool_configs(
514490 execution_requirements = execution_requirements ,
515491 swift_executable = swift_executable ,
516492 toolchain_root = toolchain_root ,
517- use_param_file = use_param_file ,
493+ use_param_file = True ,
518494 worker_mode = "persistent" ,
519495 ),
520496 }
@@ -528,25 +504,13 @@ def _all_tool_configs(
528504 execution_requirements = execution_requirements ,
529505 swift_executable = swift_executable ,
530506 toolchain_root = toolchain_root ,
531- use_param_file = use_param_file ,
507+ use_param_file = True ,
532508 worker_mode = "wrap" ,
533509 )
534510 )
535511
536512 return tool_configs
537513
538- def _is_macos (platform ):
539- """Returns `True` if the given platform is macOS.
540-
541- Args:
542- platform: An `apple_platform` value describing the platform for which a
543- target is being built.
544-
545- Returns:
546- `True` if the given platform is macOS.
547- """
548- return platform .platform_type == apple_common .platform_type .macos
549-
550514def _is_xcode_at_least_version (xcode_config , desired_version ):
551515 """Returns True if we are building with at least the given Xcode version.
552516
@@ -661,31 +625,20 @@ def _xcode_swift_toolchain_impl(ctx):
661625 cpp_fragment = ctx .fragments .cpp ,
662626 ) + features_from_swiftcopts (swiftcopts = ctx .fragments .swift .copts ())
663627 requested_features .extend (ctx .features )
664- requested_features .append (SWIFT_FEATURE_BUNDLED_XCTESTS )
665628 requested_features .extend (
666629 _features_for_bitcode_mode (apple_fragment .bitcode_mode ),
667630 )
668-
669- # TODO(b/142867898): Added to match existing Bazel Objective-C module map
670- # behavior; remove it when possible.
671- requested_features .append (SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS )
672-
673- # Xcode 10.0 implies Swift 4.2.
674- if _is_xcode_at_least_version (xcode_config , "10.0" ):
675- use_param_file = True
676- requested_features .append (SWIFT_FEATURE_ENABLE_BATCH_MODE )
677- requested_features .append (SWIFT_FEATURE_USE_RESPONSE_FILES )
678- else :
679- use_param_file = False
680-
681- # Xcode 10.2 implies Swift 5.0.
682- if _is_xcode_at_least_version (xcode_config , "10.2" ):
683- requested_features .append (SWIFT_FEATURE_DEBUG_PREFIX_MAP )
684-
685- # Xcode 11.0 implies Swift 5.1.
686- if _is_xcode_at_least_version (xcode_config , "11.0" ):
687- requested_features .append (SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION )
688- requested_features .append (SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS )
631+ requested_features .extend ([
632+ SWIFT_FEATURE_BUNDLED_XCTESTS ,
633+ SWIFT_FEATURE_ENABLE_BATCH_MODE ,
634+ SWIFT_FEATURE_USE_RESPONSE_FILES ,
635+ SWIFT_FEATURE_DEBUG_PREFIX_MAP ,
636+ SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION ,
637+ SWIFT_FEATURE_SUPPORTS_PRIVATE_DEPS ,
638+ # TODO(b/142867898): Added to match existing Bazel Objective-C module
639+ # map behavior; remove it when possible.
640+ SWIFT_FEATURE_MODULE_MAP_NO_PRIVATE_HEADERS ,
641+ ])
689642
690643 # Xcode 12.5 implies Swift 5.4.
691644 if _is_xcode_at_least_version (xcode_config , "12.5" ):
@@ -702,7 +655,6 @@ def _xcode_swift_toolchain_impl(ctx):
702655 generated_header_rewriter = generated_header_rewriter ,
703656 swift_executable = swift_executable ,
704657 toolchain_root = toolchain_root ,
705- use_param_file = use_param_file ,
706658 xcode_config = xcode_config ,
707659 )
708660 all_action_configs = _all_action_configs (
@@ -716,6 +668,7 @@ def _xcode_swift_toolchain_impl(ctx):
716668 generated_header_rewriter = generated_header_rewriter ,
717669 needs_resource_directory = swift_executable or toolchain_root ,
718670 target_triple = target ,
671+ xcode_config = xcode_config ,
719672 )
720673
721674 # Xcode toolchains don't pass any files explicitly here because they're
0 commit comments