Skip to content

Header maps can lead to one pod leaking its headers to another pod #9248

Closed
@var-const

Description

Report

What did you do?

Created a Podfile that contains two pods that demonstrate the issue with headermaps.

What did you expect to happen?

Generate a workspace that can build successfully.

What happened instead?

Workspace is misconfigured and fails compilation.

CocoaPods Environment

Stack

   CocoaPods : 1.7.5
        Ruby : ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
    RubyGems : 2.5.2.3
        Host : Mac OS X 10.14.6 (18G87)
       Xcode : 11.0 (11M382q)
         Git : git version 2.19.0.605.g01d371f741-goog
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib
Repositories : 
               cpdc-internal-firebase - sso://cpdc-internal/firebase.git @ bad42bae72cd11ac27623442b07ea20636b2d466
               master - https://github.com/CocoaPods/Specs.git @ cfa26a9e1d7aa49bff716b2c7ad51790bbe515b0

Installation Source

[HeaderMapRepro.zip](https://github.com/CocoaPods/CocoaPods/files/3719989/HeaderMapRepro.zip)

Executable Path: /usr/local/Cellar/cocoapods/1.7.5/libexec/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.3.1
cocoapods-try         : 1.1.0

Podfile

platform :ios, '10.0'
inhibit_all_warnings!

target 'HeaderMapRepro' do
  use_frameworks!
  pod 'SVGKit'
  pod 'Firebase/Firestore'
end

Project that demonstrates the issue

HeaderMapRepro.zip

Freeform description

Under certain circumstances, pods might end up leaking headers into other pods.

The issue is that the generated Xcode workspace uses a header map that contains headers from all the pods. If two pods happen to contain a header with the same short name, the header map will only contain a single entry for that short name, so that one of the headers will "shadow" the other. This will lead to a broken build if one of the pods relies on the ability to import headers using just their short name.

In order for the issue to manifest, the following is necessary:

  • Pod A contains a header with a common name, e.g. util.h, and that header is part of its source_files in the podspec;
  • Pod B contains the header with the same short name, e.g. util.h;
  • Pod B uses header maps and includes util.h by its short name, e.g. by doing #import "util.h".

The results are:

  • In the generated workspace, pod B will use several header maps, among them Pod-B-project-headers.hmap which will contain entries for all the pods used in the project;
  • Pod-B-project-headers.hmap will only contain a single entry for util.h, which may be either the header from pod A or else the header from pod B (I presume it's effectively random which one ends up in the map);
  • If header map maps util.h to pod A, building pod B will fail upon trying to include a header from pod A.

The repro case is a simple Xcode project with a Podfile containing two pods that happen to trigger the issue. Using the names above, "Pod A" is FirebaseFirestore, and "Pod B" is SVGKit. Firestore contains a header named document.h, which leaks into SVGKit and shadows its own Document.h, leading to a build error. The generated header map looks like this.

I can confirm that running the failing compilation command from Xcode in command line will succeed if I remove -I flag that includes the problematic header map (SVGKit-project-headers.hmap).

Is it possible for CocoaPods to avoid generating the project-headers.hmap? It seems that because header maps essentially are unable to handle collisions, using a header map that contains entries for more than one pod is pretty much guaranteed to fail for some combinations of pods.

Our customers have recently encountered this issue in Firestore. I have found the exact same problem previously affecting React Native and Folly.

Please let me know if any additional information would be helpful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    s1:awaiting inputWaiting for input from the original author

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions