Cocoapods: Multiple Targets - linker command failed with exit code 1

Created on 27 Sep 2017  路  8Comments  路  Source: CocoaPods/CocoaPods

Report

What did you do?

Set up targets in Podfile as follows:

target 'Views' do
    pod 'RxCocoa'
    pod 'RxDataSources'
    pod 'RxSwift'
    pod 'SlackTextViewController'
end
target 'Engine' do
    pod 'Branch'
    pod 'GooglePlaces'
    pod 'RealmSwift'
    pod 'RxCocoa'
    pod 'RxSwift'
end

Within the Views framework I made sure that the SlackTextViewController use is private and not exposed.
The Engine frame links to the Views target, but shouldn't require SlackTextViewController for anything.

What did you expect to happen?

Engine compiles because the publicly exposed interface of Views uses types known to the framework.

What happened instead?

Engine compilation fails with the error:

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

CocoaPods Environment

Stack

   CocoaPods : 1.3.1
        Ruby : ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]
    RubyGems : 2.0.14.1
        Host : Mac OS X 10.12.6 (16G29)
       Xcode : 9.0 (9A235)
         Git : git version 2.13.5 (Apple Git-94)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ d5ece662b6639444a80a41c63d3ed5f793460a5d
               officeserve-pods - https://github.com/OfficeServe/ios-podspecs.git @ f3d4e07afee12073c9a236031d8b3c4d16eb6e3b

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

cocoapods-deintegrate : 1.0.1
cocoapods-playgrounds : 1.2.2
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.0.0
cocoapods-trunk       : 1.2.0
cocoapods-try         : 1.1.0

Podfile

platform :ios, '9.0'
use_frameworks!

# ignore all warnings from all pods
inhibit_all_warnings!

target 'Hypit' do
    pod 'Alamofire'
    pod 'AlamofireImage', '~> 3.1'
    pod 'Argo'
    pod 'Auth0', '~> 1.0'
    pod 'Branch'
    pod 'Crashlytics'
    pod 'Curry'
    pod 'Fabric'
    pod 'GooglePlaces'
    pod 'Lock', '~> 2.0'
    pod 'Instabug', '~> 7.0'
    pod 'Interpolate'
    pod 'OneSignal'
    pod 'Mixpanel-swift'
    pod 'Pulley', '1.3.0'
    pod 'RealmSwift'
    pod 'RxCocoa'
    pod 'RxDataSources'
    pod 'RxRealm'
    pod 'RxSwift'
    pod 'SlackTextViewController'
    pod 'SwiftyUserDefaults'
        pod 'TTTAttributedLabel'
end

target 'Core' do
    pod 'Alamofire'
    pod 'Auth0', '~> 1.0'
    pod 'Mixpanel-swift'
    pod 'OneSignal'
    pod 'RealmSwift'
    pod 'RxCocoa'
    pod 'RxSwift'
    pod 'SwiftyUserDefaults'
end

target 'ViewModels' do
    pod 'RxCocoa'
end

target 'Views' do
    pod 'RxCocoa'
    pod 'RxDataSources'
    pod 'RxSwift'
    pod 'SlackTextViewController'
end

target 'Routing' do
    # Realm is only a dependency because Core exposes Realm objects
    # In the future Core should be refactored to expose immutable value types
    pod 'RealmSwift'
    pod 'RxCocoa'
    pod 'RxSwift'
end

target 'Service' do
  pod 'RxCocoa'
  pod 'RxSwift'
end

target 'Engine' do
    # Realm is only a dependency because Core exposes Realm objects
    # In the future Core should be refactored to expose immutable value types
    pod 'Branch'
    pod 'GooglePlaces'
    pod 'RealmSwift'
    pod 'RxCocoa'
    pod 'RxSwift'
end

target 'OneSignalNotificationServiceExtension' do
  pod 'OneSignal'
end

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '3.0'
        end
    end

    installer.pods_project.build_configurations.each { |bc|
        bc.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
    }
end

Sample Project Demonstrating Issue

Project can be found here: https://www.dropbox.com/sh/2vzfs5s4pvxsztr/AAACccj9QJB_-RmP8-jX1gUCa?dl=0

moderate confirmed defect

Most helpful comment

@dnkoutso You're a hero. It's been a really positive experience to have you working with me on this issue and taking it seriously. I really appreciate the time you've spent looking into this. 馃槃

All 8 comments

Can you please attach a sample project? You are halfway there with the detailed Podfile and report you provided

I'm trying and failing to reproduce this in a sample project. Once I succeed I will post it here.

@dnkoutso I have updated with a sample project.

@Infinity-James hm interesting case. I am trying to see if you are supposed to be hiding the "SlackTextViewController" framework.

There is no such built-in functionality in CocoaPods to do that but I am still investigating how to achieve it.

@Infinity-James in other words I think we are looking for a feature enhancement here or perhaps the use of a post_install hook to mark the framework as private.

I believe CocoaPods would be improved with the ability to establish these real boundaries as to the frameworks to which a target links. A 'fix' for the error is to add pod SlackTextViewController to the target in the Podfile. However, this clutters the targets imports and is disingenuous. I can maintain the boundaries in a 'soft' manner by simply never importing SlackTextViewController, but having it compiled with the target is lame.

@Infinity-James I find out why this happens. The CONFIGURATION_BUILD_DIR for each pod is setup as $PODS_CONFIGURATION_BUILD_DIR/<name>. This causes the output artifact to be inside a subfolder within derived data.

When Xcode reaches the link phase of 'Engine' it looks into a few standard paths on where the produced frameworks are to find them. Since SlackTextViewController.framework is present inside a subfolder, Xcode does not find it.

Try it in your sample project and copy the SlackTextViewController.framework into the root derived data folder and rebuild, it succeeds for me.

You may fix this by providing a post_install hook to update your project to look into other paths for pre-built frameworks although I do not know the exact setting Xcode uses to find those frameworks by default.

In the meantime we could be fixing this for CocoaPods so I am marking it as confirmed and medium bug.

@dnkoutso You're a hero. It's been a really positive experience to have you working with me on this issue and taking it seriously. I really appreciate the time you've spent looking into this. 馃槃

Was this page helpful?
0 / 5 - 0 ratings