Skip to content

Commit 152ee39

Browse files
committed
Support launchdplists
Add support for both BwB and BwX for the `launchdplists` rules_apple attribute.
1 parent aaee1a9 commit 152ee39

File tree

10 files changed

+158
-0
lines changed

10 files changed

+158
-0
lines changed

examples/command_line/tool/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ macos_command_line_application(
1212
"export_symbol_list.exp",
1313
],
1414
infoplists = ["Info.plist"],
15+
launchdplists = ["Launchd.plist"],
1516
minimum_os_version = "11.0",
1617
visibility = ["//visibility:public"],
1718
deps = [":tool.library"],
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>Label</key>
6+
<string>com.example.tool</string>
7+
<key>ProgramArguments</key>
8+
<array>
9+
<string>arg1</string>
10+
<string>arg2</string>
11+
</array>
12+
<key>KeepAlive</key>
13+
<true/>
14+
</dict>
15+
</plist>

test/internal/launchd_plists/BUILD

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load(
2+
":get_file_from_objc_provider_tests.bzl",
3+
"get_file_from_objc_provider_test_suite",
4+
)
5+
load(":get_file_tests.bzl", "get_file_test_suite")
6+
7+
get_file_from_objc_provider_test_suite(name = "get_file_from_objc_provider")
8+
9+
get_file_test_suite(name = "get_file")
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Tests for `launchd_plists.get_file_from_objc_provider`."""
2+
3+
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
4+
5+
# buildifier: disable=bzl-visibility
6+
load("//xcodeproj/internal:launchd_plists.bzl", "launchd_plists")
7+
8+
def _get_file_from_objc_provider_test(ctx):
9+
env = unittest.begin(ctx)
10+
11+
launchd_plist_file = ctx.actions.declare_file("Launchd.plist")
12+
ctx.actions.write(launchd_plist_file, content = "")
13+
launchd_plist_path = launchd_plist_file.path
14+
15+
linkopt_list = [
16+
"-Wl,-sectcreate,__TEXT,__launchd_plist,{}".format(launchd_plist_path),
17+
]
18+
link_inputs_list = [launchd_plist_file]
19+
linkopt_depset = depset(linkopt_list)
20+
link_inputs_depset = depset(link_inputs_list)
21+
22+
objc_prov = apple_common.new_objc_provider(
23+
linkopt = linkopt_depset,
24+
link_inputs = link_inputs_depset,
25+
)
26+
27+
actual = launchd_plists.get_file_from_objc_provider(objc_prov)
28+
asserts.equals(env, launchd_plist_file, actual)
29+
30+
return unittest.end(env)
31+
32+
get_file_from_objc_provider_test = unittest.make(
33+
_get_file_from_objc_provider_test,
34+
)
35+
36+
def get_file_from_objc_provider_test_suite(name):
37+
return unittest.suite(
38+
name,
39+
get_file_from_objc_provider_test,
40+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Tests for `launchd_plists.get_file`."""
2+
3+
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
4+
5+
# buildifier: disable=bzl-visibility
6+
load("//xcodeproj/internal:launchd_plists.bzl", "launchd_plists")
7+
8+
def _get_file_from_apple_executable_binary_test(ctx):
9+
env = unittest.begin(ctx)
10+
11+
launchd_plist_file = ctx.actions.declare_file("Launchd.plist")
12+
ctx.actions.write(launchd_plist_file, content = "")
13+
14+
linkopt_list = [
15+
"-Wl,-sectcreate,__TEXT,__launchd_plist,{}".format(launchd_plist_file.path),
16+
]
17+
link_inputs_list = [launchd_plist_file]
18+
linkopt_depset = depset(linkopt_list)
19+
link_inputs_depset = depset(link_inputs_list)
20+
21+
objc_prov = apple_common.new_objc_provider(
22+
linkopt = linkopt_depset,
23+
link_inputs = link_inputs_depset,
24+
)
25+
26+
executable_binary_prov = apple_common.AppleExecutableBinary(objc = objc_prov)
27+
target = {apple_common.AppleExecutableBinary: executable_binary_prov}
28+
29+
actual = launchd_plists.get_file(target)
30+
asserts.equals(env, launchd_plist_file, actual)
31+
32+
return unittest.end(env)
33+
34+
get_file_from_apple_executable_binary_test = unittest.make(_get_file_from_apple_executable_binary_test)
35+
36+
def get_file_test_suite(name):
37+
return unittest.suite(
38+
name,
39+
get_file_from_apple_executable_binary_test,
40+
)

xcodeproj/internal/default_automatic_target_processing_aspect.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def _default_automatic_target_processing_aspect_impl(target, ctx):
6363
entitlements = None
6464
exported_symbols_lists = []
6565
infoplists = []
66+
launchdplists = []
6667
bazel_build_mode_error = None
6768
non_arc_srcs = []
6869
pch = None
@@ -117,6 +118,8 @@ def _default_automatic_target_processing_aspect_impl(target, ctx):
117118
exported_symbols_lists = ["exported_symbols_lists"]
118119
if "infoplists" in attrs:
119120
infoplists = ["infoplists"]
121+
if "launchdplists" in attrs:
122+
launchdplists = ["launchdplists"]
120123
xcode_targets = {"deps": [target_type.compile]}
121124
elif AppleFrameworkImportInfo in target:
122125
xcode_targets = {"deps": [target_type.compile]}
@@ -153,6 +156,7 @@ def _default_automatic_target_processing_aspect_impl(target, ctx):
153156
bundle_id = bundle_id,
154157
provisioning_profile = provisioning_profile,
155158
infoplists = infoplists,
159+
launchdplists = launchdplists,
156160
entitlements = entitlements,
157161
bazel_build_mode_error = bazel_build_mode_error,
158162
),

xcodeproj/internal/input_files.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def _is_categorized_attr(attr, *, automatic_target_info):
6464
return True
6565
elif attr in automatic_target_info.exported_symbols_lists:
6666
return True
67+
elif attr in automatic_target_info.launchdplists:
68+
return True
6769
else:
6870
return False
6971

@@ -177,6 +179,9 @@ def _collect(
177179
# We don't need to include a generated one, as we already use
178180
# the Bazel generated one, which is one step further generated
179181
extra_files.append(file_path(file))
182+
elif attr in automatic_target_info.launchdplists:
183+
if file.is_source:
184+
extra_files.append(file_path(file))
180185
elif attr == automatic_target_info.entitlements:
181186
# We use `append` instead of setting a single value because
182187
# assigning to `entitlements` creates a new local variable instead
@@ -353,6 +358,7 @@ def _from_resource_bundle(bundle):
353358
resource_bundles = depset(),
354359
resource_bundle_dependencies = bundle.dependencies,
355360
infoplists = depset(),
361+
launchdplists = depset(),
356362
entitlements = None,
357363
exported_symbols_lists = depset(),
358364
xccurrentversions = depset(),

xcodeproj/internal/launchd_plists.bzl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""API to retrieve a launchd plist file from a `Target`."""
2+
3+
load(":link_opts.bzl", "link_opts")
4+
5+
def _get_file_from_objc_provider(objc_provider):
6+
"""
7+
Retrieves the launchd plist from the TEXT section provided by the ObjcProvider.
8+
"""
9+
10+
launchd_plist_section = link_opts.get_section(
11+
objc_provider.linkopt.to_list(),
12+
"__TEXT",
13+
"__launchd_plist",
14+
)
15+
16+
if launchd_plist_section == None:
17+
return None
18+
19+
# Retrieve the info plist file from the link inputs
20+
for file in objc_provider.link_inputs.to_list():
21+
if file.path == launchd_plist_section.file:
22+
return file
23+
return None
24+
25+
def _get_file(target):
26+
if apple_common.AppleExecutableBinary in target:
27+
return _get_file_from_objc_provider(target[apple_common.AppleExecutableBinary].objc)
28+
return None
29+
30+
launchd_plists = struct(
31+
get_file = _get_file,
32+
)

xcodeproj/internal/providers.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ A sequence of attribute names to collect `File`s from for the
3838
"infoplists": """\
3939
A sequence of attribute names to collect `File`s from for the `infoplists`-like
4040
attributes.
41+
""",
42+
"launchdplists": """\
43+
A sequence of attribute names to collect `File`s from for the `launchdplists`-like
44+
attributes.
4145
""",
4246
"non_arc_srcs": """\
4347
A sequence of attribute names to collect `File`s from for `non_arc_srcs`-like

xcodeproj/internal/top_level_targets.bzl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ load(":collections.bzl", "set_if_true")
88
load(":configuration.bzl", "get_configuration")
99
load(":files.bzl", "file_path", "join_paths_ignoring_empty")
1010
load(":info_plists.bzl", "info_plists")
11+
load(":launchd_plists.bzl", "launchd_plists")
1112
load(":input_files.bzl", "input_files")
1213
load(":linker_input_files.bzl", "linker_input_files")
1314
load(":opts.bzl", "process_opts")
@@ -194,6 +195,12 @@ def process_top_level_target(
194195
info_plist = file_path(info_plist_file)
195196
additional_files.append(info_plist_file)
196197

198+
launcd_plist = None
199+
launchd_plist_file = launchd_plists.get_file(target)
200+
if launchd_plist_file:
201+
launchd_plist = file_path(launchd_plist_file)
202+
additional_files.append(launchd_plist_file)
203+
197204
provisioning_profiles.process_attr(
198205
ctx = ctx,
199206
automatic_target_info = automatic_target_info,

0 commit comments

Comments
 (0)