Skip to content

Commit

Permalink
correctly propagate -target to swiftinterface clang deps
Browse files Browse the repository at this point in the history
Summary:
This change fixes the swiftinterface compilation to ensure that the transitive clang module deps of each swift module are compiled with the correct compiler target.

Summary of changes:
- remove `-target` from swiftinterface compilation, this will be picked from the swiftinterface file and is redundant
- add the target to `SdkUncompiledModuleInfo` so we can pass it down to clang deps
- don't pass `swift_cxx_flags` to swiftinterface compilation, these will be ignored anyway
- modify `get_swift_sdk_pcm_anon_targets` to collect transitive clang module deps from all SDK deps, not just Swift ones
- compile transitive clang deps of each swiftinterface using the correct target

Reviewed By: milend

Differential Revision: D48756624

fbshipit-source-id: 18b4210d4fc6ebc5e257bc90feb355587a0681fa
  • Loading branch information
rmaz authored and facebook-github-bot committed Aug 29, 2023
1 parent e11cfc7 commit e2ffd0a
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 41 deletions.
3 changes: 1 addition & 2 deletions prelude/apple/swift/apple_sdk_swift_module.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ def apple_sdk_swift_module_impl(ctx: AnalysisContext) -> list[Provider]:
"-suppress-warnings",
"-module-name",
module_name,
"-target",
ctx.attrs.target,
"-Xcc",
"-fno-implicit-modules",
"-Xcc",
Expand Down Expand Up @@ -61,6 +59,7 @@ def apple_sdk_swift_module_impl(ctx: AnalysisContext) -> list[Provider]:
partial_cmd = cmd,
input_relative_path = ctx.attrs.swiftinterface_relative_path,
deps = ctx.attrs.deps,
target = ctx.attrs.target,
transitive_clang_deps = ctx.actions.tset(SdkTransitiveDepsTset, children = clang_dep_children),
transitive_swift_deps = ctx.actions.tset(SdkTransitiveDepsTset, children = swift_dep_children),
)
Expand Down
1 change: 0 additions & 1 deletion prelude/apple/swift/swift_compilation.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ def get_swift_anonymous_targets(ctx: AnalysisContext, get_apple_library_provider
swift_interface_anon_targets = get_swift_interface_anon_targets(
ctx,
direct_uncompiled_sdk_deps,
swift_cxx_flags,
)
return ctx.actions.anon_targets(pcm_targets + sdk_pcm_targets + swift_interface_anon_targets).map(get_apple_library_providers)

Expand Down
1 change: 0 additions & 1 deletion prelude/apple/swift/swift_pcm_compilation.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ def _swift_pcm_compilation_impl(ctx: AnalysisContext) -> ["promise", list[Provid
swift_interface_anon_targets = get_swift_interface_anon_targets(
ctx,
direct_uncompiled_sdk_deps,
ctx.attrs.swift_cxx_args,
)

# Recursively compile PCMs of transitevely visible exported_deps
Expand Down
32 changes: 24 additions & 8 deletions prelude/apple/swift/swift_sdk_pcm_compilation.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
load("@prelude//apple:apple_toolchain_types.bzl", "AppleToolchainInfo")
load("@prelude//apple:apple_utility.bzl", "expand_relative_prefixed_sdk_path", "get_disable_pch_validation_flags")
load(":apple_sdk_modules_utility.bzl", "SDKDepTSet", "get_compiled_sdk_deps_tset")
load(":swift_toolchain_types.bzl", "SdkCompiledModuleInfo", "SdkUncompiledModuleInfo", "WrappedSdkCompiledModuleInfo")
load(":swift_toolchain_types.bzl", "SdkCompiledModuleInfo", "SdkTransitiveDepsTset", "SdkUncompiledModuleInfo", "WrappedSdkCompiledModuleInfo")

def get_shared_pcm_compilation_args(module_name: str) -> cmd_args:
cmd = cmd_args()
Expand Down Expand Up @@ -82,16 +82,32 @@ def get_swift_sdk_pcm_anon_targets(
ctx: AnalysisContext,
uncompiled_sdk_deps: list[Dependency],
swift_cxx_args: list[str]):
deps = [
{
"dep": uncompiled_sdk_dep,
# First collect the direct clang module deps.
clang_deps = [
d
for d in uncompiled_sdk_deps
if SdkUncompiledModuleInfo in d and not d[SdkUncompiledModuleInfo].is_swiftmodule
]

# We need to collect the transitive clang module deps across _all_
# SDK deps, as we need to pass through clang deps of Swift SDK deps.
# These cannot be propagated through the Swift SDK deps as those
# use different swift_cxx_args when compiling their clang deps.
transitive_clang_dep_tset = ctx.actions.tset(SdkTransitiveDepsTset, children = [
uncompiled_sdk_dep[SdkUncompiledModuleInfo].transitive_clang_deps
for uncompiled_sdk_dep in uncompiled_sdk_deps
if SdkUncompiledModuleInfo in uncompiled_sdk_dep
])
clang_deps += list(transitive_clang_dep_tset.traverse())

return [
(_swift_sdk_pcm_compilation, {
"dep": clang_module_dep,
"swift_cxx_args": swift_cxx_args,
"_apple_toolchain": ctx.attrs._apple_toolchain,
}
for uncompiled_sdk_dep in uncompiled_sdk_deps
if SdkUncompiledModuleInfo in uncompiled_sdk_dep and not uncompiled_sdk_dep[SdkUncompiledModuleInfo].is_swiftmodule
})
for clang_module_dep in clang_deps
]
return [(_swift_sdk_pcm_compilation, d) for d in deps]

def _swift_sdk_pcm_compilation_impl(ctx: AnalysisContext) -> ["promise", list[Provider]]:
def k(sdk_pcm_deps_providers) -> list[Provider]:
Expand Down
59 changes: 30 additions & 29 deletions prelude/apple/swift/swift_sdk_swiftinterface_compilation.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,17 @@
load("@prelude//apple:apple_toolchain_types.bzl", "AppleToolchainInfo")
load("@prelude//apple:apple_utility.bzl", "expand_relative_prefixed_sdk_path", "get_explicit_modules_env_var")
load("@prelude//apple/swift:swift_types.bzl", "SWIFTMODULE_EXTENSION")
load(":apple_sdk_modules_utility.bzl", "SDKDepTSet", "get_compiled_sdk_deps_tset")
load(":apple_sdk_modules_utility.bzl", "SDKDepTSet")
load(":swift_module_map.bzl", "write_swift_module_map")
load(":swift_sdk_pcm_compilation.bzl", "get_swift_sdk_pcm_anon_targets")
load(":swift_toolchain_types.bzl", "SdkCompiledModuleInfo", "SdkUncompiledModuleInfo", "WrappedSdkCompiledModuleInfo")

def get_swift_interface_anon_targets(
ctx: AnalysisContext,
uncompiled_sdk_deps: list[Dependency],
swift_cxx_args: list[str]):
uncompiled_sdk_deps: list[Dependency]):
deps = [
{
"dep": uncompiled_sdk_dep,
"sdk_swiftinterface_name": uncompiled_sdk_dep[SdkUncompiledModuleInfo].module_name,
"swift_cxx_args": swift_cxx_args,
"_apple_toolchain": ctx.attrs._apple_toolchain,
}
for uncompiled_sdk_dep in uncompiled_sdk_deps
Expand All @@ -33,7 +30,6 @@ def _swift_interface_compilation_impl(ctx: AnalysisContext) -> ["promise", list[
def k(sdk_deps_providers) -> list[Provider]:
uncompiled_sdk_module_info = ctx.attrs.dep[SdkUncompiledModuleInfo]
uncompiled_module_info_name = uncompiled_sdk_module_info.module_name

apple_toolchain = ctx.attrs._apple_toolchain[AppleToolchainInfo]
swift_toolchain = apple_toolchain.swift_toolchain_info
cmd = cmd_args(swift_toolchain.compiler)
Expand All @@ -46,20 +42,30 @@ def _swift_interface_compilation_impl(ctx: AnalysisContext) -> ["promise", list[
swift_toolchain.resource_dir,
])

# `sdk_deps_providers` contains providers of direct SDK deps,
# as well as a provider that aggregates SDK deps coming from all transitive pcm deps.
sdk_deps_tset = get_compiled_sdk_deps_tset(ctx, sdk_deps_providers)
# `sdk_deps_providers` contains providers of clang and swift SDK deps.
# Keep them separated as we need to only pass up the swiftmodule deps.
clang_dep_children = []
swift_dep_children = []
for sdk_dep in sdk_deps_providers:
tset = sdk_dep[WrappedSdkCompiledModuleInfo].tset
if tset.value.is_swiftmodule:
swift_dep_children.append(tset)
else:
clang_dep_children.append(tset)

clang_deps_tset = ctx.actions.tset(SDKDepTSet, children = clang_dep_children)
swift_deps_tset = ctx.actions.tset(SDKDepTSet, children = swift_dep_children)

# FIXME: - Get rid of slow traversal here, and unify with two projections below.
swift_module_map_artifact = write_swift_module_map(ctx, uncompiled_module_info_name, list(sdk_deps_tset.traverse()))
swift_module_map_artifact = write_swift_module_map(ctx, uncompiled_module_info_name, list(swift_deps_tset.traverse()))
cmd.add([
"-explicit-swift-module-map-file",
swift_module_map_artifact,
])

# sdk_swiftinterface_compile should explicitly depend on its deps that go to swift_modulemap
cmd.hidden(sdk_deps_tset.project_as_args("hidden"))
cmd.add(sdk_deps_tset.project_as_args("clang_deps"))
cmd.hidden(swift_deps_tset.project_as_args("hidden"))
cmd.add(clang_deps_tset.project_as_args("clang_deps"))

swiftmodule_output = ctx.actions.declare_output(uncompiled_module_info_name + SWIFTMODULE_EXTENSION)
expanded_swiftinterface_cmd = expand_relative_prefixed_sdk_path(
Expand Down Expand Up @@ -93,35 +99,30 @@ def _swift_interface_compilation_impl(ctx: AnalysisContext) -> ["promise", list[
return [
DefaultInfo(),
WrappedSdkCompiledModuleInfo(
tset = ctx.actions.tset(SDKDepTSet, value = compiled_sdk, children = [sdk_deps_tset]),
tset = ctx.actions.tset(SDKDepTSet, value = compiled_sdk, children = swift_dep_children),
),
]

# Skip deps compilations if run not on SdkUncompiledModuleInfo
if SdkUncompiledModuleInfo not in ctx.attrs.dep:
return []

sdk_pcm_deps_anon_targets = get_swift_sdk_pcm_anon_targets(
# For each swiftinterface compile its transitive clang deps with the provided target.
module_info = ctx.attrs.dep[SdkUncompiledModuleInfo]
clang_module_deps = get_swift_sdk_pcm_anon_targets(
ctx,
ctx.attrs.dep[SdkUncompiledModuleInfo].deps,
ctx.attrs.swift_cxx_args,
module_info.deps,
["-target", module_info.target],
)

# Recursively compile swiftinterface of any other exported_deps
sdk_swift_interface_anon_targets = get_swift_interface_anon_targets(
ctx,
ctx.attrs.dep[SdkUncompiledModuleInfo].deps,
ctx.attrs.swift_cxx_args,
)
# Compile the transitive swiftmodule deps.
swift_module_deps = [(_swift_interface_compilation, {
"dep": d,
"_apple_toolchain": ctx.attrs._apple_toolchain,
}) for d in module_info.transitive_swift_deps.traverse()]

return ctx.actions.anon_targets(sdk_pcm_deps_anon_targets + sdk_swift_interface_anon_targets).map(k)
return ctx.actions.anon_targets(clang_module_deps + swift_module_deps).map(k)

_swift_interface_compilation = rule(
impl = _swift_interface_compilation_impl,
attrs = {
"dep": attrs.dep(),
"sdk_swiftinterface_name": attrs.string(),
"swift_cxx_args": attrs.list(attrs.string(), default = []),
"_apple_toolchain": attrs.dep(),
},
)
1 change: 1 addition & 0 deletions prelude/apple/swift/swift_toolchain_types.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ SdkUncompiledModuleInfo = provider(fields = [
"partial_cmd", # Partial arguments, required to compile a particular SDK module.
"input_relative_path", # A relative prefixed path to a textual swiftinterface/modulemap file within an SDK.
"deps", # [Dependency]
"target", # A string of the compiler target triple to use for clang module deps, eg arm64-apple-ios16.4
"transitive_clang_deps", # A SdkTransitiveDepsTset of all transitive SDK clang modules.
"transitive_swift_deps", # A SdkTransitiveDepsTset of all transitive SDK swift modules.
])
Expand Down

0 comments on commit e2ffd0a

Please sign in to comment.