-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
Mac Catalyst patches #34026
Mac Catalyst patches #34026
Conversation
Base commit: d6c08bd |
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.
These look like exactly the compromise discussed in the road to 0.69 discussion - make it easy for people to do, but not enabled by default since side effects may break non-catalyst folks. Looks great to me from that perspective and is technically what I've been doing to get my catalyst builds to work. Nice!
Base commit: d6c08bd |
Hey @Arkkeeper - I followed some curiosity in a related thread and there may be a smaller / more minimal intervention for the DEAD_CODE_STRIPPING portion of this fix. You might try it, it appears to work based on success reports With apologies, I dug it up but have not tried it myself yet for the macCatalyst case... |
Code looks good to me. Thanks @mikehardy for cross-checking it. What I can say on the code itself, is that we've been moving a lot of our ruby code from |
@cortinico thanks for your comment, I've modified this PR according to it |
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.
Now looks even better to me :-)
@cortinico has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
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.
Hi @Arkkeeper, thanks a lot for your PR. Great work and thanks to the effort of supporting also Catalyst!
I apologise for the delay, but I was on PTO last week.
I left some comments and I suggested some changes to improve the code structure and the testing. Let me know what do you think about them!
firstTarget = prepare_target("FirstTarget") | ||
secondTarget = prepare_target("SecondTarget") | ||
thirdTarget = prepare_target("ThirdTarget") |
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.
firstTarget = prepare_target("FirstTarget") | |
secondTarget = prepare_target("SecondTarget") | |
thirdTarget = prepare_target("ThirdTarget") | |
first_target = prepare_target("FirstTarget") | |
second_target = prepare_target("SecondTarget") | |
third_target = prepare_target("ThirdTarget") |
[nit] let's stick to the snake_case for everything in Ruby. It is a personal preference, but mixing the cases makes it harder to collaborate.
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.
That's also regards test_fixLibrarySearchPaths_correctlySetsTheSearchPathsForAllProjects. I've renamed both of them.
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" | ||
target.build_configurations.each do |config| | ||
assert_equal(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"], "-") |
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.
These lines are replicating the logic of the fix. It is not really testing that the code executes correctly. For example, this test will pass also when "CODE_SIGN_IDENTITY[sdk=macosx*]"
is set to "-"
for all the target.
Can I suggest a different approach?
We already have the references to all the the targets (firstTarget
, secondTarget
, thirdTarget
). Why don't we assert the targets directly?
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.
Another thing that I don't think is correct: TargetMock
does not respond to :product_type
.
The TargetMock
class should be enhanced to have this property and the property must be set accordingly.
I'm pretty sure that this assert
is never really executed. Could you double check that, please?
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 are still executing the same logic in the tests.
How do you feel about asserting something like this:
first_target.build_configurations.each do |config|
assert_nil(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"])
end
second_target.build_configurations.each do |config|
assert_nil(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"])
end
third_target.build_configurations.each do |config|
assert_equal(assert_equal(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"], "-"))
end
?
In this way we don't replicate the logic but we assert on the expected outcome of the cod execution.
scripts/cocoapods/utils.rb
Outdated
config.build_settings['LIBRARY_SEARCH_PATHS'] = ['$(SDKROOT)/usr/lib/swift', '$(SDKROOT)/System/iOSSupport/usr/lib/swift', '$(inherited)'] | ||
end | ||
end | ||
aggregate_target.user_project.save |
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] Perhaps it is not idiomatic, but could we use save()
? We use the ()
everywhere else and it is better to be consistent.
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, our internal linter says that there are trailing whitespaces at this line. Can you remove them?
template/ios/Podfile
Outdated
@@ -33,5 +33,7 @@ target 'HelloWorld' do | |||
post_install do |installer| | |||
react_native_post_install(installer) | |||
__apply_Xcode_12_5_M1_post_install_workaround(installer) | |||
# Enable the next line in order to apply patches necessary for Mac Catalyst builds | |||
#__apply_mac_catalyst_patches(installer) |
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'll move the invocation of __apply_mac_catalyst_patches(installer)
inside the react_native_post_install
, actually removing the __apply_mac_catalyst_patches
. Given that not all the projects need these, we can update the react_native_post_install
function to accept a boolean apply_catalyst_patch
with a default value of false
.
The rationale here is that:
- it helps discoverability. At the end of the refactoring effort, the
react_native_pods
script will have only two function:use_react_native
andreact_native_post_install
. These will be documented and people will know about the existence of this flag. Otherwise, they have to read the whole script file to learn bout its existence. - it makes it easier for us to maintain the script. When, in the future, we will have to remove it, we could just delete all the code, and deprecate the flag. No other change will be required by the apps for a while, until we actually remove the flag.
Note that this change may foce you to also update the RNTester app.
How do you feel about this? Does it make sense?
end | ||
end | ||
end | ||
|
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.
Our internal linter says that there are trailing whitespaces at this line. Can you remove them?
end | ||
|
||
assert_equal(user_project_mock.save_invocation_count, 1) | ||
end |
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.
Our internal linter says that there are trailing whitespaces at this line. Can you remove them?
scripts/cocoapods/utils.rb
Outdated
config.build_settings['PRESERVE_DEAD_CODE_INITS_AND_TERMS'] = 'YES' | ||
# Modify library search paths | ||
config.build_settings['LIBRARY_SEARCH_PATHS'] = ['$(SDKROOT)/usr/lib/swift', '$(SDKROOT)/System/iOSSupport/usr/lib/swift', '$(inherited)'] | ||
end |
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.
Our internal linter says that there are trailing whitespaces at this line. Can you remove them?
@cipolleschi thank you for your proposals, I've tried to implement them all. |
Could you resolve the conflict on |
There seems to be an issue with the CI:
|
@cortinico has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
packages/rn-tester/Podfile
Outdated
@@ -21,6 +21,8 @@ def pods(options = {}, use_flipper: false) | |||
project 'RNTesterPods.xcodeproj' | |||
|
|||
fabric_enabled = true | |||
mac_catalyst_enabled = false |
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.
This line is not required! ;)
packages/rn-tester/Podfile
Outdated
@@ -66,6 +68,7 @@ target 'RNTesterIntegrationTests' do | |||
end | |||
|
|||
post_install do |installer| | |||
react_native_post_install(installer, @prefix_path) | |||
mac_catalyst_enabled = false | |||
react_native_post_install(installer, mac_catalyst_enabled, @prefix_path) |
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.
Instead of defining a variable, which I think is done just to have the name of the parameter for a code-as-documentation purpose, why don't we use named parameters from Ruby?
We can define a function with this syntax:
def foo(named_param: false)
end
and then invoke the function with this syntax:
foo(:named_param => true)
with this, we can emove the variable declaration and update this code as it follows:
react_native_post_install(installer, mac_catalyst_enabled, @prefix_path) | |
react_native_post_install(installer, @prefix_path, :mac_catalyst_enabled => false) |
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" | ||
target.build_configurations.each do |config| | ||
assert_equal(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"], "-") |
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 are still executing the same logic in the tests.
How do you feel about asserting something like this:
first_target.build_configurations.each do |config|
assert_nil(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"])
end
second_target.build_configurations.each do |config|
assert_nil(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"])
end
third_target.build_configurations.each do |config|
assert_equal(assert_equal(config.build_settings["CODE_SIGN_IDENTITY[sdk=macosx*]"], "-"))
end
?
In this way we don't replicate the logic but we assert on the expected outcome of the cod execution.
scripts/react_native_pods.rb
Outdated
if mac_catalyst_enabled | ||
ReactNativePodsUtils.apply_mac_catalyst_patches(installer) | ||
end |
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] We can use a conditional modifier here:
if mac_catalyst_enabled | |
ReactNativePodsUtils.apply_mac_catalyst_patches(installer) | |
end | |
ReactNativePodsUtils.apply_mac_catalyst_patches(installer) if mac_catalyst_enabled |
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 assume, the double assert_equal in third_target.build_configurations.each block is redundant, right?
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, sorry... bad copy-and-paste... 🤦
scripts/react_native_pods.rb
Outdated
@@ -141,7 +141,11 @@ def use_flipper!(versions = {}, configurations: ['Debug']) | |||
use_flipper_pods(versions, :configurations => configurations) | |||
end | |||
|
|||
def react_native_post_install(installer, react_native_path = "../node_modules/react-native") | |||
def react_native_post_install(installer, mac_catalyst_enabled, react_native_path = "../node_modules/react-native") |
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 would use a named parameter here, to have self-documenting code. What do you think?
def react_native_post_install(installer, mac_catalyst_enabled, react_native_path = "../node_modules/react-native") | |
def react_native_post_install(installer, react_native_path = "../node_modules/react-native", mac_catalyst_enabled: false) |
template/ios/Podfile
Outdated
mac_catalyst_enabled = false | ||
|
||
react_native_post_install(installer, mac_catalyst_enabled) |
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.
If we use the named parameter approach, we can avoid declaring the variable! ;)
Great job! 👏 I did another round of review, leaving also a couple of nitpicks, if you want to use them. I think that what we actually need to fix are the tests, because at the moment we are testing the code by knowing how it executes instead of trying to assert the final state of the system. What do you think? |
@cipolleschi thank you again for your comments and patience, I've commited the proposed edits. |
Thasnks a lot for the effort! 👏 Amazing job! :D |
@cortinico has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
This pull request was successfully merged by @Arkkeeper in 2fb6a33. When will my fix make it into a release? | Upcoming Releases |
A bit of a comment thread resurrection here but I just want to mention that I just got around to integrating this Only thing I can think of now is that it may make sense to also integrate one more build setting, but it's also an obvious one for developers. I do it like so in my script
|
Summary
This PR adds a new method called __apply_mac_catalyst_patches to scripts/react_native_pods.rb. If it is enabled in the Podfile, it will apply three patches necessary for successful building not only for iOS and tvOS targets, but also for macOS using Apple's Mac Catalyst technology.
These 3 patches are:
The details were discussed here reactwg/react-native-releases#21 (comment)
Changelog
[iOS] [Added] - Add Mac Catalyst compatibility (can be enabled in Podfile)
Test Plan
pod install
in ios directory