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

use_frameworks! results in pod not finding headers of its dependencies #4605

Closed
jcanizales opened this issue Nov 29, 2015 · 58 comments
Closed
Labels
s1:awaiting input Waiting for input from the original author s4:awaiting validation A Pull Request that is waiting for validation by a CocoaPods Core Team member

Comments

@jcanizales
Copy link

Hi,

I have a pod A that depends on pod B. Both are C libraries. Pod B (which I don't own) has a directory structure like this:

/include/something/*.h
/src/<*.c and *.h, sometimes in nested dirs>

Includes are expected to be of this form #include <something/header1.h>, so B's podspec has:

s.public_header_files = 'include/something/*.h'
s.header_mappings_dir = 'include'

Without use_frameworks!, this works alright, because include/something gets put into the public headers folder with the appropriate links, and that folder is added to the search path. If the user sets use_frameworks! in his Podfile, though, the public headers links aren't created, nor added to the search paths, and thus compiling pod A fails.

I inspected the framework created for Pod B, and the headers are all flattened (there's no something directory inside). Changing #include <something/header1.h> into #include <B/header1.h> doesn't work for three reasons:

  • It breaks the library if not using frameworks.
  • It fails to build anyway because the generated B-umbrella.h header in the framework imports UIKit, which can't be built within a C library.
  • Some of the headers of library B use the form #include <something/header1.h>.

Manually copying Pods/Headers/Public from a pod install without use_frameworks!, and adding "$(PODS_ROOT)/Headers/Public/B" to the search headers path of target A makes everything work again. Because I can't tell people to do the copying manually, I have to resort to the hack of adding "$(PODS_ROOT)/Headers/Private/B" (private!) to the headers search path in A's podspec, which works, but is all sorts of wrong.

Note: This also happens when both pods are Objective-C, except the generated umbrella header can import UIKit alright in that case.

Thanks a lot for your hard work!

@segiddins
Copy link
Member

Can you share a project we can use to debug this? Thanks!

@jcanizales
Copy link
Author

I've put four projects here that can be used to replicate the issue. It's the same toy app, varying whether it's written in Swift or ObjC, and whether the Podfile uses frameworks or not. They need git submodule --init update after cloning the repo.

While creating them I've realized there's no need of a pod that depends on another pod to replicate the issue, so I've simplified the case by just having the app depend on two pods, one in C and another in ObjC. Both pods work as static libraries, but fail as dynamic frameworks (no matter the language of the app).

@jcanizales
Copy link
Author

Hi Samuel, are you able to replicate the issue?

@segiddins
Copy link
Member

I've been busy with other things recently, but hopefully someone from the team will be able to investigate soon -- otherwise, we always accept PRs!

@jcanizales
Copy link
Author

I'd be very happy to grab a book on Ruby and contribute; Cocoapods has been extremely useful to our users and us. But the problem is I don't know how this should be solved: IIRC, removing the public headers under Pods/ in the case of use_frameworks! was a conscious decision.

Maybe module maps can be used to solve this? I'd need to get refreshed on them to be able and tell.

@balumusic2012
Copy link

how to Assign a captured image path to next view controller's UiimageView.
How can we get the total image data from stored image path to next view
controllers UIImageView?

On Sun, Nov 29, 2015 at 8:41 AM, Samuel E. Giddins <notifications@github.com

wrote:

Can you share a project we can use to debug this? Thanks!


Reply to this email directly or view it on GitHub
#4605 (comment)
.

@balumusic2012
Copy link

how to Assign a captured image path to next view controller's UiimageView.
How can we get the total image data from stored image path to next view
controllers UIImageView?

On Tue, Dec 8, 2015 at 1:18 PM, Bala Bhaskar balumusic2012@gmail.com
wrote:

how to Assign a captured image path to next view controller's UiimageView.
How can we get the total image data from stored image path to next view
controllers UIImageView?

On Sun, Nov 29, 2015 at 8:41 AM, Samuel E. Giddins <
notifications@github.com> wrote:

Can you share a project we can use to debug this? Thanks!


Reply to this email directly or view it on GitHub
#4605 (comment)
.

@master-nevi
Copy link

Any updates on this?

@nikolay-kapustin
Copy link

For a new beta 1.0.0b also applicable.

@jcanizales
Copy link
Author

I've investigated it and it seems the problem can be solved by not generating the "Headers" (formerly "Copy Headers") build phase for the created targets, and not failing to create the Pods/Headers/Public directories.

I'm going to update the projects I linked above to reproduce the issue and, if those two measures solve it, I can try to make the changes in Cocoapods (although I'll need all the guidance in the world for that).

@matti777
Copy link

matti777 commented Mar 1, 2016

I'm facing the same issue, trying to build a Swift app using 'pod gRPC' as I need to use use_frameworks!.

Any ideas? I've spent the last few hours trying to build the grpc + dependencies into the project as source, but that is proving equally painful.

@matti777
Copy link

matti777 commented Mar 2, 2016

In the meanwhile I solved this by writing a shell script (which resides in the project root) that creates symlinks for the missing headers:

cd Pods/Headers/Private
ln -s BoringSSL/openssl/

for f in Protobuf/*.h
do
    ln -s $f
done

cd gRPC
ln -s ../Protobuf/google/

And also added a post_install hook to Podfile:

post_install do | installer |
  print "Running post_install hook to create symlinks..\n"
  system './create_symlinks.sh'
end

This is a "works for me" -solution, sure, but who knows, it or something similar might even work for You too.

@jcanizales
Copy link
Author

Thanks for the report, Matti. To help me when I tackle this, can you check what version of Cocoapods you used?

@matti777
Copy link

The latest stable as of today, cannot remember the version any more since I already updated to 1.0.0-b6 which does the same thing.

Trying to build gRPC stack as a part of a Swift app using CocoaPods + use_frameworks!, basically.

EDIT: the versions tried were:

  • 0.39.0
  • 1.0.0.beta.6 (this one does not even create the header structure under Pods/Headers/Private)

@CapnSpellcheck
Copy link

Is there any update on this? I'm experiencing an issue on 0.39.0 where header for pod A are going entirely into Pods/Headers/Private, but that pod has public headers, and I'm developing pod B and now I really need to import an A header.

@atsepkov
Copy link

I too am experiencing this issue. It seemed to be fine in 0.39, at least until I specified an exact commit to pull for one of the libraries I was using. In the process I updated to 1.0.0.beta.6 and now my Pods/Headers directory is empty, removing use_frameworks! allows the directory to be populated, but as for others, breaks all Swift libraries. I've described the issue in more detail on Stack Overflow: http://stackoverflow.com/questions/36507504/pods-headers-empty-after-pod-install

@BenchR267
Copy link

Removing use_frameworks! is not really a solution :/

@jcanizales
Copy link
Author

@timburks this is the issue.

@mfronczyk
Copy link

mfronczyk commented Apr 23, 2016

@matti777 I have a similar issue when trying to push my pod based on gRPC and I wanted to try your workaround, but I'm not sure where to execute the ./create_symlinks.sh during the build because I don't have Podfile, but Podspec, which doesn't have post_install. Can you help? My Podspec:

Pod::Spec.new do |s|
  s.name     = 'TestServiceApi'
  s.version  = '0.0.1'
  s.authors  = 'Michal Fronczyk
  s.homepage = 'https://bitbucket.org/jurand/milliongame-service-api-objc'
  s.summary  = 'gRPC test'
  s.license  = '...'
  s.source   = { :git => 'https://jurand@bitbucket.org/jurand/milliongame-service-api-objc.git', :branch => 'master' }

  s.ios.deployment_target = '8.0'
  s.osx.deployment_target = '10.9'

  # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
  # You can run this command manually if you later change your protos and need to regenerate.
  s.prepare_command = "protoc --objc_out=. --objcgrpc_out=. *.proto"

  # The --objc_out plugin generates a pair of .pbobjc.h/.pbobjc.m files for each .proto file.
  s.subspec "Messages" do |ms|
    ms.source_files = "*.pbobjc.{h,m}"
    ms.header_mappings_dir = "."
    ms.requires_arc = false
    ms.dependency "Protobuf", "~> 3.0.0-beta-2"
  end

  # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with
  # a service defined.
  s.subspec "Services" do |ss|
    ss.source_files = "*.pbrpc.{h,m}"
    ss.header_mappings_dir = "."
    ss.requires_arc = true
    ss.dependency "gRPC", "~> 0.12"
    ss.dependency "#{s.name}/Messages"
  end
end

Solution can be found here - grpc/grpc#6275 (comment)

@dkharrat
Copy link

I'm seeing this issue too after upgrading to CocoaPods 1.0 (from 0.39.0), specifically for pod 'CocoaLumberjack/Swift' (I'm using a Swift project). The directive #import <CocoaLumberjack/CocoaLumberjack.h> does not work anymore. CocoaPods 0.39.0 did not have this issue. Seems like the difference between the two versions is that 0.39.0 generates the Pods/Headers/Private/... headers, whereas 1.0.0 does not.

It this a regression in 1.0?

@k06a
Copy link

k06a commented May 23, 2016

Have the same issue with project created with pod lib create on 0.39.0. Test target can not find header:

.../Example/Tests/Tests.m:10:9: 'MyLib/MyLib.h' file not found

Here is project: https://github.com/k06a/DeluxeInjection/tree/feature/imperative
Tests can be compiled and passed if no use_frameworks! used, but gives a compilation error when use_frameworks! option is turned on.

@k06a
Copy link

k06a commented May 23, 2016

Looks like this happens when pod lib create without example project, but with tests.

@prestonj
Copy link

prestonj commented Jun 8, 2016

I'm encountering the same problem in CocoaPods 1.0.0 and 1.0.1.

EDIT -- actually this problem exists in 0.39 too. My solution was to add to the xcconfig in the podspec as mentioned above (but also including all the potential platform variants that might exist:

  spec.xcconfig = {
    'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/BrainCloudCpp/include"'
  }

Sadly I also had to do the same to another CocoaPod (BrainCloud) that depends on this one (BrainCloudCpp).

@texassiga
Copy link

After installing the CocoaPods. I saw a "Pods_appName" under Linked Frameworks and Libraries section. This is causing the build to fail. I am seeing following error "ld: framework not found Pods_appName". Removing this solves the problem but I don't understand this completely to decide if removing it is a good thing.

@CodeLife2012
Copy link

Any update?

@Skelzor
Copy link

Skelzor commented Jan 4, 2017

A good workaround for me was to use Carthage for the Swift-Frameworks - it's much easier than to add all frameworks by yourself. But keep the possible problems in mind: StackOverflow

@javache
Copy link

javache commented Jan 26, 2017

We've split the react-native podspec into multiple podspecs and this is affecting us as well: facebook/react-native#11781

The issue here seems to be that when use_frameworks is enabled we no longer create separate targets for every subspec but instead merge everything in one big target. This ignores any header_dir settings in subspecs.

To support frameworks, could we consider keeping the targets as-they-are but adding a framework target on top of that links the other static libraries?

@alloy
Copy link
Member

alloy commented Jan 27, 2017

As shown here https://github.com/facebook/react-native/pull/12089/files#diff-66230b3e029caa37b0fbdc8cbd47f4abR50, you can add a header search path to make this work.

@jcanizales
Copy link
Author

@muxi: Per @alloy's fix, it looks like @dnkoutso's variable (of #6037) is already available, and we can undo our workarounds as commented in that PR?

@muxi
Copy link

muxi commented Jan 29, 2017

Actually I am starting with it. The original way seems to be not working for now. I will update.

@sketch34
Copy link

sketch34 commented Feb 10, 2017

Thanks for everyone's efforts in solving this issue. As a relative newcomer to cocoapods I'm having some trouble following this thread and understanding if:

a) There is a recommended workaround or fix? or...
b) Do I need to switch to a different system altogether like Carthage?
c) Is it possible to roll back to the previous cocoapods version 0.39.0 which worked?

I've just returned to a Swift project that I put on ice for a few months and this is blocking me after upgrading to the version recommended by the pod terminal.

pod --version = 1.1.1, was using 0.39.0.

Cheers all.

@pankkor
Copy link

pankkor commented Apr 26, 2017

any updates?

@DavidKuennen
Copy link

It's so sad that this is still not working. I was using CocoaPods just to include GoogleMaps and everything was broken afterwards.

@aaronbuchanan
Copy link

samesies @DavidKuennen

@segiddins
Copy link
Member

It's so sad that this is still not working. I was using CocoaPods just to include GoogleMaps and everything was broken afterwards

This is open source. Complaining that something doesn't work perfectly is unproductive, and the most likely outcome is that you will de-motivate anyone on the team who otherwise would've looked at addressing the issue. If the issue is indeed critical for you, you're welcome to contribute a pull request that attempts to fix it, and I'm sure the team would be more than happy to review one, but merely commenting that you wish something had been done does not come off as appreciative for the project that is free for you to use.

Just my 2¢

@crontab
Copy link

crontab commented Jun 28, 2017

Having tried everything above... what worked for me eventually:

Use the YourApp.xcworkspace file generated by cocoapds, not the YourApp.xcodeproj

This way the project file for Pods frameworks will be included and built too, and the headers will become available to your app.

@stale
Copy link

stale bot commented Sep 26, 2017

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.

@stale
Copy link

stale bot commented Oct 3, 2017

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 👍

@n8r0n
Copy link

n8r0n commented Mar 24, 2018

I realize not everyone will want to go this route, but in a project I had control over the source code in, I worked around this problem by just removing the contents of the Bridging Header, and instead, in the Swift code that used my pods (which previously were #imported in the Bridging Header), I had an "Import LibName" that needed to be added in each .swift file.

See:
http://www.innerexception.com/2015/05/cocoapods-useframeworks-means-bridging.html

@matti777
Copy link

I notice this issue is still open. :) I am now using the following setup - in my FooService.podspec I have:

  s.pod_target_xcconfig = {
    # This is needed by all pods that depend on Protobuf:
    "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1",
    # This is needed by all pods that depend on gRPC-RxLibrary:
    "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES" => "YES",

    "USE_HEADERMAP" => "NO",
    "ALWAYS_SEARCH_USER_PATHS" => "NO",
    "USER_HEADER_SEARCH_PATHS" => "$(PODS_ROOT)/FooService",
    "HEADER_SEARCH_PATHS" => "$(PODS_ROOT)/FooService"
  }

And in the user target (the app using the gRPC pod) I simply add a User Header Search Path:

$(PODS_ROOT)/FooService

Still hacky.

  • M

@heistings
Copy link

Any updates?

@fggeraissate
Copy link

fggeraissate commented Dec 20, 2019

As shown here https://github.com/facebook/react-native/pull/12089/files#diff-66230b3e029caa37b0fbdc8cbd47f4abR50, you can add a header search path to make this work.

@alloy This solution works for me 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
s1:awaiting input Waiting for input from the original author s4:awaiting validation A Pull Request that is waiting for validation by a CocoaPods Core Team member
Projects
None yet
Development

No branches or pull requests