Description
- [ x ] I've read and understood the CONTRIBUTING guidelines and have done my best effort to follow.
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
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 itssource_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 forutil.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