Skip to content

Commit 92baa13

Browse files
committed
Swift support
1 parent c6cd079 commit 92baa13

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

refresh.template.py

+33-7
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,11 @@ def _get_files(compile_action):
557557
# First, we do the obvious thing: Filter args to those that look like source files.
558558
source_file_candidates = [arg for arg in compile_action.arguments if not arg.startswith('-') and arg.endswith(_get_files.source_extensions)]
559559
assert source_file_candidates, f"No source files found in compile args: {compile_action.arguments}.\nPlease file an issue with this information!"
560+
561+
# If we've got swift action just return sources
562+
if all(candidate.endswith(_get_files.swift_source_extensions) for candidate in source_file_candidates):
563+
return set(source_file_candidates), set()
564+
560565
source_file = source_file_candidates[0]
561566

562567
# If we've got multiple candidates for source files, apply heuristics based on how Bazel tends to format commands.
@@ -639,7 +644,8 @@ def _get_files(compile_action):
639644
_get_files.openclxx_source_extensions = ('.clcpp',)
640645
_get_files.assembly_source_extensions = ('.s', '.asm')
641646
_get_files.assembly_needing_c_preprocessor_source_extensions = ('.S',)
642-
_get_files.source_extensions = _get_files.c_source_extensions + _get_files.cpp_source_extensions + _get_files.objc_source_extensions + _get_files.objcpp_source_extensions + _get_files.cuda_source_extensions + _get_files.opencl_source_extensions + _get_files.openclxx_source_extensions + _get_files.assembly_source_extensions + _get_files.assembly_needing_c_preprocessor_source_extensions
647+
_get_files.swift_source_extensions = ('.swift',)
648+
_get_files.source_extensions = _get_files.c_source_extensions + _get_files.cpp_source_extensions + _get_files.objc_source_extensions + _get_files.objcpp_source_extensions + _get_files.cuda_source_extensions + _get_files.opencl_source_extensions + _get_files.openclxx_source_extensions + _get_files.assembly_source_extensions + _get_files.assembly_needing_c_preprocessor_source_extensions + _get_files.swift_source_extensions
643649
_get_files.extensions_to_language_args = { # Note that clangd fails on the --language or -ObjC or -ObjC++ forms. See https://github.com/clangd/clangd/issues/1173#issuecomment-1226847416
644650
_get_files.c_source_extensions: '-xc',
645651
_get_files.cpp_source_extensions: '-xc++',
@@ -672,7 +678,7 @@ def _get_apple_SDKROOT(SDK_name: str):
672678
# Traditionally stored in SDKROOT environment variable, but not provided by Bazel. See https://github.com/bazelbuild/bazel/issues/12852
673679

674680

675-
def _get_apple_platform(compile_args: typing.List[str]):
681+
def _get_apple_platform(compile_args: typing.List[str], environmentVariables = None):
676682
"""Figure out which Apple platform a command is for.
677683
678684
Is the name used by Xcode in the SDK files, not the marketing name.
@@ -683,6 +689,13 @@ def _get_apple_platform(compile_args: typing.List[str]):
683689
match = re.search('/Platforms/([a-zA-Z]+).platform/Developer/', arg)
684690
if match:
685691
return match.group(1)
692+
if environmentVariables:
693+
match = next(
694+
filter(lambda x: x.key == "APPLE_SDK_PLATFORM", environmentVariables),
695+
None
696+
)
697+
if match:
698+
return match.value
686699
return None
687700

688701

@@ -694,7 +707,7 @@ def _get_apple_DEVELOPER_DIR():
694707
# Traditionally stored in DEVELOPER_DIR environment variable, but not provided by Bazel. See https://github.com/bazelbuild/bazel/issues/12852
695708

696709

697-
def _apple_platform_patch(compile_args: typing.List[str]):
710+
def _apple_platform_patch(compile_args: typing.List[str], environmentVariables = None):
698711
"""De-Bazel the command into something clangd can parse.
699712
700713
This function has fixes specific to Apple platforms, but you should call it on all platforms. It'll determine whether the fixes should be applied or not.
@@ -705,16 +718,29 @@ def _apple_platform_patch(compile_args: typing.List[str]):
705718
# Undo Bazel's Apple platform compiler wrapping.
706719
# Bazel wraps the compiler as `external/local_config_cc/wrapped_clang` and exports that wrapped compiler in the proto. However, we need a clang call that clangd can introspect. (See notes in "how clangd uses compile_commands.json" in ImplementationReadme.md for more.)
707720
# Removing the wrapper is also important because Bazel's Xcode (but not CommandLineTools) wrapper crashes if you don't specify particular environment variables (replaced below). We'd need the wrapper to be invokable by clangd's --query-driver if we didn't remove the wrapper.
708-
compile_args[0] = 'clang'
721+
722+
# rules_swift add a worker for wrapping if enable --persistent_worker flag (https://bazel.build/remote/persistent)
723+
# https://github.com/bazelbuild/rules_swift/blob/master/swift/internal/actions.bzl#L236
724+
# We need to remove it (build_bazel_rules_swift/tools/worker/worker)
725+
while len(compile_args) > 0 and (not compile_args[0].endswith('clang')) and (not compile_args[0].endswith('swiftc')):
726+
compile_args.pop(0)
727+
728+
assert len(compile_args), "Compiler not found in CMD"
729+
if compile_args[0].endswith('swiftc'):
730+
compile_args[0] = 'swiftc'
731+
else:
732+
compile_args[0] = 'clang'
709733

710734
# We have to manually substitute out Bazel's macros so clang can parse the command
711735
# Code this mirrors is in https://github.com/bazelbuild/bazel/blob/master/tools/osx/crosstool/wrapped_clang.cc
712736
# Not complete--we're just swapping out the essentials, because there seems to be considerable turnover in the hacks they have in the wrapper.
713737
compile_args = [arg for arg in compile_args if not arg.startswith('DEBUG_PREFIX_MAP_PWD') or arg == 'OSO_PREFIX_MAP_PWD'] # No need for debug prefix maps if compiling in place, not that we're compiling anyway.
738+
# Remove -Xwrapped-swift introduced by rules_swift
739+
compile_args = [arg for arg in compile_args if not arg.startswith('-Xwrapped-swift')]
714740
# We also have to manually figure out the values of SDKROOT and DEVELOPER_DIR, since they're missing from the environment variables Bazel provides.
715741
# Filed Bazel issue about the missing environment variables: https://github.com/bazelbuild/bazel/issues/12852
716742
compile_args = [arg.replace('__BAZEL_XCODE_DEVELOPER_DIR__', _get_apple_DEVELOPER_DIR()) for arg in compile_args]
717-
apple_platform = _get_apple_platform(compile_args)
743+
apple_platform = _get_apple_platform(compile_args, environmentVariables)
718744
assert apple_platform, f"Apple platform not detected in CMD: {compile_args}"
719745
compile_args = [arg.replace('__BAZEL_XCODE_SDKROOT__', _get_apple_SDKROOT(apple_platform)) for arg in compile_args]
720746

@@ -764,7 +790,7 @@ def _get_cpp_command_for_files(compile_action):
764790
"""
765791
# Patch command by platform
766792
compile_action.arguments = _all_platform_patch(compile_action.arguments)
767-
compile_action.arguments = _apple_platform_patch(compile_action.arguments)
793+
compile_action.arguments = _apple_platform_patch(compile_action.arguments, getattr(compile_action, 'environmentVariables', None))
768794
# Android and Linux and grailbio LLVM toolchains: Fine as is; no special patching needed.
769795

770796
source_files, header_files = _get_files(compile_action)
@@ -861,7 +887,7 @@ def _get_commands(target: str, flags: str):
861887
# Aquery docs if you need em: https://docs.bazel.build/versions/master/aquery.html
862888
# Aquery output proto reference: https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/analysis_v2.proto
863889
# One bummer, not described in the docs, is that aquery filters over *all* actions for a given target, rather than just those that would be run by a build to produce a given output. This mostly isn't a problem, but can sometimes surface extra, unnecessary, misconfigured actions. Chris has emailed the authors to discuss and filed an issue so anyone reading this could track it: https://github.com/bazelbuild/bazel/issues/14156.
864-
f"mnemonic('(Objc|Cpp)Compile',deps({target}))",
890+
f"mnemonic('(Objc|Cpp|Swift)Compile',deps({target}))",
865891
# We switched to jsonproto instead of proto because of https://github.com/bazelbuild/bazel/issues/13404. We could change back when fixed--reverting most of the commit that added this line and tweaking the build file to depend on the target in that issue. That said, it's kinda nice to be free of the dependency, unless (OPTIMNOTE) jsonproto becomes a performance bottleneck compated to binary protos.
866892
'--output=jsonproto',
867893
# We'll disable artifact output for efficiency, since it's large and we don't use them. Small win timewise, but dramatically less json output from aquery.

0 commit comments

Comments
 (0)