Cocoapods: Framework user targets cannot depend on xcframeworks

Created on 6 Feb 2020  ·  28Comments  ·  Source: CocoaPods/CocoaPods

Report

What did you do?

pod install or pod update

What did you expect to happen?

Install all xcframework pod dependencies correctly even in the subproject

What happened instead?

subprojects are not able to build cause of used xcframework dependencies

CocoaPods Environment

Stack

   CocoaPods : 1.9.0.beta.3
        Ruby : ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]
    RubyGems : 3.0.3
        Host : Mac OS X 10.15.4 (19E224g)
       Xcode : 11.3.1 (11C504)
         Git : git version 2.21.1 (Apple Git-122.3)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib
Repositories : infor-scm-xos-cocoapodsspecs - git - http://git.infor.com/scm/xos/cocoapodsspecs.git @ 4ae4508215b41033b8b43a4fc94ddc50272f9ca8

               infor-scm-xos-cocoapodsspecs-1 - git - https://git.infor.com/scm/xos/cocoapodsspecs.git @ 4c0a507c59b2ee6732179ab68056eb6c8d4996e2

               master - git - https://github.com/CocoaPods/Specs.git @ bc2bf5a3549403c0039035c481dd6c3bf9d0dfd3

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

cocoapods-clean       : 0.0.1
cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.4.0
cocoapods-try         : 1.1.0

Podfile

platform :ios, '11.0'

source 'https://myPrivatePods.com/scm/xos/cocoapodsspecs.git'
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!
use_modular_headers!

workspace 'Application'

target 'FrameworkSubproject' do
  project 'Internal Frameworks/FrameworkSubproject'
  pod 'XCFRAMEWORK', '~> x.y.z'
end

target 'Application' do
    project 'Application.xcodeproj'

    pod 'XCFRAMEWORK', '~> x.y.z'
end

Project that demonstrates the issue

just use whatever project that has any subproject and try to add dependency to any xcframework in this subproject

What I've observerd: the subprojects don't have [CP] Prepare Artifacts Build Phase and corresponding input files. When I tried to manually copy this script from main app project (and adjusting paths) to problematic subproject the issue was solved. So I would either expect that [CP] Prepare Artifacts is created also for all subprojects that uses Pods or the [CP] Prepare Artifacts in main project somehow take care also about those subprojects?

xcframeworks defect

Most helpful comment

1.10.1 still have this problem

All 28 comments

Hello, similar problem here. I'm trying to put xcframework into another framework project and after installing pod with xcframework as vendored_frameworks it doesnt have [CP] Prepare Artifacts and throws me errors that cant find path. The same pod is working on single page app without any problems

Likely a bug. Anyone able to whip up a sample project that demonstrates this?

If you need a dummy .xcframework I can upload one here

@amorde I can create a sample tomorrow if needed. If you already have any dummy xcframework ideally put it to publicly accessible pods repository from which I can reference it.

See attached two samples. First one is demonstrating issue after fresh pod update, second one contains manually copied artifacts input and output files plus there is added [CP] Prepare Artifacts Build phase. (note I've also updated paths and added subpath in artifacts.sh ARTIFACT_LIST_FILE property)

PodsXCSampleWoArtifacts.zip
PodsXCSampleWManuallyCopiedAndAdjustedArtifacts.zip

Awesome, thanks! Will look into it

@amorde any news on that?

I looked into this briefly and saw that the target is a framework target - frameworks can't embed their own frameworks, they need to be embedded into a containing target (ex. an app) and _linked_. There might be an issue with the linking here but that's as far as I got before switching to another issue

I looked into this briefly and saw that the target is a framework target - frameworks can't embed their own frameworks, they need to be embedded into a containing target (ex. an app) and _linked_. There might be an issue with the linking here but that's as far as I got before switching to another issue

@amorde: we are just linking our framework subproject with other framework from pods. Not embedding. Only app is embedding all required frameworks.

The reason I mentioned embedding is that the Prepare Artifacts is currently used as a setup step before embed frameworks. That said, I think user framework targets that are using CocoaPods might need the Prepare Artifacts script as well, otherwise Xcode won't have the correct slice of the framework to link.

@amorde Do we have any solution for this now?

I don't unfortunately

@amorde Hope you are looking into this. Do we have any beta version for this?

No, there isn't a fix yet as I haven't had time to dedicate to it.

PRs are welcomed! I work on CocoaPods during my free time, and have already spent a significant amount of time implementing XCFrameworks (including giving up weekends). Help would be appreciated 👍

@amorde Is there a slack for the CocoaPods community where discussion could be had? I'm wondering if there is an easy way to exclude xcframework's from the aggregate targets.

It seems like when CocoaPods includes an XCFramework, it includes all architectures in the "framework search paths". This is confusing Xcode and it tries to link with the wrong version of the framework.

I tried "manually" adding the XCFramework to my project, and Xcode seems to handle it correctly if you list the XCFramework directly in the list of files to link (under the Build Phases tab).

So, I think if I can get CocoaPods to link with xcframeworks directly rather than via the aggregate targets, that might fix the bug.

An alternative solution would be if there is a build environment variable for the appropriate architecture (ie, ios-arm64 and ios-x86_64-simulator) that could be used to include only the correct architecture in the framework search path.

Yes, this is a bit of a hack because there's no way to tell Xcode to "look for headers in this xcframework" without using each directory.

The short version of why CocoaPods doesn't just use the Link Binary with Libraries build phase in Xcode is because CocoaPods supports dependencies whitelisted by configuration:

pod 'MyPod', :configurations => ['Debug']

and Xcode doesn't support this natively, so we end up re-implementing a lot of Xcode's logic in scripts to support this feature. We've considered dropping support for that for pods with XCFrameworks but haven't pulled the trigger yet.

Given that, I'm open to suggestions on how to improve this, but I wasn't able to get this working without using the FRAMEWORK_SEARCH_PATHS hack that you mentioned. The "slice" of the framework to pick depends on the architecture as well as the "variant" which is either simulator, maccatalyst, or empty. You can see the logic for that here:

https://github.com/CocoaPods/CocoaPods/blob/778fe350d65c2646e978de68830c55d8fa4b931d/lib/cocoapods/generator/prepare_artifacts_script.rb#L132-L153

We might be able to hack together something using $(ARCHS) but I don't know if EFFECTIVE_PLATFORM_NAME etc. are available as build settings.

There's some more context here as to why it ended up how it did and what Xcode does under the hood.

@icecrystal23 if you're on Twitter, DM me (@_amorde) your email and I can invite you to Slack

I manually updated the generated xcconfig files to replace the duplicated search paths per arch with ios-${CURRENT_ARCH} and that seems to be working. I haven't found a good variable for the "ios" portion yet.

EFFECTIVE_PLATFORM_NAME appears to be "-iphoneos" so that doesn't help.

Update: This works for device, but not simulator. That needs -simulator...

@icecrystal23 Hi, did you solve this issue ?

I did not, unfortunately, and then other work priorities came up.

Working on this now, planning to rework some of this stuff to fix this + some other issues

Really appreciate your work Eric. I was thinking about finding some time for it, but weekends are mostly reserved for kid in my case.

Hi @amorde, shall that work with CocoaPods version 1.9.3?
In commit log I see: amorde: Rework XCFramework support to use a script at the pod level instead o… … dcd166c which I guess shall fix also this issue.
But when I was testing it I got same error.

Hi @amorde: any update on this one? Shall it work in 1.9.3 as I was asking above?

That change wasn’t released in 1.9.3, it will be included with 1.10

@amorde: Thanks for clarification

1.10.1 still have this problem

Was this page helpful?
0 / 5 - 0 ratings