react-native-community / upgrade-support

A central community-backed place to request and give help when upgrading your app.
MIT License
258 stars 2 forks source link

Flipper shouldn't be included in Release builds #28

Closed javiercr closed 4 years ago

javiercr commented 4 years ago

Environment

npx react-native info
info Fetching system and libraries information...
System:
    OS: macOS Mojave 10.14.5
    CPU: (4) x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
    Memory: 270.57 MB / 16.00 GB
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 13.12.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /Users/javi/.rvm/gems/ruby-2.5.3/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.1, DriverKit 19.0, macOS 10.15, tvOS 13.0, watchOS 6.0
    Android SDK:
      API Levels: 23, 25, 26, 28
      Build Tools: 27.0.3, 28.0.2, 28.0.3, 29.0.0
      System Images: android-28 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5900203
    Xcode: 11.1/11A1027 - /usr/bin/xcodebuild
  Languages:
    Python: 2.7.16 - /usr/local/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0
    react-native: 0.62.0 => 0.62.0
  npmGlobalPackages:
    *react-native*: Not Found

Upgrading version

From 0.61.3 to 0.62.0

Description

After upgrading to 0.62, when we created our first iOS Release build, we noticed some warnings related to Flipper's pods such as:

⚠️  [redacted]]ios/Pods/Headers/Public/Flipper-Folly/folly/Memory.h:66:30: possible misuse of comma operator here [-Wcomma]
  return rc == 0 ? (errno = 0, ptr) : (errno = rc, nullptr);
    ^~~~~
⚠️  [redacted]]ios/Pods/Headers/Public/Flipper-Folly/folly/Memory.h:66:50: possible misuse of comma operator here [-Wcomma]
  return rc == 0 ? (errno = 0, ptr) : (errno = rc, nullptr);
              ^
⚠️  [redacted]]ios/Pods/Headers/Public/Flipper-Folly/folly/ScopeGuard.h:125:52: possible misuse of comma operator here [-Wcomma]
      auto catcher = []() -> R { warnAboutToCrash(), std::terminate(); };
              ^
⚠️  [redacted]]ios/Pods/Headers/Public/Flipper-Folly/folly/FBString.h:1879:72: possible misuse of comma operator here [-Wcomma]
                  "basic_fbstring: null pointer initializer not valid"),
                                 ^~~~~~~~~~~~~~~~~~
⚠️  [redacted]]ios/Pods/Headers/Public/Flipper-Folly/folly/Conv.h:1184:44: possible misuse of comma operator here [-Wcomma]
      [&](Tgt res) { return void(out = res), src; });
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Building library libFlipperKit.a

This made us wonder why is Flipper included in a build using the Release mode configuration. We've seen that the new Podfile template only includes the FlipperKit pods for the Debug build configuration:

def add_flipper_pods!
  version = '~> 0.33.1'
  pod 'FlipperKit', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitLayoutPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/SKIOSNetworkPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitUserDefaultsPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitReactPlugin', version, :configuration => 'Debug'
end

However the Cocoapods' docs notes that:

Note that transitive dependencies are included in all configurations and you have to manually specify build configurations for them as well in case this is not desired.

The pod Flipper-Folly is a dependency of Flipper, and Flipper seems to be dependency of FlipperKit/Core and FlipperKit/CppBridge.

Is this why it's being built and linked on Release build? Should add_flipper_pods! specify the Flipper and Flipper-Folly pods so that they get excluded from Release builds?

rickhanlonii commented 4 years ago

I thought that we had excluded this from release builds, but the only thing I can find is an open PR for Andorid. cc @passy @alloy https://github.com/facebook/react-native/pull/28257

alloy commented 4 years ago

Is this why it's being built and linked on Release build? Should add_flipper_pods! specify the Flipper and Flipper-Folly pods so that they get excluded from Release builds?

@javiercr Yup, looks like it, good catch. Mind sending a PR after verifying those changes work for you?

passy commented 4 years ago

Definitely shouldn't be included in release builds. We exclude it in Android release builds, too.

javiercr commented 4 years ago

Definitely shouldn't be included in release builds. We exclude it in Android release builds, too.

@passy do you mean it's already excluded for Android in the templates from RN 0.62 or that your team has excluded them for Android (making additional changes)?

@alloy I'll give it a try with a fresh project. I tried once yesterday but Flipper was still being included, but I suspect is because we had react-native-flipper and rn-redux-middleware-flipper in our package.json (and they may depend on Flipper's pod too).

passy commented 4 years ago

@javiercr Already excluded in 0.62. :)

ovy9086 commented 4 years ago

yes for android it's excluded as it's only specified as a debugImplementation dependency :

   debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
      exclude group:'com.facebook.fbjni'
    }
    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }
    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }
javiercr commented 4 years ago

@alloy I've created a new project, then added all transitive dependencies related to Flipper that I found in Podfile.lock to the add_fliper_pods! method:

def add_flipper_pods!
  version = '~> 0.33.1'
  pod 'FlipperKit', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitLayoutPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/SKIOSNetworkPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitUserDefaultsPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitReactPlugin', version, :configuration => 'Debug'

  # Exclude transitive dependencies from Release builds
  pod 'Flipper', version, :configuration => 'Debug'
  pod 'Flipper-DoubleConversion', '1.1.7', :configuration => 'Debug'
  pod 'Flipper-Folly', '~> 2.1', :configuration => 'Debug'
  pod 'Flipper-Glog', '0.3.6', :configuration => 'Debug'
  pod 'Flipper-PeerTalk', '~> 0.0.4', :configuration => 'Debug'
  pod 'Flipper-RSocket', '~> 1.0', :configuration => 'Debug'
  pod 'FlipperKit/Core', version, :configuration => 'Debug'
  pod 'FlipperKit/CppBridge', version, :configuration => 'Debug'
  pod 'FlipperKit/FBCxxFollyDynamicConvert', version, :configuration => 'Debug'
  pod 'FlipperKit/FBDefines', version, :configuration => 'Debug'
  pod 'FlipperKit/FKPortForwarding', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitHighlightOverlay', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitLayoutTextSearchable', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitNetworkPlugin', version, :configuration => 'Debug'
end

Then did cd ios && rm -rf Pods && pod install

However it seems Xcode is still building stuff the Flipper libraries:

image

I'm not an expert on cocoapods so I am not sure if the fact that these libraries are being build means that they're also included in the resulting Release build. Is that normal?

javiercr commented 4 years ago

I'm not an expert on cocoapods so I am not sure if the fact that these libraries are being build means that they're also included in the resulting Release build. Is that normal?

Answering myself from https://github.com/CocoaPods/CocoaPods/issues/9658#issuecomment-608261590

I do not think building can be avoided as the dependency is mapped on Xcode using the "Dependencies" section in Build Phases for each target.

I do not think Xcode supports dependencies per configuration.

The important bit is whether or not the dependency gets linked. If you have specified "Debug" and you see -framework MyDependency or-l MyDependency in the CocoaPods generated xcconfig for "Release" for that target then it is a bug in CocoaPods. Although this is very thoroughly tested.

Until cocoapods supports excluding transitive dependencies for a specific build configuration, from the React Native side I think the best we can do is try to list all Flipper dependencies in the Podfile, they will be still build for Release mode, but shouldn't be linked in the final IPA.

alloy commented 4 years ago

Until cocoapods supports excluding transitive dependencies for a specific build configuration, from the React Native side I think the best we can do is try to list all Flipper dependencies in the Podfile, they will be still build for Release mode, but shouldn't be linked in the final IPA.

Yup, that’s the important bit :+1:

Note that you can always verify this yourself by checking the built app binary with otool -L path/to/binary when using dynamic linking or listing the symbols with nm -a path/to/binary when using static linking.

alloy commented 4 years ago

To readers needing immediate support, make the following changes to your Podfile: https://github.com/facebook/react-native/pull/28504/commits/1c007d553cc71884952def921a15e7d088084854

nobodyabcd commented 4 years ago

To readers needing immediate support, make the following changes to your Podfile: facebook/react-native@1c007d5

I did what you suggested and rebuild everything from scratch.

However, I still seeing the flipper related libraries were included as part of the build.

As a workaround, i just commented out all flipper pod and rebuild..........

This is kind of annoying, and hopefully Cocapod would address it soon.....

alloy commented 4 years ago

@guanhuay Alas there is no way for CocoaPods to have control over this, as Xcode does not offer that ability.

javiercr commented 4 years ago

@guanhuay

I still seeing the flipper related libraries were included as part of the build.

If by these you mean you see Flipper libraries being build in the console logs, I'd say that's normal. See the comments in my merged PR:

Note that this will still build Flipper's pods when doing a Release, but it won't link it in the resulting IPA.

I hope we could get rid of Flipper during the build of a Release, as I have the feeling that iOS build have become much slower since the introduction of Flipper, but apparently that's not possible at the moment :/

nobodyabcd commented 4 years ago

@guanhuay

I still seeing the flipper related libraries were included as part of the build.

If by these you mean you see Flipper libraries being build in the console logs, I'd say that's normal. See the comments in my merged PR:

Note that this will still build Flipper's pods when doing a Release, but it won't link it in the resulting IPA.

I hope we could get rid of Flipper during the build of a Release, as I have the feeling that iOS build have become much slower since the introduction of Flipper, but apparently that's not possible at the moment :/

Hi Javier,

Thanks for your reply, based on your comment.

Even though flipper was built as part of the release, it just slow down the overall build time, but no flipper file would go into release artifact, right?

javiercr commented 4 years ago

Even though flipper was built as part of the release, it just slow down the overall build time, but no flipper file would go into release artifact, right?

As far as I know that's correct.

alloy commented 4 years ago

Aye, it is correct. You can check the LD flags in the xcconfig CocoaPods generates for your target/configuration to see the flipper libs are only included in the debug variant.

Osamasomy commented 3 years ago

I face the similar kind of problem in release mode and then I delete the release folder from ./android/app/src and after that run


cd ./android
./gradlew assembleRelease

and Got Success