Skip to content
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

XCFrameworks slice selection fails in multiple ways #10026

Closed
1 task done
lowip opened this issue Sep 2, 2020 · 18 comments
Closed
1 task done

XCFrameworks slice selection fails in multiple ways #10026

lowip opened this issue Sep 2, 2020 · 18 comments
Labels
r:xcframeworks Related to the support for XCFrameworks t2:defect These are known bugs. The issue should also contain steps to reproduce. PRs welcome!
Milestone

Comments

@lowip
Copy link
Contributor

lowip commented Sep 2, 2020

Report

What did you do?

Integrating a pod distributed as a xcframework.

What did you expect to happen?

The xcframework pod to be handled properly by Cocoapods and for the target to compile without errors.

What happened instead?

The shell script generated by copy_xcframework_script.rb does not handle all xcframeworks correctly.

Example 1

Given the following xcframework:

SampleXCFramework.xcframework
├── Info.plist
├── ios-arm64
│   └── SampleXCFramework.framework
│       └── ...
└── ios-arm64_x86_64-simulator
    └── SampleXCFramework.framework
        └── ...

When compiling on a device or using the Any iOS Device destination. The pod's copy_xcframework_script.rb will select the simulator slice instead of the device slice.

Screen Shot 2020-09-02 at 2 13 57 PM

This leads to the following compilation error on the target:

Building for iOS, but linking in dylib file (.../SampleXCFramework.framework/SampleXCFramework) built for iOS Simulator, file '.../SampleXCFramework.framework/SampleXCFramework' for architecture arm64

Example 2

Given the following xcframework:

AppboyKit.xcframework
├── Info.plist
├── ios-arm64_armv7
│   ├── Headers
│   │   └── ...
│   └── libAppboyKitLibrary.a
└── ios-arm64_i386_x86_64-simulator
    ├── Headers
    │   └── ...
    └── libAppboyKitLibrary.a

When compiling on a device or using the Any iOS Device destination. The pod's copy_xcframework_script.rb will fail to select a slice in the xcframework:

[CP] Unable to find matching .xcframework slice in '.../AppboyKit.xcframework AppboyKit library ios-arm64_i386_x86_64-simulator ios-arm64_armv7' for the current build architectures (armv7 arm64).

As you can see, the slice ios-arm64_armv7 contains all the architectures needed (armv7 arm64). The script fails to select this slice due to the following regex:

# This regex matches all possible variants of the arch in the folder name:
# Let's say the folder name is: ios-armv7_armv7s_arm64_arm64e/CoconutLib.framework
# We match the following: -armv7_, _armv7s_, _arm64_ and _arm64e/.
# If we have a specific variant: ios-i386_x86_64-simulator/CoconutLib.framework
# We match the following: -i386_ and _x86_64-
local target_arch_regex="[_\-]${target_arch}[\/_\-]"

That regex fails to match the target architecture in the string ios-arm64_armv7. A possible fix for that regex is:

"[_\-]${target_arch}([\/_\-]|$)"

Notes

In both examples, the xcframeworks were:

  • generated using Xcode 12 beta 6
  • tested and work correctly when integrated manually into an Xcode project

CocoaPods Environment

Stack

   CocoaPods : 1.10.0.beta.2
        Ruby : ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin19]
    RubyGems : 3.0.1
        Host : Mac OS X 10.15.6 (19G2021)
       Xcode : 12.0 (12A8189n)
         Git : git version 2.28.0
Ruby lib dir : /Users/louis.bur/.rbenv/versions/2.6.1/lib
Repositories : cocoapods - git - https://github.com/CocoaPods/Specs.git @ a73178d31cff733dba361b7b9332648ff995121d

               trunk - CDN - https://cdn.cocoapods.org/

Installation Source

Executable Path: /Users/louis.bur/.rbenv/versions/2.6.1/bin/pod

Plugins

cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.4.1
cocoapods-try         : 1.1.0

Podfile

platform :ios, '14.0'
project 'SampleApp.xcodeproj'

target :SampleApp do
  pod 'SampleXCFramework', :path => './'
end

Project that demonstrates the issue

Example 1 - SampleXCFramework.zip
Example 2 - AppboyKit.xcframework.zip

@dnkoutso
Copy link
Contributor

dnkoutso commented Sep 2, 2020

Yes! great issue report. If we need to update the regex care to open a PR for it? Target branch 1-10-stable so it ships with 1.10.x

@dnkoutso dnkoutso added this to the 1.10.0 milestone Sep 2, 2020
@dnkoutso dnkoutso added the t2:defect These are known bugs. The issue should also contain steps to reproduce. PRs welcome! label Sep 2, 2020
@dnkoutso
Copy link
Contributor

dnkoutso commented Sep 2, 2020

@lowip also would be awesome to expand our test surface area with the sample xcframeworks to ensure no regressions.

@lowip
Copy link
Contributor Author

lowip commented Sep 2, 2020

@dnkoutso I'm preparing a PR.

@dnkoutso
Copy link
Contributor

This was merged.

@trevinwisaksana
Copy link

trevinwisaksana commented Dec 1, 2020

I believe this bug or at least a variation of it might still be occurring. I'm getting a build issue only on my Development configuration because Cocoapods is selecting the wrong slice of the XCFramework. This prevents me from building for a simulator but it works normally when building for a device.

Screen Shot 2020-12-01 at 09 07 38

It correctly selected the correct slice at first as shown on the logs. But then notice that it's still looking for the x86_64 architecture in the ios-arm64_armv7 folder.
missing required architecture x86_64 in file Pods/Crisp/Crisp.xcframework/ios-arm64_armv7/Crisp.framework/Crisp (2 slices)

I'm using Xcode 12.2 and Cocoapods 1.10 to generate this.

@perrosnk
Copy link

@trevinwisaksana Did you find a solution to that?

@ManueGE
Copy link

ManueGE commented Dec 18, 2020

@perrosnk

My solution was adding this to the bottom of the Podfile

xcframeworks = ['PodName1', 'PodName2']  # pods which are xcframeworks

post_install do |installer|
      installer.pods_project.targets.each do |target|
            if xcframeworks.include? target.name
                target.build_configurations.each do |config|
                    config.build_settings['ARCHS'] = ["$(ARCHS_STANDARD)", "i386", "x86_64"]
                end
            end
      end
 end

@perrosnk
Copy link

@ManueGE did you add this to post_install do |installer| or pre_install do |installer|?
Thank you very much

@ManueGE
Copy link

ManueGE commented Dec 18, 2020

@perrosnk post_install. Updated my answer.

@perrosnk
Copy link

perrosnk commented Dec 18, 2020

@ManueGE Thank you very much for your help. Unfortunately it doesn't work for me. It seems that xcode still tries to use the ios slice (instead of ios-simulator) of the XCFrameworks that doesn't contain the x86_64 architecture. I have no idea why that is the case!

@trevinwisaksana
Copy link

@trevinwisaksana Did you find a solution to that?

I haven't found a long term solution to this. But I found a stop gap one by deleting the ios-arm64_armv7 folder in the ExampleFramework.xcframework folder when building for a simulator. You can find it in the Pods folder of your project. However, you need to pod deintegrate and pod install if you want to archive or build for a device. Yes, this is annoying and not ideal. But if you need a quick solution this works

@banane
Copy link

banane commented Jan 10, 2021

I'm having a similar issue- on CircleCi/remote, it's building for simulator all the time, never for device. Locally, it builds for device, but on CircleCI, it builds for simulator. I see the warning, and the failure (when try to verify on upload with app store). This is Plaid/LinkKit xc framework.

@tplester
Copy link

@trevinwisaksana I had this same issue with the AppCenter Cocoapod today. I fixed it by removing an recursive path ($(SRCROOT)/**) from the Framework Search Path in the target (though it could also be in the project) Build Settings.

The recursive path was causing XCode to add every folder into the Link step including (incorrectly) the architecture folders inside of the xcframework, and using those paths it would find the wrong architecture framework. You can tell if this is the case by looking at the Link step log
image
for paths similar to this:

-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_i386_x86_64-simulator
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_x86_64-maccatalyst
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64_x86_64-simulator

@trevinwisaksana
Copy link

@tplester it works! Thank you so much for this!

@m1entus
Copy link

m1entus commented Apr 1, 2021

If you still facing this issue i had to exclude arm64 from build settings like this:

if target.name == "AgoraRtcEngine_iOS"
        config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end

@markus-mohemian
Copy link

@trevinwisaksana I had this same issue with the AppCenter Cocoapod today. I fixed it by removing an recursive path ($(SRCROOT)/**) from the Framework Search Path in the target (though it could also be in the project) Build Settings.

The recursive path was causing XCode to add every folder into the Link step including (incorrectly) the architecture folders inside of the xcframework, and using those paths it would find the wrong architecture framework. You can tell if this is the case by looking at the Link step log
image
for paths similar to this:

-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_i386_x86_64-simulator
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_x86_64-maccatalyst
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64_x86_64-simulator

Saved my day! Big thanks. Turned out that I recursively added all folders in my entire project to search paths. 🙈

@Tibbs
Copy link

Tibbs commented Jul 16, 2021

@trevinwisaksana I had this same issue with the AppCenter Cocoapod today. I fixed it by removing an recursive path ($(SRCROOT)/**) from the Framework Search Path in the target (though it could also be in the project) Build Settings.

The recursive path was causing XCode to add every folder into the Link step including (incorrectly) the architecture folders inside of the xcframework, and using those paths it would find the wrong architecture framework. You can tell if this is the case by looking at the Link step log
image
for paths similar to this:

-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_i386_x86_64-simulator
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_x86_64-maccatalyst
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64_x86_64-simulator

@markus-mohemian Thank you very much for sharing this
I have been struggling with this issue for months. I was only able to test my apps on a device. One of my projects had the error and none of the solutions I found online worked. I deleted $(SRCROOT) from the projects Framework Search Path and now it works perfectly.

@herbertvuijk
Copy link

herbertvuijk commented Sep 4, 2023

@trevinwisaksana I had this same issue with the AppCenter Cocoapod today. I fixed it by removing an recursive path ($(SRCROOT)/**) from the Framework Search Path in the target (though it could also be in the project) Build Settings.

The recursive path was causing XCode to add every folder into the Link step including (incorrectly) the architecture folders inside of the xcframework, and using those paths it would find the wrong architecture framework. You can tell if this is the case by looking at the Link step log image for paths similar to this:

-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_arm64e_armv7_armv7s
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_i386_x86_64-simulator
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/ios-arm64_x86_64-maccatalyst
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/macos-arm64_x86_64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64
-FPods/AppCenter/AppCenter-SDK-Apple/AppCenter.xcframework/tvos-arm64_x86_64-simulator

@markus-mohemian
OMG. Thank you so much. I've have been looking for a solution for 2 days, didn't even know how to Google the problem. Those scary moments we all know when you Google an error and you barely find any hits, feeling you are the first one having this issue, expect excluding arm64 architecture which is not what I want (I'm on an M1) and didn't even work either.

I found out if I removed the ios arm 64 slice, it would finally pick the simulator one. After i realized this I could google the problem better (chat GPT was of NO help). You saved my day! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
r:xcframeworks Related to the support for XCFrameworks t2:defect These are known bugs. The issue should also contain steps to reproduce. PRs welcome!
Projects
None yet
Development

No branches or pull requests