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

Failure to include .xcframework from private pod repo #9601

Closed
jongarate opened this issue Mar 9, 2020 · 9 comments
Closed

Failure to include .xcframework from private pod repo #9601

jongarate opened this issue Mar 9, 2020 · 9 comments
Labels
r:xcframeworks Related to the support for XCFrameworks s6:need sample Needs a sample project that reproduces the issue

Comments

@jongarate
Copy link

Report

What did you do?

Hosted an XCFramework library in a private Artifactory repository with the following filesystem layout:

MyBundle-X.Y.Z
├── MyBundle.podspec
└── MyBundle.xcframework
    ├── Info.plist
    ├── ios-arm64
    │   └── MyBundle.framework
    │       ├── Headers
    │       │   ├── A.h
    │       │   ├── B.h
    │       │   ├── C.h
    │       │   └── MyBundle.h
    │       ├── Info.plist
    │       ├── Modules
    │       │   └── module.modulemap
    │       ├── MyBundle
    │       └── _CodeSignature
    │           └── CodeResources
    └── ios-x86_64-simulator
        └── MyBundle.framework
            ├── Headers
            │   ├── A.h
            │   ├── B.h
            │   ├── C.h
            │   └── MyBundle.h
            ├── Info.plist
            ├── Modules
            │   └── module.modulemap
            ├── MyBundle
            └── _CodeSignature
                └── CodeResources

The .podspec file looks like this:

Pod::Spec.new do |s|
  s.name           = 'MyBundle'
  s.version        = 'X.Y.Z'
  s.author         = { 'John Doe' => 'johndoe@example.com' }
  s.source         = { :path => '.' }
  s.platform       = :ios
  s.license      = {
    :type => 'Comercial',
    :text => "blah, blah, blah..."
  }

  s.frameworks     = 'CoreBluetooth'
  s.vendored_frameworks = 'MyBundle.xcframework'
  s.compiler_flags = '-ObjC'
end

And the consuming project file's Podfile looks like this:

plugin 'cocoapods-art', :sources => [
    'private-cocoapods-repo'
]
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!
# Inhibit warnings from Pods project
# https://stackoverflow.com/questions/44034057/xcode-dont-display-warnings-from-cocoapods-pods
inhibit_all_warnings!

# My Bundle version
$myBundleVersion = 'X.Y.Z'

abstract_target 'Base' do
    platform :ios, '10.0'

    # Other general dependencies go here

    abstract_target 'App' do
    
        # Other specific dependencies go here

        target 'My App' do
            pod 'MyBundle', $myBundleVersion
        end
        target 'My AppTests'
    end
end

Upon adding the repo and executing pod install everything seems to run fine.

What did you expect to happen?

I expected the App project to compile without further issues and the library to be working within it.

What happened instead?

The compiler fails with the following output:

ld: framework not found MyBundle
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The layout within the App project looks like this (Pods -> Pods/):

MyBundle
├── Frameworks
│   └── MyBundle.xcframework
└── Support Files
    ├── MyBundle.debug.xcconfig
    └── MyBundle.release.xcconfig

When checking the Pod project status within XCode, I noticed that MyBundle.debug.xcconfig file looks like this:

APPLICATION_EXTENSION_API_ONLY = YES
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MyBundle
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/MyBundle" "${PODS_ROOT}/MyBundle/MyBundle.xcframework/ios-arm64" "${PODS_ROOT}/MyBundle/MyBundle.xcframework/ios-x86_64-simulator"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_LDFLAGS = $(inherited) -framework "CoreBluetooth"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/MyBundle
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

Also note that this very XCFramework works fine when included by hand in the App project.

CocoaPods Environment

XCode is version 11.3.1

/Users/developer/.cocoapods/repos-art/private-cocoapods-repo/.artpodrc

Stack

   CocoaPods : 1.9.0
        Ruby : ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin19]
    RubyGems : 3.0.6
        Host : Mac OS X 10.15.3 (19D76)
       Xcode : 11.3.1 (11C504)
         Git : git version 2.21.1 (Apple Git-122.3)
Ruby lib dir : /Users/developer/.rvm/rubies/ruby-2.6.3/lib
Repositories : cocoapods - git - https://github.com/CocoaPods/Specs.git @ 9de799d63b36a9142ac3a1b54080d1bf1f60c0cd

               private-cocoapods-repo - file system

Installation Source

Executable Path: /Users/developer/.rvm/gems/ruby-2.6.3/bin/pod

Plugins

cocoapods-art         : 1.0.4
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
@dnkoutso
Copy link
Contributor

dnkoutso commented Mar 9, 2020

maybe @amorde has some more insight here

@amorde
Copy link
Member

amorde commented Mar 9, 2020

Everything looks fine given the info provided - might be hard to troubleshoot without a sample.

Couple questions:

  • Does MyBundle contain any compiled sources? (looks like no, but double checking)
  • Does this fail before the Prepare Artifacts script runs? If not, did the script print any warnings?

@amorde amorde added the r:xcframeworks Related to the support for XCFrameworks label Mar 9, 2020
@dnkoutso dnkoutso added the s1:awaiting input Waiting for input from the original author label Mar 9, 2020
@jongarate
Copy link
Author

Thanks for such a quick response.

I'll try to answer both your questions first @amorde and then provide some additional insight.

Does MyBundle contain any compiled sources? (looks like no, but double checking)

It's an Objective-C based library, provided in binary form and adhering to CLang/LLVM interfaces to ease adoption in both modern Objective-C and Swift consumers. module.modulemap makes this possible.

Does this fail before the Prepare Artifacts script runs? If not, did the script print any warnings?

Digging further on this I'm noticing an odd situation. Let me first provide a more accurate context regarding the Podfile. The actual Podfile also contains a Today Extension (aka Widget) which I stripped for clarity reasons:

abstract_target 'Base' do
    platform :ios, '10.0'

    # Other general dependencies go here

    target 'My Extension' do
        pod 'MyBundle', $myBundleVersion
    end

    abstract_target 'App' do
    
        # Other specific dependencies go here

        target 'My App' do
            pod 'MyBundle', $myBundleVersion
        end
        target 'My AppTests'
    end
end

Under this scheme, the extension target sits inside a Dependency in the Build Phases page of XCode (which btw is the topmost entry in this tab).

When performing the build using fastlane (2.137.0), looks to me as if this dependency isn't linked until Prepare Artifacts is performed, which results in a successful build. However, when performing the build using XCode, an attempt to link this extension is made before Prepare Artifacts is triggered (which would actually honor Build Phases's order of events), which fails.

I also noticed that the target of the extension doesn't display a Prepare Artifacts build phase on its own.

  • Is this App+Extension arrangement perhaps unsupported? Am I missing something else in the Podfile?
  • Could this be related to somehow XCode using a different build system than fastlane?

@stale stale bot removed the s1:awaiting input Waiting for input from the original author label Mar 10, 2020
@amorde
Copy link
Member

amorde commented Mar 10, 2020

Hmm, it could definitely be related to the extension, but I'm fairly certain watchOS extensions are working (based on #9575).

1.9.1 was just released, can you update and try it out?

If 1.9.1 still doesn't work then there might be something related to #9525

@jongarate
Copy link
Author

I've been making more tests and I think I can further expand on this.

As always, first some additional context. In all the previous comments I've talked about MyBundle.xcframework as a single entity, but it's actually slightly more complicated than this. The actual Podfile looks something like this:

abstract_target 'Base' do
    platform :ios, '10.0'

    # Other general dependencies go here

    target 'My Extension' do
        pod 'MyBundle', $myBundleVersion
    end

    target 'My Extension Debug' do
        pod 'MyBundleDebug', $myBundleVersion
    end

    abstract_target 'App' do
    
        # Other specific dependencies go here

        target 'My App' do
            pod 'MyBundle', $myBundleVersion
        end
        target 'My App Debug' do
            pod 'MyBundleDebug', $myBundleVersion
        end
        target 'My AppTests'
    end
end

The idea here is to have two "flavors" of MyBundle, the Debug one having additional logging verbosity (since Cocoapods doesn't support flavors as such, to the best of my knowledge). In the fastlane case I mentioned previously, It's successfully compiling the regular My App scheme, while in the failing case I was compiling the Debug scheme using XCode. If the regular scheme is compiled in XCode, it also runs successfully.

Taking a look at #9525, my findings resemble quite closely to what this colleague mentions.

@amorde
Copy link
Member

amorde commented Mar 11, 2020

Sorry I'm having a hard time following this - would it be possible to create a sample project that reproduces the issue?

If you need a dummy .xcframework, you can use the one we use for tests here: https://github.com/CocoaPods/cocoapods-integration-specs/tree/master/install_vendored_xcframework/before/BananaLib/CoconutLib.xcframework

@dnkoutso dnkoutso added s6:need sample Needs a sample project that reproduces the issue s1:awaiting input Waiting for input from the original author labels Mar 11, 2020
@jongarate
Copy link
Author

Since the main reason to use Cocoapods was to ease the workflow for an internal project, we decided to resort to copying the XCFramework files directly to the project until some more convenient solution can be arranged (SwiftPM binary support?).

Unfortunately I don't have enough time right now to build a sample project with all the correct details.

Thanks to everyone involved in this issue.

@stale stale bot removed the s1:awaiting input Waiting for input from the original author label Mar 12, 2020
@dnkoutso
Copy link
Contributor

Seems like a good plan! Should we close this?

@dnkoutso dnkoutso added the s1:awaiting input Waiting for input from the original author label Mar 12, 2020
@jongarate
Copy link
Author

It's fine for me. Go ahead.

@stale stale bot removed the s1:awaiting input Waiting for input from the original author label Mar 13, 2020
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 s6:need sample Needs a sample project that reproduces the issue
Projects
None yet
Development

No branches or pull requests

3 participants