Skip to content

Commit 9d33c7a

Browse files
authored
Collect .lo files from dependencies as binaries in apple_framework_pa… (#943)
…ckaging When `alwayslink` is `True`, `objc_library` can produce an `.lo` file instead of an `.a` file. From the `cc_library` docs (which I believe also apply to `objc_library`): https://bazel.build/reference/be/c-cpp#cc_library > Use cc_library() for C++-compiled libraries. The result is either a .so, .lo, or .a, depending on what is needed. > > If you build something with static linking that depends on a cc_library, the output of a depended-on library rule is the .a file. If you specify alwayslink=True, you get the .lo file. > > The actual output file name is libfoo.so for the shared library, where foo is the name of the rule. The other kinds of libraries end with .lo and .a, respectively. If you need a specific shared library name, for example, to define a Python module, use a genrule to copy the library to the desired name. I'm not 100% sure if this is valid (does a .framework bundle with an .lo file as its binary make sense?), and the non-VFS codepath that [uses libtool to merge the `objc_library` and `swift_library` binary might break](https://github.com/bazel-ios/rules_ios/blob/f7dcd0c4f90985495bba517dc8cc7d86ce7f7632/rules/framework/framework_packaging.py#L19). But if [no binary is set in the `AppleBundleInfo` provider, `rules_xcodeproj` treats `apple_framework_packaging` targets as unsupported.](https://github.com/MobileNativeFoundation/rules_xcodeproj/blob/41929acc4c7c1da973c77871d0375207b9d0806f/xcodeproj/internal/automatic_target_info.bzl#L497)
1 parent 99db8be commit 9d33c7a

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""An analysis test to assert that the default outputs of a target match a specified list."""
2+
3+
load("@bazel_skylib//lib:sets.bzl", "sets")
4+
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
5+
6+
def _default_outputs_test(ctx):
7+
env = analysistest.begin(ctx)
8+
target_under_test = analysistest.target_under_test(env)
9+
10+
actual_output_paths = [
11+
file.short_path
12+
for file in target_under_test[DefaultInfo].files.to_list()
13+
]
14+
expected_output_paths = [
15+
target_under_test.label.package + "/" + path
16+
for path in ctx.attr.expected_output_file_paths
17+
]
18+
19+
asserts.set_equals(
20+
env,
21+
sets.make(expected_output_paths),
22+
sets.make(actual_output_paths),
23+
"Expected output paths do not match actual output paths",
24+
)
25+
26+
return analysistest.end(env)
27+
28+
default_outputs_test = analysistest.make(
29+
_default_outputs_test,
30+
attrs = {
31+
"expected_output_file_paths": attr.string_list(
32+
mandatory = True,
33+
allow_empty = False,
34+
doc = """A list of expected output file paths. The paths are relative to the package of the target under test""",
35+
),
36+
},
37+
)

rules/framework.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ def _get_framework_files(ctx, deps):
355355
continue
356356

357357
# collect binary files
358-
if file.path.endswith(".a"):
358+
if file.path.endswith(".a") or file.path.endswith(".lo"):
359359
binaries_in.append(file)
360360

361361
# collect swift specific files

tests/ios/app/analysis-tests.bzl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
load("//rules/analysis_tests:default_outputs_test.bzl", "default_outputs_test")
12
load("//rules/analysis_tests:identical_outputs_test.bzl", "identical_outputs_test")
23

34
def make_tests():
@@ -10,6 +11,27 @@ def make_tests():
1011
deps = [":AppWithSelectableCopts", ":SwiftLib"],
1112
)
1213

14+
default_outputs_test(
15+
name = "test_FWOutputs",
16+
target_under_test = ":FW",
17+
expected_output_file_paths = select({
18+
"//:virtualize_frameworks": [
19+
"libFW_objc.lo",
20+
"FW/FW.h",
21+
"FW-modulemap/FW-umbrella.h",
22+
"FW/FW_Private.h",
23+
"FW-modulemap/FW.modulemap",
24+
],
25+
"//conditions:default": [
26+
"FW/FW.framework/FW",
27+
"FW/FW.framework/Headers/FW.h",
28+
"FW/FW.framework/Headers/FW-umbrella.h",
29+
"FW/FW.framework/PrivateHeaders/FW_Private.h",
30+
"FW/FW.framework/Modules/module.modulemap",
31+
],
32+
}),
33+
)
34+
1335
native.test_suite(
1436
name = "AnalysisTests",
1537
tests = [

0 commit comments

Comments
 (0)