Skip to content

Commit

Permalink
Add experimental_expose_build_files flag (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
sewerynplazuk authored Nov 18, 2024
1 parent 85bd586 commit e6b9de1
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 19 deletions.
3 changes: 2 additions & 1 deletion docs/bzlmod_extensions_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ 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-recursive_init_submodules">recursive_init_submodules</a>, <a href="#swift_deps.configure_package-experimental_expose_build_files">experimental_expose_build_files</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 @@ -43,6 +43,7 @@ Used to add or override settings for a particular Swift package.
| <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-recursive_init_submodules"></a>recursive_init_submodules | Whether to clone submodules recursively in the repository. | Boolean | optional | `True` |
| <a id="swift_deps.configure_package-experimental_expose_build_files"></a>experimental_expose_build_files | Allows to expose internal build files required for package compilation. This option is experimental and should be used at your own risk. The structure and labels of exposed build files may change in future releases without requiring a major version bump. | Boolean | optional | `False` |

<a id="swift_deps.configure_swift_package"></a>

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", "EXPERIMENTAL_ATTRS", "PATCH_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 `experimental_expose_build_files` 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.experimental_expose_build_files:
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
experimental_expose_build_files = 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
experimental_expose_build_files = config_pkg.experimental_expose_build_files

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,
experimental_expose_build_files = experimental_expose_build_files,
)

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 | EXPERIMENTAL_ATTRS,
doc = "Used to add or override settings for a particular Swift package.",
)

Expand Down
11 changes: 11 additions & 0 deletions swiftpkg/internal/swift_package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,19 @@ PATCH_ATTRS = {
),
}

EXPERIMENTAL_ATTRS = {
"experimental_expose_build_files": attr.bool(
default = False,
doc = "Allows to expose internal build files required for package compilation. " +
"This option is experimental and should be used at your own risk. " +
"The structure and labels of exposed build files may change in future releases " +
"without requiring a major version bump.",
),
}

_ALL_ATTRS = dicts.add(
PATCH_ATTRS,
EXPERIMENTAL_ATTRS,
_GIT_ATTRS,
repo_rules.env_attrs,
repo_rules.swift_attrs,
Expand Down
40 changes: 25 additions & 15 deletions swiftpkg/internal/swiftpkg_build_files.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def _new_for_target(repository_ctx, pkg_ctx, target, artifact_infos = []):
if target.module_type == module_types.clang:
return _clang_target_build_file(repository_ctx, pkg_ctx, target)
elif target.module_type == module_types.swift:
return _swift_target_build_file(pkg_ctx, target)
return _swift_target_build_file(repository_ctx, pkg_ctx, target)
elif target.module_type == module_types.system_library:
return _system_library_build_file(target)
elif target.module_type == module_types.binary:
Expand All @@ -32,22 +32,22 @@ def _new_for_target(repository_ctx, pkg_ctx, target, artifact_infos = []):
lambda ai: ai.artifiact_type == artifact_types.xcframework,
)
if xcf_artifact_info != None:
return _xcframework_import_build_file(target, xcf_artifact_info)
return _xcframework_import_build_file(repository_ctx, target, xcf_artifact_info)

# GH046: Support plugins.
return None

# MARK: - Swift Target

def _swift_target_build_file(pkg_ctx, target):
def _swift_target_build_file(repository_ctx, pkg_ctx, target):
if target.swift_src_info == None:
fail("Expected a `swift_src_info`. name: ", target.name)

all_build_files = []
attrs = {
"module_name": target.c99name,
"srcs": pkginfo_targets.srcs(target),
"visibility": ["//:__subpackages__"],
"visibility": _build_file_visibility(repository_ctx),
}

def _update_attr_list(name, value):
Expand Down Expand Up @@ -144,6 +144,7 @@ def _swift_target_build_file(pkg_ctx, target):

if target.resources:
swift_apple_res_bundle_info = _apple_resource_bundle_for_swift(
repository_ctx,
pkg_ctx,
target,
)
Expand Down Expand Up @@ -176,7 +177,7 @@ def _swift_target_build_file(pkg_ctx, target):

# Generate a modulemap for the Swift module.
if attrs.get("generates_header", False):
all_build_files.append(_generate_modulemap_for_swift_target(target, deps))
all_build_files.append(_generate_modulemap_for_swift_target(repository_ctx, target, deps))

return build_files.merge(*all_build_files)

Expand Down Expand Up @@ -274,6 +275,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
clang_apple_res_bundle_info = None
if target.resources:
clang_apple_res_bundle_info = _apple_resource_bundle_for_clang(
repository_ctx,
pkg_ctx,
target,
)
Expand Down Expand Up @@ -363,7 +365,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
attrs = {
"copts": copts,
"srcs": srcs,
"visibility": ["//:__subpackages__"],
"visibility": _build_file_visibility(repository_ctx),
}
if clang_src_info.hdrs:
attrs["hdrs"] = clang_src_info.hdrs
Expand Down Expand Up @@ -438,7 +440,7 @@ def _clang_target_build_file(repository_ctx, pkg_ctx, target):
"hdrs": clang_src_info.hdrs,
"module_name": target.c99name,
"noop": noop_modulemap,
"visibility": ["//:__subpackages__"],
"visibility": _build_file_visibility(repository_ctx),
}
decls.append(
build_decls.new(
Expand Down Expand Up @@ -646,7 +648,7 @@ def _system_library_build_file(target):

# MARK: - Apple xcframework Targets

def _xcframework_import_build_file(target, artifact_info):
def _xcframework_import_build_file(repository_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 @@ -684,7 +686,7 @@ expected: {expected}\
kind = kind,
name = pkginfo_targets.bazel_label_name(target),
attrs = attrs | {
"visibility": ["//:__subpackages__"],
"visibility": _build_file_visibility(repository_ctx),
"xcframework_imports": glob,
},
),
Expand All @@ -696,7 +698,7 @@ expected: {expected}\

# MARK: - Apple Resource Group

def _apple_resource_bundle(target, package_name, default_localization):
def _apple_resource_bundle(repository_ctx, target, package_name, default_localization):
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 @@ -730,7 +732,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": _build_file_visibility(repository_ctx),
},
),
]
Expand All @@ -740,8 +742,9 @@ def _apple_resource_bundle(target, package_name, default_localization):
build_file = build_files.new(load_stmts = load_stmts, decls = decls),
)

def _apple_resource_bundle_for_swift(pkg_ctx, target):
def _apple_resource_bundle_for_swift(repository_ctx, pkg_ctx, target):
apple_res_bundle_info = _apple_resource_bundle(
repository_ctx,
target,
pkg_ctx.pkg_info.name,
pkg_ctx.pkg_info.default_localization,
Expand Down Expand Up @@ -772,8 +775,9 @@ def _apple_resource_bundle_for_swift(pkg_ctx, target):
),
)

def _apple_resource_bundle_for_clang(pkg_ctx, target):
def _apple_resource_bundle_for_clang(repository_ctx, pkg_ctx, target):
apple_res_bundle_info = _apple_resource_bundle(
repository_ctx,
target,
pkg_ctx.pkg_info.name,
pkg_ctx.pkg_info.default_localization,
Expand Down Expand Up @@ -856,7 +860,7 @@ def _collect_modulemap_deps(deps):
modulemap_deps.append(mm_dep)
return modulemap_deps

def _generate_modulemap_for_swift_target(target, deps):
def _generate_modulemap_for_swift_target(repository_ctx, target, deps):
load_stmts = [swiftpkg_generate_modulemap_load_stmt]
bzl_target_name = pkginfo_targets.bazel_label_name(target)
modulemap_target_name = pkginfo_targets.modulemap_label_name(bzl_target_name)
Expand All @@ -865,7 +869,7 @@ def _generate_modulemap_for_swift_target(target, deps):
"deps": bzl_selects.to_starlark(modulemap_deps),
"hdrs": [":{}".format(bzl_target_name)],
"module_name": target.c99name,
"visibility": ["//:__subpackages__"],
"visibility": _build_file_visibility(repository_ctx),
}
decls = [
build_decls.new(
Expand Down Expand Up @@ -1053,6 +1057,12 @@ def _new_for_license(pkg_info, license):
decls = decls,
)

# MARK: - Build files encapsulation

def _build_file_visibility(repository_ctx):
experimental_expose_build_files = getattr(repository_ctx.attr, "experimental_expose_build_files", False)
return ["//visibility:public"] if experimental_expose_build_files else ["//:__subpackages__"]

# MARK: - Constants and API Definition

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

0 comments on commit e6b9de1

Please sign in to comment.