2

I'm having a few problems creating a podspec file to extract a C++ library from an iOS application.

Actually my main problem are headers, my C++ library depends on rapidjson that is included inside the library repository in an ext_inc directory ( the files are something like ${PROJECT_SOURCE_PATH}/ext_inc/rapidjson/*h).

If I include it in source files like this:

s.source_files = utils/*{cpp,h}', 'handler/*{cpp,h}','ext_inc/**/*h'

When I try to compile the library with:

pod lib lint --verbose report-base.podspec

I get errors like this:

 ../utils/json_serializer.h:8:10: fatal error: 'rapidjson/prettywriter.h' file not found

The errors are caused by the fact that headers are included as:

#include "rapidjson/prettywriter.h"

The compilation goes on if I change that to:

#include "prettywriter.h"

... but that is the wrong way to include an external library like rapidjson and it's not portable at all (the same library is also the core of the android application, so I should remain as crossplatform as possible).

I tried to avoid this problem using the podfile private_header_path and adding a xcconfig with the key:

'HEADER_SEARCH_PATHS' => 'ext_inc'

... but nothing works.

For what I have understood cocoapods build an xcode project from the podspec file, and uses module mapping to map all the source and header files like if they are all in a single directory, and in this context the fact that my headers include a path break everything... there is a way to "save" in the module map an header with a path?

gabry
  • 1,370
  • 11
  • 26
  • why you don't change just your `Additionnal Include Directories` project argument ? because now, i suppose it definied like this : `.../rapidjson/` this is why it work when you wrote `#include "prettywriter.h"` and not when you wrote `#include "rapidjson/prettywriter.h"` – Landstalker Mar 04 '20 at 09:32
  • HEADER_SEARCH_PATHS is the xcconfig name of "Additional Include Headers" – gabry Mar 04 '20 at 09:49
  • your `HEADER_SEARCH_PATHS` must be setted in absolut path like this : `${PROJECT_SOURCE_PATH}/ext_inc/` and not just like this `ext_inc` – Landstalker Mar 04 '20 at 10:24
  • PROJECT_SOURCE_PATH environment variable is not configured... I cannot find in the cocoapods documentation where is the correct name of that variable... – gabry Mar 04 '20 at 14:36
  • `${PROJECT_SOURCE_PATH}` (who represents `Additionnal Include Directories`) must be a vriable of your IDE and can not be an environement variable like `PATH, USERNAME, ...`. Because it value changes depending on the path of your project sources. Example : if you copy your project to `G:\myProject` `${PROJECT_SOURCE_PATH} = G:\myProject` – Landstalker Mar 04 '20 at 14:46
  • We are not talking about an IDE here, but about the commands: pod lib lint --verbose myname.podspec pod repo push myname.podspec ... anyway I found a variable defined by cocoapods, that is $PROJECT_DIR – gabry Mar 04 '20 at 16:09
  • you say that when you put `#include "prettywriter.h"` it work, that means that `${PROJECT_SOURCE_PATH}/ext_inc/rapidjson/` is already defined as additional include folder. At what step this was configured? – Landstalker Mar 04 '20 at 16:23
  • It means that cocoapods is grabbing all the source files and header files and placing them in a single folder, anyway I've a solution now, it's a bit convoluted but it works. I'll publish it as answer right now. – gabry Mar 06 '20 at 15:50

1 Answers1

2

After a few days struggling on this topic I've found a solution.

The solution requires multiple steps.

  • You must specify inside the podspec file that you want to preserve a path
  • then you have to specify in the header search path used in pod validation (pod lint / pod repo push) where to find the headers.
  • then you have to specify in the header search path of the final application where the headers are located.
  • pod lib lint/pod repo push should be run with the option --skip-import-validation

So given that you want to access rapidjson/prettywriter.h that is located inside ext_inc inside your pod project repository this is what I had to do:

note: spec is the object inside the ruby myproject.podspec

   spec.preserve_paths = 'ext_inc/**'
   spec.pod_target_xcconfig = {
       'HEADER_SEARCH_PATHS' => "\"" + __dir__ + "/ext_inc\""
   }
   spec.xcconfig = {
       'HEADER_SEARCH_PATHS' => "\"${PODS_ROOT}/report-base/ext_inc\""
   }

The strange thing is that I need to build with the ruby trick of using __dir__ since it was the only way to work both when using pod lib lint (local repository) that using pod repo push (cloned on the fly repository).

gabry
  • 1,370
  • 11
  • 26