Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add publicly_expose_all_targets flag #1345

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/bzlmod_extensions_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ On this page:
<pre>
swift_deps = use_extension("@rules_swift_package_manager//:extensions.bzl", "swift_deps")
swift_deps.configure_package(<a href="#swift_deps.configure_package-name">name</a>, <a href="#swift_deps.configure_package-init_submodules">init_submodules</a>, <a href="#swift_deps.configure_package-patch_args">patch_args</a>, <a href="#swift_deps.configure_package-patch_cmds">patch_cmds</a>, <a href="#swift_deps.configure_package-patch_cmds_win">patch_cmds_win</a>,
<a href="#swift_deps.configure_package-patch_tool">patch_tool</a>, <a href="#swift_deps.configure_package-patches">patches</a>, <a href="#swift_deps.configure_package-recursive_init_submodules">recursive_init_submodules</a>)
<a href="#swift_deps.configure_package-patch_tool">patch_tool</a>, <a href="#swift_deps.configure_package-patches">patches</a>, <a href="#swift_deps.configure_package-publicly_expose_all_targets">publicly_expose_all_targets</a>,
<a href="#swift_deps.configure_package-recursive_init_submodules">recursive_init_submodules</a>)
swift_deps.configure_swift_package(<a href="#swift_deps.configure_swift_package-build_path">build_path</a>, <a href="#swift_deps.configure_swift_package-cache_path">cache_path</a>, <a href="#swift_deps.configure_swift_package-dependency_caching">dependency_caching</a>, <a href="#swift_deps.configure_swift_package-manifest_cache">manifest_cache</a>,
<a href="#swift_deps.configure_swift_package-manifest_caching">manifest_caching</a>, <a href="#swift_deps.configure_swift_package-security_path">security_path</a>)
swift_deps.from_package(<a href="#swift_deps.from_package-declare_swift_deps_info">declare_swift_deps_info</a>, <a href="#swift_deps.from_package-declare_swift_package">declare_swift_package</a>, <a href="#swift_deps.from_package-resolved">resolved</a>, <a href="#swift_deps.from_package-swift">swift</a>)
Expand All @@ -42,6 +43,7 @@ Used to add or override settings for a particular Swift package.
| <a id="swift_deps.configure_package-patch_cmds_win"></a>patch_cmds_win | Sequence of Powershell commands to be applied on Windows after patches are applied. If this attribute is not set, patch_cmds will be executed on Windows, which requires Bash binary to exist. | List of strings | optional | `[]` |
| <a id="swift_deps.configure_package-patch_tool"></a>patch_tool | The patch(1) utility to use. If this is specified, Bazel will use the specified patch tool instead of the Bazel-native patch implementation. | String | optional | `""` |
| <a id="swift_deps.configure_package-patches"></a>patches | A list of files that are to be applied as patches after extracting the archive. By default, it uses the Bazel-native patch implementation which doesn't support fuzz match and binary patch, but Bazel will fall back to use patch command line tool if `patch_tool` attribute is specified or there are arguments other than `-p` in `patch_args` attribute. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="swift_deps.configure_package-publicly_expose_all_targets"></a>publicly_expose_all_targets | Allows to expose internal build targets required for package compilation. The structure and labels of exposed targets may change in future releases without requiring a major version bump. | Boolean | optional | `False` |
| <a id="swift_deps.configure_package-recursive_init_submodules"></a>recursive_init_submodules | Whether to clone submodules recursively in the repository. | Boolean | optional | `True` |

<a id="swift_deps.configure_swift_package"></a>
Expand Down
6 changes: 4 additions & 2 deletions docs/repository_rules_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ Used to build a local Swift package.

<pre>
swift_package(<a href="#swift_package-name">name</a>, <a href="#swift_package-bazel_package_name">bazel_package_name</a>, <a href="#swift_package-branch">branch</a>, <a href="#swift_package-commit">commit</a>, <a href="#swift_package-dependencies_index">dependencies_index</a>, <a href="#swift_package-env">env</a>, <a href="#swift_package-init_submodules">init_submodules</a>,
<a href="#swift_package-patch_args">patch_args</a>, <a href="#swift_package-patch_cmds">patch_cmds</a>, <a href="#swift_package-patch_cmds_win">patch_cmds_win</a>, <a href="#swift_package-patch_tool">patch_tool</a>, <a href="#swift_package-patches">patches</a>, <a href="#swift_package-recursive_init_submodules">recursive_init_submodules</a>,
<a href="#swift_package-remote">remote</a>, <a href="#swift_package-repo_mapping">repo_mapping</a>, <a href="#swift_package-shallow_since">shallow_since</a>, <a href="#swift_package-tag">tag</a>, <a href="#swift_package-verbose">verbose</a>, <a href="#swift_package-version">version</a>)
<a href="#swift_package-patch_args">patch_args</a>, <a href="#swift_package-patch_cmds">patch_cmds</a>, <a href="#swift_package-patch_cmds_win">patch_cmds_win</a>, <a href="#swift_package-patch_tool">patch_tool</a>, <a href="#swift_package-patches">patches</a>,
<a href="#swift_package-publicly_expose_all_targets">publicly_expose_all_targets</a>, <a href="#swift_package-recursive_init_submodules">recursive_init_submodules</a>, <a href="#swift_package-remote">remote</a>, <a href="#swift_package-repo_mapping">repo_mapping</a>,
<a href="#swift_package-shallow_since">shallow_since</a>, <a href="#swift_package-tag">tag</a>, <a href="#swift_package-verbose">verbose</a>, <a href="#swift_package-version">version</a>)
</pre>

Used to download and build an external Swift package.
Expand All @@ -64,6 +65,7 @@ Used to download and build an external Swift package.
| <a id="swift_package-patch_cmds_win"></a>patch_cmds_win | Sequence of Powershell commands to be applied on Windows after patches are applied. If this attribute is not set, patch_cmds will be executed on Windows, which requires Bash binary to exist. | List of strings | optional | `[]` |
| <a id="swift_package-patch_tool"></a>patch_tool | The patch(1) utility to use. If this is specified, Bazel will use the specified patch tool instead of the Bazel-native patch implementation. | String | optional | `""` |
| <a id="swift_package-patches"></a>patches | A list of files that are to be applied as patches after extracting the archive. By default, it uses the Bazel-native patch implementation which doesn't support fuzz match and binary patch, but Bazel will fall back to use patch command line tool if `patch_tool` attribute is specified or there are arguments other than `-p` in `patch_args` attribute. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="swift_package-publicly_expose_all_targets"></a>publicly_expose_all_targets | Allows to expose internal build targets required for package compilation. The structure and labels of exposed targets may change in future releases without requiring a major version bump. | Boolean | optional | `False` |
| <a id="swift_package-recursive_init_submodules"></a>recursive_init_submodules | Whether to clone submodules recursively in the repository. | Boolean | optional | `True` |
| <a id="swift_package-remote"></a>remote | The version control location from where the repository should be downloaded. | String | required | |
| <a id="swift_package-repo_mapping"></a>repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<br><br>For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).<br><br>This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | |
Expand Down
17 changes: 15 additions & 2 deletions swiftpkg/bzlmod/swift_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load("//swiftpkg/internal:local_swift_package.bzl", "local_swift_package")
load("//swiftpkg/internal:pkginfos.bzl", "pkginfos")
load("//swiftpkg/internal:repository_utils.bzl", "repository_utils")
load("//swiftpkg/internal:swift_deps_info.bzl", "swift_deps_info")
load("//swiftpkg/internal:swift_package.bzl", "PATCH_ATTRS", "swift_package")
load("//swiftpkg/internal:swift_package.bzl", "PATCH_ATTRS", "TOOL_ATTRS", "swift_package")
load("//swiftpkg/internal:swift_package_tool.bzl", "SWIFT_PACKAGE_CONFIG_ATTRS")
load("//swiftpkg/internal:swift_package_tool_repo.bzl", "swift_package_tool_repo")

Expand Down Expand Up @@ -150,6 +150,16 @@ the Swift package to make it available.\
)
_declare_pkg_from_dependency(dep, config_pkg)

# Add all transitive dependencies to direct_dep_repo_names if `publicly_expose_all_targets` flag is set.
for dep in all_deps_by_id.values():
config_pkg = config_pkgs.get(dep.name) or config_pkgs.get(
bazel_repo_names.from_identity(dep.identity),
)
if config_pkg and config_pkg.publicly_expose_all_targets:
bazel_repo_name = bazel_repo_names.from_identity(dep.identity)
if bazel_repo_name not in direct_dep_repo_names:
direct_dep_repo_names.append(bazel_repo_name)

return direct_dep_repo_names

def _declare_pkg_from_dependency(dep, config_pkg):
Expand All @@ -162,6 +172,7 @@ def _declare_pkg_from_dependency(dep, config_pkg):
patch_cmds_win = None
patch_tool = None
patches = None
publicly_expose_all_targets = None
if config_pkg:
init_submodules = config_pkg.init_submodules
recursive_init_submodules = config_pkg.recursive_init_submodules
Expand All @@ -170,6 +181,7 @@ def _declare_pkg_from_dependency(dep, config_pkg):
patch_cmds_win = config_pkg.patch_cmds_win
patch_tool = config_pkg.patch_tool
patches = config_pkg.patches
publicly_expose_all_targets = config_pkg.publicly_expose_all_targets

pin = dep.source_control.pin
swift_package(
Expand All @@ -186,6 +198,7 @@ def _declare_pkg_from_dependency(dep, config_pkg):
patch_cmds_win = patch_cmds_win,
patch_tool = patch_tool,
patches = patches,
publicly_expose_all_targets = publicly_expose_all_targets,
)

elif dep.file_system:
Expand Down Expand Up @@ -291,7 +304,7 @@ The identity (i.e., name in the package's manifest) for the Swift package.\
default = True,
doc = "Whether to clone submodules recursively in the repository.",
),
} | PATCH_ATTRS,
} | PATCH_ATTRS | TOOL_ATTRS,
doc = "Used to add or override settings for a particular Swift package.",
)

Expand Down
11 changes: 11 additions & 0 deletions swiftpkg/internal/pkginfos.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ def _new_from_parsed_json(

url = None
version = None
expose_build_targets = False
if hasattr(repository_ctx, "attr"):
# We only want to try to collect url and version when called from
# `swift_package`
Expand All @@ -609,6 +610,11 @@ def _new_from_parsed_json(
"version",
getattr(repository_ctx.attr, "commit", None),
)
expose_build_targets = getattr(
repository_ctx.attr,
"publicly_expose_all_targets",
False,
)

return _new(
name = dump_manifest["name"],
Expand All @@ -624,6 +630,7 @@ def _new_from_parsed_json(
targets = targets,
url = url,
version = version,
expose_build_targets = expose_build_targets,
c_language_standard = dump_manifest.get("cLanguageStandard"),
cxx_language_standard = dump_manifest.get("cxxLanguageStandard"),
)
Expand All @@ -641,6 +648,7 @@ def _new(
targets = [],
url = None,
version = None,
expose_build_targets = False,
c_language_standard = None,
cxx_language_standard = None):
"""Returns a `struct` representing information about a Swift package.
Expand All @@ -661,6 +669,8 @@ def _new(
`pkginfos.new_target()`.
url: Optional. The url of the package (`string`).
version: Optional. The semantic version of the package (`string`).
expose_build_targets: Optional. Defaults to False. A boolean that specifies whether to expose
the package's internal build targets.
c_language_standard: Optional. The c language standard (e.g. `c99`,
`gnu99`, `c11`).
cxx_language_standard: Optional. The c++ language standard (e.g.
Expand All @@ -680,6 +690,7 @@ def _new(
targets = targets,
url = url,
version = version,
expose_build_targets = expose_build_targets,
c_language_standard = c_language_standard,
cxx_language_standard = cxx_language_standard,
)
Expand Down
12 changes: 12 additions & 0 deletions swiftpkg/internal/swift_package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,20 @@ PATCH_ATTRS = {
),
}

TOOL_ATTRS = {
"publicly_expose_all_targets": attr.bool(
default = False,
doc = """
Allows to expose internal build targets required for package compilation.
The structure and labels of exposed targets may change in future releases
without requiring a major version bump.
""",
),
}

_ALL_ATTRS = dicts.add(
PATCH_ATTRS,
TOOL_ATTRS,
_GIT_ATTRS,
repo_rules.env_attrs,
repo_rules.swift_attrs,
Expand Down
25 changes: 16 additions & 9 deletions swiftpkg/internal/swiftpkg_build_files.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def _new_for_target(repository_ctx, pkg_ctx, target, artifact_infos = []):
lambda ai: ai.artifact_type == artifact_types.xcframework,
)
if xcf_artifact_info != None:
return _xcframework_import_build_file(target, xcf_artifact_info)
return _xcframework_import_build_file(pkg_ctx, target, xcf_artifact_info)

# GH046: Support plugins.
return None
Expand All @@ -44,7 +44,7 @@ def _swift_target_build_file(pkg_ctx, target):
attrs = {
"module_name": target.c99name,
"srcs": pkginfo_targets.srcs(target),
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(pkg_ctx.pkg_info.expose_build_targets),
}

def _update_attr_list(name, value):
Expand Down Expand Up @@ -340,7 +340,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
"alwayslink": True,
"copts": copts,
"srcs": srcs,
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(pkg_ctx.pkg_info.expose_build_targets),
}
if clang_src_info.hdrs:
attrs["hdrs"] = clang_src_info.hdrs
Expand Down Expand Up @@ -400,7 +400,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
"deps": [],
"hdrs": clang_src_info.hdrs,
"module_name": target.c99name,
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(pkg_ctx.pkg_info.expose_build_targets),
},
),
)
Expand Down Expand Up @@ -575,7 +575,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
":{}".format(dname)
for dname in child_dep_names
],
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(pkg_ctx.pkg_info.expose_build_targets),
}
decls.append(
build_decls.new(
Expand Down Expand Up @@ -660,7 +660,7 @@ def _system_library_build_file(target):

# MARK: - Apple xcframework Targets

def _xcframework_import_build_file(target, artifact_info):
def _xcframework_import_build_file(pkg_ctx, target, artifact_info):
attrs = {}
if artifact_info.link_type == link_types.static:
load_stmts = [apple_static_xcframework_import_load_stmt]
Expand Down Expand Up @@ -692,7 +692,7 @@ expected: {expected}\
kind = kind,
name = pkginfo_targets.bazel_label_name(target),
attrs = attrs | {
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(pkg_ctx.pkg_info.expose_build_targets),
"xcframework_imports": glob,
},
),
Expand All @@ -704,7 +704,7 @@ expected: {expected}\

# MARK: - Apple Resource Group

def _apple_resource_bundle(target, package_name, default_localization):
def _apple_resource_bundle(target, package_name, default_localization, expose_build_targets):
bzl_target_name = pkginfo_targets.bazel_label_name(target)
bundle_label_name = pkginfo_targets.resource_bundle_label_name(bzl_target_name)
bundle_name = pkginfo_targets.resource_bundle_name(package_name, target.c99name)
Expand Down Expand Up @@ -738,7 +738,7 @@ def _apple_resource_bundle(target, package_name, default_localization):
# Based upon the code in SPM, it looks like they only support unstructured resources.
# https://github.com/apple/swift-package-manager/blob/main/Sources/PackageModel/Resource.swift#L25-L33
"resources": resources,
"visibility": ["//:__subpackages__"],
"visibility": _target_visibility(expose_build_targets),
},
),
]
Expand All @@ -753,6 +753,7 @@ def _apple_resource_bundle_for_swift(pkg_ctx, target):
target,
pkg_ctx.pkg_info.name,
pkg_ctx.pkg_info.default_localization,
pkg_ctx.pkg_info.expose_build_targets,
)

# Apparently, SPM provides a `Bundle.module` accessor. So, we do too.
Expand Down Expand Up @@ -785,6 +786,7 @@ def _apple_resource_bundle_for_clang(pkg_ctx, target):
target,
pkg_ctx.pkg_info.name,
pkg_ctx.pkg_info.default_localization,
pkg_ctx.pkg_info.expose_build_targets,
)
all_build_files = [apple_res_bundle_info.build_file]
objc_accessor_hdr_label_name = None
Expand Down Expand Up @@ -1007,6 +1009,11 @@ def _new_for_license(pkg_info, license):
decls = decls,
)

# MARK: - Build targets encapsulation

def _target_visibility(expose_build_targets):
return ["//visibility:public"] if expose_build_targets else ["//:__subpackages__"]

# MARK: - Constants and API Definition

swift_location = "@build_bazel_rules_swift//swift:swift.bzl"
Expand Down
Loading