CodeBender CodeBender - 11 months ago 93
C++ Question

A C++ header file in a CocoaPod is unable to import from a framework

My situation involves a privately developed CocoaPod that contains the OpenCV framework, as well as a wrapper and interface file for working with it. This design is intended to simplify cross-platform sharing for our other apps.

Here is a somewhat crude diagram showing the pieces:

opencv2.framework -> c++ interface file -> objective-c wrapper -> application

If I take the first three pieces, and place them directly in the target application, everything works as intended. However, we lose the ability to easily share this across platforms, and we need to manually update the files as changes propagate from the c++ interface.

The problem I am currently seeing, is that when the framework, interface, and wrapper are in a CocoaPod, once imported into the application, the interface file loses the ability to import from the framework (as well as from standard C++ libraries).

Here is the podspec file I am working with the relevant parts: do |s| = 'PodName'
s.source = { :path => "." }
s.source_files = "path/to/source/files/Classes/**/*.{h,mm}", "c++libraryPath/**/*.{h,cpp}"
s.vendored_frameworks = 'path/to/framework/file/Frameworks/opencv2.framework'
s.frameworks = 'Accelerate', 'AssetsLibrary', 'AVFoundation', 'CoreGraphics', 'CoreImage', 'CoreMedia', 'CoreVideo', 'Foundation', 'opencv2', 'QuartzCore', 'UIKit'
s.libraries = 'stdc++'


In the C++ library file header, we have the following:

#include <string>
#include <map>
#include <vector>
#include <memory>

#include "opencv2/core.hpp"

When that file is dropped into the target project, everything works great. However, in a CocoaPod, it fails to find anything in the include statements.

Some things I have tried doing to assist it include:

  • Setting the file type to C++ header instead of C header

  • Checked to make sure the header file has target membership

I also explored the framework search path in Xcode:
enter image description here

I have tested without the specific paths to the OpenCV framework, and it makes no difference. I just included this to show that this was tried.

I also tested a very simplified CocoaPod that only consists of the OpenCV framework, and the C++ library class. When I import the CocoaPod with only the framework, I am able to successfully access the methods contained in it. However, once I add the C++ class, it fails to find any includes.

Another item to note. Upon adding the framework to CocoaPods, we found that the links were being broken internally, which caused all kinds of problems. Links were recreated by running the following commands from inside the OpenCV framework:

rm -rf Headers
ln -s Versions/A/Headers/ .
rm -rf opencv2
ln -s Versions/A/opencv2 .
rm -rf Resources
ln -s Versions/A/Resources/ .

Answer Source

Turns out the problem was that the header file for a C++ library I had was being exposed by Cocoapods, which in turn, caused the problem with the Swift project.

The solution was to do this in the podspec file:

s.public_header_files = { all header files for code that was in Obj-C }

s.private_header_files = { all header files for code that was pure C / C++ }

Using this, I was able to hide the C/C++ code from the Swift project, which allowed it to work properly.