-
Notifications
You must be signed in to change notification settings - Fork 85
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
Fix and assert swift imported header propagation #333
Conversation
This PR fixes a bug in swift compilation with imported framework transitive headers. Additionally it refactors the testing rules into a package that can be used with `rules_ios` or other repositories. These tests iclude existing tests for Bazel transitions being incorrect in `rules_ios` and the new generalized header test. The headers test allows a user to assert that tests are propagated to actions For cases: 1. add a frameworks directory to the app. This represents the case of `apple_framework.vendored_static_frameworks` which is commonly used as a way to import frameworks 2. test framework import under test-imports-app. Asserts transitive headers are loaded from TesnorFlow.
9416cae
to
b2a9946
Compare
rules/framework.bzl
Outdated
if not CcInfo in dep: | ||
continue | ||
for h in dep[CcInfo].compilation_context.headers.to_list(): | ||
propagated_interface_headers.append(depset([h])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will h.is_source be true for headers? Or true only to a set of headers? The original logic of continue if is_source is baffling me...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here-in lies the problem: it needs to propagate all of the headers somehow, e.g. rather than the ones of is_source
.. The documentation for is_source
indicates True
generated sources so if you use a generated source it would be true: https://docs.bazel.build/versions/main/skylark/lib/File.html#is_source ✅
rules/framework.bzl
Outdated
@@ -159,22 +160,20 @@ def _get_virtual_framework_info(ctx, framework_files, compilation_context_fields | |||
# We need to map all the deps here - for both swift headers and others | |||
fw_dep_vfsoverlays = [] | |||
for dep in transitive_deps + deps: | |||
# Collect transitive headers. For now, this needs to include all of the | |||
# transitive headers | |||
if not CcInfo in dep: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why the order matters? Is it because an dep (except apple_framework_packaging targets) may return CcInfo, but won't return FrameworkInfo? Could we change it to something like
if CcInfo in dep:
...
if FrameworkInfo in dep:
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why the order matters?
The code has a continue
statement inside of the if block so it will skip ahead.
Could we change it to something like
I haven't tried that out yet but wouldn't be opposed to it. What are the benefits to changing the code to that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code has a continue statement inside of the if block so it will skip ahead.
I got that, but was wondering why we need the headers of imported frameworks.
What are the benefits to changing the code to that?
It might just be me, but the current logic is a little hard to understand. I had to know that if a dep doesn't return CcInfo, it won't return FrameworkInfo, either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got that, but was wondering why we need the headers of imported frameworks.
The point of this PR is so the headers for imported frameworks are included in upstream actions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also we may be better off just checking the providers like here https://github.com/bazel-ios/rules_ios/pull/333/files/5138482e5b1fcd470f76b793ef40e6ebc930cc73#r724580342 I don't believe there's exclusivity here but need to test it a bit more.
257397d
to
5138482
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for adding these! A few questions inline 🙏
--apple_platform_type=ios \ | ||
--deleted_packages='' \ | ||
-- //tests/ios/... \ | ||
-//tests/ios/frameworks/sources-with-prebuilt-binaries/... # Needs more work for pre-built binaries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What work? Maybe more details here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want to file an issue to see what is wrong with it? I don't have an idea about what to do ATM
# The input root is the part of the file usually rooted in bazel-out. | ||
# For starlark transitions output dirs are fingerprinted by the hash of the | ||
# relevant configuration keys. | ||
# src/main/java/com/google/devtools/build/lib/analysis/starlark/FunctionTransitionUtil.java |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thx for linking this 🙏
def _identical_outputs_test_impl(ctx): | ||
env = analysistest.begin(ctx) | ||
all_files = [] | ||
asserts.true(env, len(ctx.attr.deps) > 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why > 1
and not > 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test doesn't assert the problem to have 1 dev because it asserts identical outputs amongst multiple deps
https://github.com/bazel-ios/rules_ios/pull/333/files/5138482e5b1fcd470f76b793ef40e6ebc930cc73#diff-fa2c728306ed72d291b632ffa2b0458ea872ba83445c911667ac90ff0c4263a0R56
This is the only way to ensure that bazelbuild/bazel#12171 isn't happening internal to a rule!
# - adding apple_common.multi_arch_split to apple_framework.deps - #188 | ||
# - the transition yields the same result when used w/rules_apple - #196 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'd put the links here and not just the number #123
dep_headers = dep[CcInfo].compilation_context.headers.to_list() | ||
for dep_header in dep_headers: | ||
# Assert that all of the dep headers are in the target | ||
if not dep_header.extension == "h": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we care about .hh
or .hpp
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could by default have that and better expose this to the user to match other extensions if they'd like
@@ -95,6 +95,7 @@ def _get_framework_info_providers(ctx, old_cc_info, old_objc_provider): | |||
private_hdrs = [], | |||
has_swift = False, | |||
framework_name = imported_framework_name, | |||
extra_search_paths = imported_framework_name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra_search_paths
is an argument to the rule framework_vfs_overlay
so used internally of that rule
# Note: it is totally possible that a user would write a glob like this.. | ||
# srcs = glob([ | ||
# "sources/Basic/**/*.h", | ||
# ]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the ideal is to keep this as a note for someone trying to understand what is under test right? Why is it relevant to know that such a glob
could be written?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it is possible a user to craft an redundant build file which duplicates srcs
and framework_imports
- probably better to have the comment but I can remove it doesn't make sense. The rule will handle it anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with keeping it. Was just curious to know the details of the edge case you're mentioning here 👍
Co-authored-by: Thiago Cruz <thiago.hmcruz@gmail.com>
Co-authored-by: Thiago Cruz <thiago.hmcruz@gmail.com>
* Fix and assert swift imported header propagation This PR fixes a bug in swift compilation with imported framework transitive headers. Additionally it refactors the testing rules into a package that can be used with `rules_ios` or other repositories. These tests iclude existing tests for Bazel transitions being incorrect in `rules_ios` and the new generalized header test. The headers test allows a user to assert that tests are propagated to actions For cases: 1. add a frameworks directory to the app. This represents the case of `apple_framework.vendored_static_frameworks` which is commonly used as a way to import frameworks 2. test framework import under test-imports-app. Asserts transitive headers are loaded from TensorFlow.
This PR fixes a bug in swift compilation with imported framework
transitive headers. Additionally it refactors the testing rules into a
package that can be used with
rules_ios
or other repositories. Thesetests iclude existing tests for Bazel transitions being incorrect in
rules_ios
and the new generalized header test. The headers test allows a user to
assert that tests are propagated to actions
For cases:
add a frameworks directory to the app. This represents the case of
apple_framework.vendored_static_frameworks
which is commonly usedas a way to import frameworks
test framework import under test-imports-app. Asserts transitive headers
are loaded from TesnorFlow.