Skip to content

Commit

Permalink
Conditionally add developer framework paths (#868)
Browse files Browse the repository at this point in the history
Condtionally adds developer framework paths to
compile and linking actions. These developer paths
should only be enabled for targets that have
`testonly = True`. Currently they are added for
all targets by default.
  • Loading branch information
maxwellE authored Aug 3, 2022
1 parent 088096a commit d39d966
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 108 deletions.
6 changes: 4 additions & 2 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ A new attribute dictionary that can be added to the attributes of a

<pre>
swift_common.compile(<a href="#swift_common.compile-actions">actions</a>, <a href="#swift_common.compile-additional_inputs">additional_inputs</a>, <a href="#swift_common.compile-copts">copts</a>, <a href="#swift_common.compile-defines">defines</a>, <a href="#swift_common.compile-deps">deps</a>, <a href="#swift_common.compile-feature_configuration">feature_configuration</a>,
<a href="#swift_common.compile-generated_header_name">generated_header_name</a>, <a href="#swift_common.compile-module_name">module_name</a>, <a href="#swift_common.compile-private_deps">private_deps</a>, <a href="#swift_common.compile-srcs">srcs</a>, <a href="#swift_common.compile-swift_toolchain">swift_toolchain</a>,
<a href="#swift_common.compile-generated_header_name">generated_header_name</a>, <a href="#swift_common.compile-is_test">is_test</a>, <a href="#swift_common.compile-module_name">module_name</a>, <a href="#swift_common.compile-private_deps">private_deps</a>, <a href="#swift_common.compile-srcs">srcs</a>, <a href="#swift_common.compile-swift_toolchain">swift_toolchain</a>,
<a href="#swift_common.compile-target_name">target_name</a>, <a href="#swift_common.compile-workspace_name">workspace_name</a>)
</pre>

Expand All @@ -102,6 +102,7 @@ Compiles a Swift module.
| <a id="swift_common.compile-deps"></a>deps | Non-private dependencies of the target being compiled. These targets are used as dependencies of both the Swift module being compiled and the Clang module for the generated header. These targets must propagate one of the following providers: <code>CcInfo</code>, <code>SwiftInfo</code>, or <code>apple_common.Objc</code>. | <code>[]</code> |
| <a id="swift_common.compile-feature_configuration"></a>feature_configuration | A feature configuration obtained from <code>swift_common.configure_features</code>. | none |
| <a id="swift_common.compile-generated_header_name"></a>generated_header_name | The name of the Objective-C generated header that should be generated for this module. If omitted, no header will be generated. | <code>None</code> |
| <a id="swift_common.compile-is_test"></a>is_test | Represents if the <code>testonly</code> value of the context. | none |
| <a id="swift_common.compile-module_name"></a>module_name | The name of the Swift module being compiled. This must be present and valid; use <code>swift_common.derive_module_name</code> to generate a default from the target's label if needed. | none |
| <a id="swift_common.compile-private_deps"></a>private_deps | Private (implementation-only) dependencies of the target being compiled. These are only used as dependencies of the Swift module, not of the Clang module for the generated header. These targets must propagate one of the following providers: <code>CcInfo</code>, <code>SwiftInfo</code>, or <code>apple_common.Objc</code>. | <code>[]</code> |
| <a id="swift_common.compile-srcs"></a>srcs | The Swift source files to compile. | none |
Expand Down Expand Up @@ -248,7 +249,7 @@ A `struct` containing four fields:
<pre>
swift_common.create_linking_context_from_compilation_outputs(<a href="#swift_common.create_linking_context_from_compilation_outputs-actions">actions</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-additional_inputs">additional_inputs</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-alwayslink">alwayslink</a>,
<a href="#swift_common.create_linking_context_from_compilation_outputs-compilation_outputs">compilation_outputs</a>,
<a href="#swift_common.create_linking_context_from_compilation_outputs-feature_configuration">feature_configuration</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-label">label</a>,
<a href="#swift_common.create_linking_context_from_compilation_outputs-feature_configuration">feature_configuration</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-is_test">is_test</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-label">label</a>,
<a href="#swift_common.create_linking_context_from_compilation_outputs-linking_contexts">linking_contexts</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-module_context">module_context</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-name">name</a>,
<a href="#swift_common.create_linking_context_from_compilation_outputs-swift_toolchain">swift_toolchain</a>, <a href="#swift_common.create_linking_context_from_compilation_outputs-user_link_flags">user_link_flags</a>)
</pre>
Expand All @@ -273,6 +274,7 @@ command line parameters file, those actions will be created here.
| <a id="swift_common.create_linking_context_from_compilation_outputs-alwayslink"></a>alwayslink | If True, any binary that depends on the providers returned by this function will link in all of the library's object files, even if some contain no symbols referenced by the binary. | <code>False</code> |
| <a id="swift_common.create_linking_context_from_compilation_outputs-compilation_outputs"></a>compilation_outputs | A <code>CcCompilationOutputs</code> value containing the object files to link. Typically, this is the second tuple element in the value returned by <code>swift_common.compile</code>. | none |
| <a id="swift_common.create_linking_context_from_compilation_outputs-feature_configuration"></a>feature_configuration | A feature configuration obtained from <code>swift_common.configure_features</code>. | none |
| <a id="swift_common.create_linking_context_from_compilation_outputs-is_test"></a>is_test | Represents if the <code>testonly</code> value of the context. | none |
| <a id="swift_common.create_linking_context_from_compilation_outputs-label"></a>label | The <code>Label</code> of the target being built. This is used as the owner of the linker inputs created for post-compile actions (if any), and the label's name component also determines the name of the artifact unless it is overridden by the <code>name</code> argument. | none |
| <a id="swift_common.create_linking_context_from_compilation_outputs-linking_contexts"></a>linking_contexts | A <code>list</code> of <code>CcLinkingContext</code>s containing libraries from dependencies. | <code>[]</code> |
| <a id="swift_common.create_linking_context_from_compilation_outputs-module_context"></a>module_context | The module context returned by <code>swift_common.compile</code> containing information about the Swift module that was compiled. Typically, this is the first tuple element in the value returned by <code>swift_common.compile</code>. | none |
Expand Down
3 changes: 2 additions & 1 deletion doc/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Propagates Swift-specific information about a `proto_library`.
## SwiftToolchainInfo

<pre>
SwiftToolchainInfo(<a href="#SwiftToolchainInfo-action_configs">action_configs</a>, <a href="#SwiftToolchainInfo-cc_toolchain_info">cc_toolchain_info</a>, <a href="#SwiftToolchainInfo-clang_implicit_deps_providers">clang_implicit_deps_providers</a>,
SwiftToolchainInfo(<a href="#SwiftToolchainInfo-action_configs">action_configs</a>, <a href="#SwiftToolchainInfo-cc_toolchain_info">cc_toolchain_info</a>, <a href="#SwiftToolchainInfo-clang_implicit_deps_providers">clang_implicit_deps_providers</a>, <a href="#SwiftToolchainInfo-developer_dirs">developer_dirs</a>,
<a href="#SwiftToolchainInfo-feature_allowlists">feature_allowlists</a>, <a href="#SwiftToolchainInfo-generated_header_module_implicit_deps_providers">generated_header_module_implicit_deps_providers</a>,
<a href="#SwiftToolchainInfo-implicit_deps_providers">implicit_deps_providers</a>, <a href="#SwiftToolchainInfo-linker_supports_filelist">linker_supports_filelist</a>, <a href="#SwiftToolchainInfo-package_configurations">package_configurations</a>,
<a href="#SwiftToolchainInfo-requested_features">requested_features</a>, <a href="#SwiftToolchainInfo-root_dir">root_dir</a>, <a href="#SwiftToolchainInfo-swift_worker">swift_worker</a>, <a href="#SwiftToolchainInfo-test_configuration">test_configuration</a>, <a href="#SwiftToolchainInfo-tool_configs">tool_configs</a>,
Expand All @@ -81,6 +81,7 @@ that use the toolchain.
| <a id="SwiftToolchainInfo-action_configs"></a>action_configs | This field is an internal implementation detail of the build rules. |
| <a id="SwiftToolchainInfo-cc_toolchain_info"></a>cc_toolchain_info | The <code>cc_common.CcToolchainInfo</code> provider from the Bazel C++ toolchain that this Swift toolchain depends on. |
| <a id="SwiftToolchainInfo-clang_implicit_deps_providers"></a>clang_implicit_deps_providers | A <code>struct</code> with the following fields, which represent providers from targets that should be added as implicit dependencies of any precompiled explicit C/Objective-C modules:<br><br>* <code>cc_infos</code>: A list of <code>CcInfo</code> providers from targets specified as the toolchain's implicit dependencies. * <code>objc_infos</code>: A list of <code>apple_common.Objc</code> providers from targets specified as the toolchain's implicit dependencies. * <code>swift_infos</code>: A list of <code>SwiftInfo</code> providers from targets specified as the toolchain's implicit dependencies.<br><br>For ease of use, this field is never <code>None</code>; it will always be a valid <code>struct</code> containing the fields described above, even if those lists are empty. |
| <a id="SwiftToolchainInfo-developer_dirs"></a>developer_dirs | A list of <code>structs</code> containing the following fields:* <code>developer_path_label</code>: A <code>string</code> representing the type of developer path. * <code>path</code>: A <code>string</code> representing the path to the developer framework. |
| <a id="SwiftToolchainInfo-feature_allowlists"></a>feature_allowlists | A list of <code>SwiftFeatureAllowlistInfo</code> providers that allow or prohibit packages from requesting or disabling features. |
| <a id="SwiftToolchainInfo-generated_header_module_implicit_deps_providers"></a>generated_header_module_implicit_deps_providers | A <code>struct</code> with the following fields, which are providers from targets that should be treated as compile-time inputs to actions that precompile the explicit module for the generated Objective-C header of a Swift module:<br><br>* <code>cc_infos</code>: A list of <code>CcInfo</code> providers from targets specified as the toolchain's implicit dependencies. * <code>objc_infos</code>: A list of <code>apple_common.Objc</code> providers from targets specified as the toolchain's implicit dependencies. * <code>swift_infos</code>: A list of <code>SwiftInfo</code> providers from targets specified as the toolchain's implicit dependencies.<br><br>This is used to provide modular dependencies for the fixed inclusions (Darwin, Foundation) that are unconditionally emitted in those files.<br><br>For ease of use, this field is never <code>None</code>; it will always be a valid <code>struct</code> containing the fields described above, even if those lists are empty. |
| <a id="SwiftToolchainInfo-implicit_deps_providers"></a>implicit_deps_providers | A <code>struct</code> with the following fields, which represent providers from targets that should be added as implicit dependencies of any Swift compilation or linking target (but not to precompiled explicit C/Objective-C modules):<br><br>* <code>cc_infos</code>: A list of <code>CcInfo</code> providers from targets specified as the toolchain's implicit dependencies. * <code>objc_infos</code>: A list of <code>apple_common.Objc</code> providers from targets specified as the toolchain's implicit dependencies. * <code>swift_infos</code>: A list of <code>SwiftInfo</code> providers from targets specified as the toolchain's implicit dependencies.<br><br>For ease of use, this field is never <code>None</code>; it will always be a valid <code>struct</code> containing the fields described above, even if those lists are empty. |
Expand Down
8 changes: 8 additions & 0 deletions swift/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ bzl_library(
":autolinking",
":debugging",
":derived_files",
":developer_dirs",
":feature_names",
":features",
":providers",
Expand Down Expand Up @@ -77,6 +78,13 @@ bzl_library(
],
)

bzl_library(
name = "developer_dirs",
srcs = ["developer_dirs.bzl"],
visibility = ["//swift:__subpackages__"],
deps = ["@bazel_skylib//lib:paths"],
)

bzl_library(
name = "features",
srcs = ["features.bzl"],
Expand Down
84 changes: 82 additions & 2 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ load(
"struct_fields",
)
load(":vfsoverlay.bzl", "write_vfsoverlay")
load(
":developer_dirs.bzl",
"developer_dirs_linkopts",
"platform_developer_framework_dir",
"swift_developer_lib_dir",
)

# VFS root where all .swiftmodule files will be placed when
# SWIFT_FEATURE_VFSOVERLAY is enabled.
Expand Down Expand Up @@ -490,6 +496,22 @@ def compile_action_configs(
features = [SWIFT_FEATURE_ENABLE_TESTING],
),

# Set Developer Framework search paths
swift_toolchain_config.action_config(
actions = [
swift_action_names.COMPILE,
swift_action_names.DERIVE_FILES,
swift_action_names.DUMP_AST,
],
configurators = [_non_pcm_developer_framework_paths_configurator],
),
swift_toolchain_config.action_config(
actions = [
swift_action_names.PRECOMPILE_C_MODULE,
],
configurators = [_pcm_developer_framework_paths_configurator],
),

# Emit appropriate levels of debug info. On Apple platforms, requesting
# dSYMs (regardless of compilation mode) forces full debug info because
# `dsymutil` produces spurious warnings about symbols in the debug map
Expand Down Expand Up @@ -1209,6 +1231,51 @@ def _c_layering_check_configurator(prerequisites, args):
args.add("-Xcc", "-fmodules-strict-decluse")
return None

# The platform developer framework directory contains XCTest.swiftmodule
# with Swift extensions to XCTest, so it needs to be added to the search
# path on platforms where it exists.
def _add_developer_swift_imports(developer_dirs, args):
platform_developer_framework = platform_developer_framework_dir(
developer_dirs,
)
if platform_developer_framework:
swift_developer_lib_dir_path = swift_developer_lib_dir(
developer_dirs,
)
args.add(swift_developer_lib_dir_path, format = "-I%s")

def _non_pcm_developer_framework_paths_configurator(prerequisites, args):
""" Adds developer frameworks flags to the command line. """
if prerequisites.is_test:
args.add_all(
[
developer_dir.path
for developer_dir in prerequisites.developer_dirs
],
format_each = "-F%s",
)
_add_developer_swift_imports(
prerequisites.developer_dirs,
args,
)

# PCM version of the logic above
def _pcm_developer_framework_paths_configurator(prerequisites, args):
""" Adds developer frameworks flags to the command line. """
if prerequisites.is_test:
args.add_all(
[
developer_dir.path
for developer_dir in prerequisites.developer_dirs
],
before_each = "-Xcc",
format_each = "-F%s",
)
_add_developer_swift_imports(
prerequisites.developer_dirs,
args,
)

def _clang_search_paths_configurator(prerequisites, args):
"""Adds Clang search paths to the command line."""
args.add_all(
Expand Down Expand Up @@ -1791,6 +1858,7 @@ def compile(
deps = [],
feature_configuration,
generated_header_name = None,
is_test,
module_name,
private_deps = [],
srcs,
Expand All @@ -1817,6 +1885,7 @@ def compile(
`SwiftInfo`, or `apple_common.Objc`.
feature_configuration: A feature configuration obtained from
`swift_common.configure_features`.
is_test: Represents if the `testonly` value of the context.
generated_header_name: The name of the Objective-C generated header that
should be generated for this module. If omitted, no header will be
generated.
Expand Down Expand Up @@ -1973,8 +2042,10 @@ def compile(
bin_dir = feature_configuration._bin_dir,
cc_compilation_context = merged_providers.cc_info.compilation_context,
defines = sets.to_list(defines_set),
developer_dirs = swift_toolchain.developer_dirs,
genfiles_dir = feature_configuration._genfiles_dir,
is_swift = True,
is_test = is_test,
module_name = module_name,
objc_include_paths_workaround = (
merged_providers.objc_include_paths_workaround
Expand Down Expand Up @@ -2763,9 +2834,11 @@ def new_objc_provider(
alwayslink = False,
deps,
feature_configuration,
is_test,
libraries_to_link,
module_context,
user_link_flags = []):
user_link_flags = [],
swift_toolchain):
"""Creates an `apple_common.Objc` provider for a Swift target.
Args:
Expand All @@ -2780,12 +2853,14 @@ def new_objc_provider(
will be passed to the new one in order to propagate the correct
transitive fields.
feature_configuration: The Swift feature configuration.
is_test: Represents if the `testonly` value of the context.
libraries_to_link: A list (typically of one element) of the
`LibraryToLink` objects from which the static archives (`.a` files)
containing the target's compiled code will be retrieved.
module_context: The module context as returned by
`swift_common.compile`.
user_link_flags: Linker options that should be propagated to dependents.
swift_toolchain: The `SwiftToolchainInfo` provider of the toolchain.
Returns:
An `apple_common.Objc` provider that should be returned by the calling
Expand Down Expand Up @@ -2831,6 +2906,11 @@ def new_objc_provider(
debug_link_flags = []
debug_link_inputs = []

if is_test:
developer_paths_linkopts = developer_dirs_linkopts(swift_toolchain.developer_dirs)
else:
developer_paths_linkopts = []

return apple_common.new_objc_provider(
force_load_library = depset(
force_load_libraries,
Expand All @@ -2842,7 +2922,7 @@ def new_objc_provider(
order = "topological",
),
link_inputs = depset(additional_link_inputs + debug_link_inputs),
linkopt = depset(user_link_flags + debug_link_flags),
linkopt = depset(user_link_flags + debug_link_flags + developer_paths_linkopts),
providers = get_providers(
deps,
apple_common.Objc,
Expand Down
Loading

0 comments on commit d39d966

Please sign in to comment.