I have a project with two targets A and B. Target A is an iOS app, target B is a dynamic iOS framework. Both targets need FirebaseAnalytics
dependency (which to my understanding is a static vendored library).
Have a correctly linked project where static dependencies of target B would be only present in target A's binary.
No matter how I try to add the dependency, there are always two possible outcomes. One is that it compiles and runs, but all symbols from FirebaseAnalytics are reported to be duplicates contained in both target A and B. If I manually change the target A's xcconfig file (generated by CocoaPods) and remove -framework FirebaseAnalytics
from OTHER_LDFLAGS
it seems to work as expected.
The other outcome are just No such module 'FirebaseAnalytics'
errors. That can be achieved by changing the Podfile to this:
platform :ios, '9.0'
use_frameworks!
abstract_target 'ProjectRoot' do
pod 'FirebaseAnalytics'
target 'SampleApp' do
pod 'AFNetworking'
end
target 'SampleFramework' do
inherit! :search_paths
pod 'CocoaLumberjack'
end
end
I tried both CocoaPods 1.3.1 and 1.4.0.beta.1. The following environment dump is from 1.3.1.
CocoaPods : 1.3.1
Ruby : ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
RubyGems : 2.6.7
Host : Mac OS X 10.12.6 (16G29)
Xcode : 9.0 (9A235)
Git : git version 2.13.5 (Apple Git-94)
Ruby lib dir : /Users/TadeasKriz/.rvm/rubies/ruby-2.2.1/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ 2aff79c74df623306725ab10122c62017088a5e3
Executable Path: /Users/TadeasKriz/.rvm/gems/ruby-2.2.1/bin/pod
cocoapods-acknowledgements : 1.0.0
cocoapods-clean : 0.0.1
cocoapods-deintegrate : 1.0.1
cocoapods-dependencies : 1.0.0
cocoapods-plugins : 1.0.0
cocoapods-release : 0.3.1
cocoapods-search : 1.0.0
cocoapods-stats : 1.0.0
cocoapods-superdeintegrate : 0.0.1
cocoapods-trunk : 1.2.0
cocoapods-try : 1.1.0
cocoapods-wholemodule : 0.0.1
platform :ios, '9.0'
use_frameworks!
target 'SampleApp' do
pod 'AFNetworking'
end
target 'SampleFramework' do
pod 'CocoaLumberjack'
pod 'FirebaseAnalytics'
end
I created a sample project to show this: https://github.com/TadeasKriz/CocoaPodsStaticDependencyError (it's based on @benasher44's https://github.com/benasher44/CocoaPodsLibExample).
FirebaseAnalytics is a static library framework and the iOS linker does not support static library dependencies for dynamic libraries.
One approach would be to make SampleFramework a static library framework as well with a CocoaPod static_framework with the feature introduced in 1.4.0 in #6811
@paulb777 Thanks for the info, I'll try to look for a way to use it differently.
Also, I made this stupid workaround, but it does seem to do the trick.
post_install do |installer|
installer.aggregate_targets.each do |aggregate_target|
if aggregate_target.name == 'Pods-SampleApp'
aggregate_target.xcconfigs.each do |config_name, config_file|
aggregate_target.pod_targets.each do |pod_target|
pod_target.specs.each do |spec|
if spec.attributes_hash['vendored_frameworks'] != nil or (spec.attributes_hash['ios'] != nil and spec.attributes_hash['ios']['vendored_frameworks'] != nil)
puts "Removing #{spec.name}"
config_file.frameworks.delete(spec.name)
end
end
end
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
end
@TadeasKriz you are the man, I was on the same issue since hours... Your workaround worked for me as I can build my app, thanks. I still have some warnings in the console but way less than before.
I didn't figure yet why:
objc[5193]: Class FIRClearcutWriter is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48160) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65cd0). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRClearcutAccountData is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e481b0) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65d20). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRClearcutRequest is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48200) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65d70). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRClearcutLogger is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48250) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65dc0). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRDiagnostics is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e482a0) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65e10). One of the two will be used. Which one is undefined.
objc[5193]: Class CLRPBClientInfo is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e482f0) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65e60). One of the two will be used. Which one is undefined.
objc[5193]: Class CLRPBIosClientInfo is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48340) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65eb0). One of the two will be used. Which one is undefined.
objc[5193]: Class CLRPBLogEvent is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48390) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65f00). One of the two will be used. Which one is undefined.
objc[5193]: Class CLRPBLogRequest is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e483e0) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65f50). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRPBErrorInfo is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48430) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor (0x102c65fa0). One of the two will be used. Which one is undefined.
objc[5193]: Class FIRPBICoreConfiguration is implemented in both /private/var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/Frameworks/BabysittorKit.framework/BabysittorKit (0x105e48480) and /var/containers/Bundle/Application/39FF9BB6-E9CC-4AEE-8173-CC3C1B3133C1/BabySittor.app/BabySittor
@TadeasKriz Be careful. The build error workaround is potentially pushing bugs to runtime where duplicate implementations can cause subtle incorrect behavior.
@paulb777 With this workaround I don't see any warnings about duplicate implementations. I'm not sure why @loryhuz does. I might have missed something to look for (maybe another property instead of vendored_frameworks).
My question is, if I get no warnings about duplicate implementations, do I have them? I thought that this workaround will tell the linker to not link static libraries to the iOS app target (leaving them linked only to the library). Is this assumption wrong? Thank you for your insight.
@paulb777 I've checked again, I still have like 3 warnings about duplicates (way way less than before and now the app started working as expected). I think that's because of the way I try to "detect" whether the library is static. Do you know any other way to tell if the dependency is a static library framework in the post_install
? Thanks.
I see it now. In some cases I'm removing wrong framework names. I need to remove them by the vendored framework name, not by the spec name.
@loryhuz I'll update the workaround in a few minutes. Still would love to find a better solution though.
@loryhuz New version of the workaround, this time you shouldn't see any warnings about duplicate symbols.
post_install do |installer|
installer.aggregate_targets.each do |aggregate_target|
puts aggregate_target.name
if aggregate_target.name == 'Pods-SampleApp'
aggregate_target.xcconfigs.each do |config_name, config_file|
aggregate_target.pod_targets.each do |pod_target|
pod_target.specs.each do |spec|
if spec.attributes_hash['ios'] != nil
frameworkPaths = spec.attributes_hash['ios']['vendored_frameworks']
else
frameworkPaths = spec.attributes_hash['vendored_frameworks']
end
if frameworkPaths != nil
frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
extension = File.extname filename
File.basename filename, extension
end
frameworkNames.each do |name|
puts "Removing #{name} from OTHER_LDFLAGS"
config_file.frameworks.delete(name)
end
end
end
end
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
end
@TadeasKriz Thanks for the help in this issue. This one seems more hard ! I can't compile with your new workaround, it's seems it's related to other static dependencies I have in my Podfile (like Facebook SDK), since I didn't see undefined symbols errors for Firebase:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_FBSDKClass", referenced from:
objc-class-ref in ViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What dependency is the FBSDKClass
from? My guess is they use vendored_frameworks
as well, but the framework is not a static library one, but dynamic.
I put this class as an example, but here is the full trace with real class names:
d: warning: Auto-Linking supplied '/Users/loryhuz/Documents/BabySittor/Pods/ZDCChat/ZDCChat.framework/ZDCChat', framework linker option at /Users/loryhuz/Documents/BabySittor/Pods/ZDCChat/ZDCChat.framework/ZDCChat is not a dylib
ld: warning: Auto-Linking supplied '/Users/loryhuz/Documents/BabySittor/Pods/ZDCChat/ZDCChatAPI.framework/ZDCChatAPI', framework linker option at /Users/loryhuz/Documents/BabySittor/Pods/ZDCChat/ZDCChatAPI.framework/ZDCChatAPI is not a dylib
ld: warning: Auto-Linking supplied '/Users/loryhuz/Documents/BabySittor/Pods/AccountKit/AccountKit.framework/AccountKit', framework linker option at /Users/loryhuz/Documents/BabySittor/Pods/AccountKit/AccountKit.framework/AccountKit is not a dylib
ld: warning: Auto-Linking supplied '/Users/loryhuz/Documents/BabySittor/Pods/Fabric/iOS/Fabric.framework/Fabric', framework linker option at /Users/loryhuz/Documents/BabySittor/Pods/Fabric/iOS/Fabric.framework/Fabric is not a dylib
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_ZDCRatingCell", referenced from:
objc-class-ref in SettingsViewController.o
"_OBJC_CLASS_$_ZDCVisitorChatCell", referenced from:
objc-class-ref in SettingsViewController.o
"_OBJC_CLASS_$_ZDCAgentChatCell", referenced from:
objc-class-ref in SettingsViewController.o
"_OBJC_CLASS_$_ZDCChat", referenced from:
objc-class-ref in SettingsViewController.o
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture arm64
And about this pod:
https://github.com/zendesk/zendesk_sdk_chat_ios
I didn't understand as I only reference it in my main app target, not in my Framework. I thought your post_install hook was only removing pod reference in the top of the file (abstract_target) to avoid duplicate but it's a total another stuff I guess ?
It was removing all of them. It's probably a good idea to somehow check if they are in the framework as well, that didn't occur to me before. Let me check that.
@loryhuz Alright, try this one:
post_install do |installer|
sharedLibrary = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-SampleFramework' }
installer.aggregate_targets.each do |aggregate_target|
if aggregate_target.name == 'Pods-SampleApp'
aggregate_target.xcconfigs.each do |config_name, config_file|
sharedLibraryPodTargets = sharedLibrary.pod_targets
aggregate_target.pod_targets.select { |pod_target| sharedLibraryPodTargets.include?(pod_target) }.each do |pod_target|
pod_target.specs.each do |spec|
frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || Set.new
frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
extension = File.extname filename
File.basename filename, extension
end
frameworkNames.each do |name|
puts "Removing #{name} from OTHER_LDFLAGS"
config_file.frameworks.delete(name)
end
end
end
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
end
@TadeasKriz Well done ! Console warnings completely disappeared now. I still have two linker warnings with this one:
ld: warning: Auto-Linking supplied 'xxx/Pods/Fabric/iOS/Fabric.framework/Fabric', framework linker option at xxx/BabySittor/Pods/Fabric/iOS/Fabric.framework/Fabric is not a dylib
ld: warning: Auto-Linking supplied 'xxx/Pods/AccountKit/AccountKit.framework/AccountKit', framework linker option at xxx/Pods/AccountKit/AccountKit.framework/AccountKit is not a dylib
Dunno why I got them
@loryhuz I have the exact same warning.
ld: warning: Auto-Linking supplied 'xxx/Pods/Fabric/iOS/Fabric.framework/Fabric', framework linker option at xxx/Pods/Fabric/iOS/Fabric.framework/Fabric is not a dylib
Here is my podfile:
platform :ios, '10.0'
use_frameworks!
target 'xxxCore' do
pod 'Fabric', '~> 1.6.13'
pod 'Crashlytics', '~> 3.8.6'
target 'xxx' do
inherit! :search_paths
end
end
Did you manage to fix this warning?
yes @adauguet follow the workaround script (post_install)
There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.
This issue will be auto-closed because there hasn't been any activity for a few months. Feel free to open a new one if you still experience this problem :+1:
Posting the workaround that I'm currently using in case it's helpful to anyone. This workaround uses the pre_install
hook instead of the post_install
hook. The issue occurs in the analyzer which runs before the pre_install
hook. So you only have to change one thing if you make the change there. Using the example from https://github.com/CocoaPods/CocoaPods/issues/7126#issue-264583808, add the following to your Podfile
.
pre_install do |installer|
embedded_target = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-SampleFramework' }
host_target = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-SampleApp' }
host_target.pod_targets = host_target.pod_targets - embedded_target.pod_targets
end
Please let me know if you notice any potential issues with my workaround.
Related issues:
@hongrich Hi
In the example below AFNetworking also will be removed, that's not right.
platform :ios, '9.0'
use_frameworks!
target 'SampleApp' do
pod 'AFNetworking'
end
target 'SampleFramework' do
pod 'CocoaLumberjack'
pod 'FirebaseAnalytics'
pod 'AFNetworking'
end
I get a lots of similar warning on app start.
I start with @TadeasKriz 's solution, but does not disappeared all of my warnings.
I want to use 'couchbase-lite-ios', '~> 1.4.1'
, this pod contains an CBLJSViewCompiler.a
file, what linked into my core lib, and into the main app.
A resolve it with edit @TadeasKriz 's code, with insert a remove for CBLJSViewCompiler.a
file bellow.
post_install do |installer|
sharedLibrary = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-SampleFramework' }
installer.aggregate_targets.each do |aggregate_target|
if aggregate_target.name == 'Pods-SampleApp'
aggregate_target.xcconfigs.each do |config_name, config_file|
sharedLibraryPodTargets = sharedLibrary.pod_targets
aggregate_target.pod_targets.select { |pod_target| sharedLibraryPodTargets.include?(pod_target) }.each do |pod_target|
pod_target.specs.each do |spec|
frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || Set.new
frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
extension = File.extname filename
File.basename filename, extension
end
frameworkNames.each do |name|
puts "Removing #{name} from OTHER_LDFLAGS"
config_file.frameworks.delete(name)
config_file.libraries.delete("CBLJSViewCompiler")#<- What I insert
end
end
end
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
end
@hongrich Hi,
I have dependencies like :
pod 'Firebase/Core'
pod 'FirebaseUI/Auth'
pod 'FirebaseUI/Google'
pod 'FirebaseUI/Facebook'
pod 'FirebaseUI/Phone'
pod 'Firebase/Storage'
pod 'FBSDKLoginKit'
and your workaround give me this error:
dyld: Library not loaded: @rpath/Bolts.framework/Bolts
Referenced from: /.../SampleFramework
Reason: image not found
Any idea?
I have a new version of the workaround. It works when some static libraries are only used in the Application target, but not in the library target. Still not sure if it's a good idea to use this, but at this time we don't have much else to try.
post_install do |installer|
applicationTargets = [
'Pods-SampleApp',
]
libraryTargets = [
'Pods-SampleLib',
]
embedded_targets = installer.aggregate_targets.select { |aggregate_target|
libraryTargets.include? aggregate_target.name
}
embedded_pod_targets = embedded_targets.flat_map { |embedded_target| embedded_target.pod_targets }
host_targets = installer.aggregate_targets.select { |aggregate_target|
applicationTargets.include? aggregate_target.name
}
# We only want to remove pods from Application targets, not libraries
host_targets.each do |host_target|
host_target.xcconfigs.each do |config_name, config_file|
host_target.pod_targets.each do |pod_target|
if embedded_pod_targets.include? pod_target
pod_target.specs.each do |spec|
if spec.attributes_hash['ios'] != nil
frameworkPaths = spec.attributes_hash['ios']['vendored_frameworks']
else
frameworkPaths = spec.attributes_hash['vendored_frameworks']
end
if frameworkPaths != nil
frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
extension = File.extname filename
File.basename filename, extension
end
frameworkNames.each do |name|
puts "Removing #{name} from OTHER_LDFLAGS of target #{host_target.name}"
config_file.frameworks.delete(name)
end
end
end
end
end
xcconfig_path = host_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
end
@TadeasKriz to implement this in my own project I assume I replace Pods-SampleApp
with my app name and Pods-SampleLib
with a library name and list all of them I want this to apply to?
I tried to insert the postinstall code, but I get:
[!] An error occurred while processing the post-install hook of the Podfile.
undefined method `build_configurations' for nil:NilClass
See also the next comment.
objc[99263]: Class PodsDummy_CocoaAsyncSocket is implemented in both /Users/user172615/Library/Developer/CoreSimulator/Devices/B4BCD2F3-8787-4F77-AA76-5DB45FA2EA7C/data/Containers/Bundle/Application/1E01783C-C884-4F5B-A253-28CF8E0E8C55/testProject.app/Frameworks/SquareReaderSDK.framework/SquareReaderSDK (0x110866c90) and /Users/user172615/Library/Developer/CoreSimulator/Devices/B4BCD2F3-8787-4F77-AA76-5DB45FA2EA7C/data/Containers/Bundle/Application/1E01783C-C884-4F5B-A253-28CF8E0E8C55/testProject.app/testProject (0x10c764238). One of the two will be used. Which one is undefined.
platform :ios, '11.1'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
def add_flipper_pods!(versions = {})
versions['Flipper'] ||= '~> 0.33.1'
versions['DoubleConversion'] ||= '1.1.7'
versions['Flipper-Folly'] ||= '~> 2.1'
versions['Flipper-Glog'] ||= '0.3.6'
versions['Flipper-PeerTalk'] ||= '~> 0.0.4'
versions['Flipper-RSocket'] ||= '~> 1.0'
pod 'FlipperKit', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitReactPlugin', versions['Flipper'], :configuration => 'Debug'
# List all transitive dependencies for FlipperKit pods
# to avoid them being linked in Release builds
pod 'Flipper', versions['Flipper'], :configuration => 'Debug'
pod 'Flipper-DoubleConversion', versions['DoubleConversion'], :configuration => 'Debug'
pod 'Flipper-Folly', versions['Flipper-Folly'], :configuration => 'Debug'
pod 'Flipper-Glog', versions['Flipper-Glog'], :configuration => 'Debug'
pod 'Flipper-PeerTalk', versions['Flipper-PeerTalk'], :configuration => 'Debug'
pod 'Flipper-RSocket', versions['Flipper-RSocket'], :configuration => 'Debug'
pod 'FlipperKit/Core', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/CppBridge', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBCxxFollyDynamicConvert', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBDefines', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FKPortForwarding', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitHighlightOverlay', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutTextSearchable', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
end
# Post Install processing for Flipper
def flipper_post_install(installer)
installer.pods_project.targets.each do |target|
if target.name == 'YogaKit'
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.1'
end
end
end
end
target 'testProject' do
# Pods for testProject
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React', :path => '../node_modules/react-native/'
pod 'React-Core', :path => '../node_modules/react-native/'
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
target 'testProjectTests' do
inherit! :complete
# Pods for testing
end
use_native_modules!
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable these next few lines.
add_flipper_pods!
post_install do |installer|
flipper_post_install(installer)
# ---------- start of change ------------
sharedLibrary = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-SquareReaderSDK' }
installer.aggregate_targets.each do |aggregate_target|
if aggregate_target.name == 'Pods-plumpPlym'
aggregate_target.xcconfigs.each do |config_name, config_file|
sharedLibraryPodTargets = sharedLibrary.pod_targets
aggregate_target.pod_targets.select { |pod_target| sharedLibraryPodTargets.include?(pod_target) }.each do |pod_target|
pod_target.specs.each do |spec|
frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || Set.new
frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
extension = File.extname filename
File.basename filename, extension
end
end
frameworkNames.each do |name|
if name != 'SquareReaderSDK'
raise("Script is trying to remove unwanted flags: #{name}. Check it out!")
end
puts "Removing #{name} from OTHER_LDFLAGS"
config_file.frameworks.delete(name)
end
end
end
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
# ---------- end of change ------------
end
end
target 'testProject-tvOS' do
# Pods for testProject-tvOS
target 'testProject-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end
The following is another trial, following the code example in https://stackoverflow.com/a/52773670/5532513:
platform :ios, '11.1'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
def add_flipper_pods!(versions = {})
versions['Flipper'] ||= '~> 0.33.1'
versions['DoubleConversion'] ||= '1.1.7'
versions['Flipper-Folly'] ||= '~> 2.1'
versions['Flipper-Glog'] ||= '0.3.6'
versions['Flipper-PeerTalk'] ||= '~> 0.0.4'
versions['Flipper-RSocket'] ||= '~> 1.0'
pod 'FlipperKit', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitReactPlugin', versions['Flipper'], :configuration => 'Debug'
# List all transitive dependencies for FlipperKit pods
# to avoid them being linked in Release builds
pod 'Flipper', versions['Flipper'], :configuration => 'Debug'
pod 'Flipper-DoubleConversion', versions['DoubleConversion'], :configuration => 'Debug'
pod 'Flipper-Folly', versions['Flipper-Folly'], :configuration => 'Debug'
pod 'Flipper-Glog', versions['Flipper-Glog'], :configuration => 'Debug'
pod 'Flipper-PeerTalk', versions['Flipper-PeerTalk'], :configuration => 'Debug'
pod 'Flipper-RSocket', versions['Flipper-RSocket'], :configuration => 'Debug'
pod 'FlipperKit/Core', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/CppBridge', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBCxxFollyDynamicConvert', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FBDefines', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FKPortForwarding', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitHighlightOverlay', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitLayoutTextSearchable', versions['Flipper'], :configuration => 'Debug'
pod 'FlipperKit/FlipperKitNetworkPlugin', versions['Flipper'], :configuration => 'Debug'
end
# Post Install processing for Flipper
def flipper_post_install(installer)
installer.pods_project.targets.each do |target|
if target.name == 'YogaKit'
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.1'
end
end
end
end
target 'testProject' do
# Pods for testProject
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React', :path => '../node_modules/react-native/'
pod 'React-Core', :path => '../node_modules/react-native/'
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
target 'testProjectTests' do
inherit! :complete
# Pods for testing
end
use_native_modules!
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable these next few lines.
add_flipper_pods!
post_install do |installer|
flipper_post_install(installer)
# ---------- start of change ------------
# you should change the sample auto_process_target method call to fit your project
# sample for the question
auto_process_target('testProject', 'SquareReaderSDK', installer)
# sample for the multi app use on same framework
#auto_process_target(['exampleiOSApp', 'exampleMacApp'], 'exampleFramework', installer)
end
# the below code no need to modify
def auto_process_target(app_target_names, embedded_target_name, installer)
words = find_words_at_embedded_target('Pods-' + embedded_target_name,
installer)
handle_app_targets(app_target_names.map{ |str| 'Pods-' + str },
words,
installer)
end
def find_line_with_start(str, start)
str.each_line do |line|
if line.start_with?(start)
return line
end
end
return nil
end
def remove_words(str, words)
new_str = str
words.each do |word|
new_str = new_str.sub(word, '')
end
return new_str
end
def find_words_at_embedded_target(target_name, installer)
target = installer.pods_project.targets.find { |target| target.name == target_name }
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")
if old_line == nil
next
end
words = old_line.split(' ').select{ |str| str.start_with?("-l") }.map{ |str| ' ' + str }
return words
end
end
def handle_app_targets(names, words, installer)
installer.pods_project.targets.each do |target|
if names.index(target.name) == nil
next
end
puts "Updating #{target.name} OTHER_LDFLAGS"
target.build_configurations.each do |config|
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")
if old_line == nil
next
end
new_line = remove_words(old_line, words)
new_xcconfig = xcconfig.sub(old_line, new_line)
File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
end
end
end
# ---------- end of change ------------
end
target 'testProject-tvOS' do
# Pods for testProject-tvOS
target 'testProject-tvOSTests' do
inherit! :search_paths
# Pods for testing
end
end
@rahamin1
Please try to change the
auto_process_target('testProject', 'SquareReaderSDK', installer)
to
auto_process_target(['testProject'], 'SquareReaderSDK', installer)
The main target should be an array.
@bestwnh Thanks! Missed that...
I see now that I am getting an error for something else:
undefined method
build_configurations' for nil:NilClass...`
Any idea what I am missing?
@rahamin1 It looks like the target name is incorrect. Maybe because your SquareReaderSDK
is not import by CocoaPods? You can try to replace all two 'Pods-'
to ''
. It make the script no longer auto change the SquareReaderSDK
to Pods-SquareReaderSDK
.
You can also check the .xcconfig file to confirm the target name. The information is in my blog post link of the answer in stackoverflow.
@bestwnh can you send me an email? I would like to ask you something in an email...
_yossi.[email protected]_
Regarding the name of the pod (SquareReaderSDK), there is no such pod...
The installation process for this package (https://bit.ly/3d4SPA3) doesn't use cocoapods...
objc[7955]: Class PodsDummy_CocoaAsyncSocket is implemented in both /Users/user172615/Library/Developer/CoreSimulator/Devices/B4BCD2F3-8787-4F77-AA76-5DB45FA2EA7C/data/Containers/Bundle/Application/36574EF1-2F18-444B-B47B-F9FEA43DC7BE/plumpPlum.app/Frameworks/SquareReaderSDK.framework/SquareReaderSDK (0x10ed07c90) and /Users/user172615/Library/Developer/CoreSimulator/Devices/B4BCD2F3-8787-4F77-AA76-5DB45FA2EA7C/data/Containers/Bundle/Application/36574EF1-2F18-444B-B47B-F9FEA43DC7BE/plumpPlum.app/plumpPlum (0x10ac05238). One of the two will be used. Which one is undefined.
I have uploaded a sample repo that demonstrates the problem to https://github.com/rahamin1/duplicate
Most helpful comment
I have a new version of the workaround. It works when some static libraries are only used in the Application target, but not in the library target. Still not sure if it's a good idea to use this, but at this time we don't have much else to try.