Cocoapods: Vendoring Pods folder with Swift static libraries does not work due to absolute symlinks

Created on 10 Oct 2018  路  11Comments  路  Source: CocoaPods/CocoaPods

Report

What did you do?

I was trying to vendor a Pods folder for a project that is using Swift Static libraries and our CI system was having issues with missing modulemaps, for example:

Testing failed:
Command CompileSwift failed with a nonzero exit code
Module map file '/Users/distiller/project/app/Pods/Headers/Public/KeychainAccess/KeychainAccess.modulemap' not found
Missing required module 'SwiftShims'
Module map file '/Users/distiller/project/app/Pods/Headers/Public/Swiftilities/Swiftilities.modulemap' not found
Testing cancelled because the build failed.
** TEST FAILED **

It seems that when using Swift static libraries CocoaPods creates a symbolic link for the modulemap, but it uses an absolute path:

$ pwd
/Users/example/Example/app/Pods/Headers/Public/KeychainAccess
$ ls -al
total 0
drwxr-xr-x   4 example  staff  128 Oct 10 11:04 .
drwxr-xr-x  11 example  staff  352 Oct 10 11:04 ..
lrwxr-xr-x   1 example  staff  112 Oct 10 11:04 KeychainAccess-umbrella.h -> /Users/example/Example/app/Pods/Target Support Files/KeychainAccess/KeychainAccess-umbrella.h
lrwxr-xr-x   1 example  staff  111 Oct 10 11:04 KeychainAccess.modulemap -> /Users/example/Example/app/Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap

It does seem to be committed to the repository as a symbolic link:

$ git ls-files -s KeychainAccess.modulemap 
120000 bbd67842feea5a0681d75ddae21fb748fc0e8399 0   KeychainAccess.modulemap
$ git cat-file -p bbd67842feea5a0681d75ddae21fb748fc0e8399
/Users/example/Example/app/Pods/Target Support Files/KeychainAccess/KeychainAccess.modulemap

However when checking out the repository on another machine, the file does not exist at Pods/Headers/Public/KeychainAccess/KeychainAccess.modulemap. My guess is that git doesn't like the absolute symlink.

Is there a way to force CocoaPods to create relative symlinks for these files, or copy the full file?

What did you expect to happen?

All files in the Pods folder can be committed to a git repository and checked out on another machine.

What happened instead?

Symlinked modulemap and header files in Pods/Headers/Public/ folder do not exist when checking out the repo on another machine.

CocoaPods Environment

Stack

   CocoaPods : 1.6.0.beta.1
        Ruby : ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
    RubyGems : 2.7.6
        Host : Mac OS X 10.14 (18A391)
       Xcode : 10.0 (10A254a)
         Git : git version 2.19.1
Ruby lib dir : /usr/local/Cellar/ruby/2.5.1/lib
Repositories :  master - https://github.com/CocoaPods/Specs.git @ cbb416f1eeb3b0b06c59877eaab7a2b14f5d6409

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

claide-plugins        : 0.9.2
cocoapods-deintegrate : 1.0.2
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.0.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0
slather               : 2.4.6

Podfile

platform :ios, '11.0'
inhibit_all_warnings!

abstract_target 'Shared' do
  pod 'Marshal'
  pod 'KeychainAccess'
  pod 'Alamofire'
  pod 'Swiftilities', :git => 'https://github.com/Raizlabs/Swiftilities', :branch => 'feature/heyltsjay/swift4_2'

  target 'Example' do
    pod 'BonMot'
    pod 'Anchorage'

    pod 'Instabug'
    pod 'Crashlytics'

    pod 'GoogleAnalytics',   '~>3.0'

    pod 'SimulatorStatusMagic', :configurations => ['Debug'], :modular_headers => true

    target 'ExampleTests' do
      inherit! :search_paths
      pod 'OHHTTPStubs/Swift'
    end
  end

  target 'Services'
end

pod 'SwiftGen'
pod 'Sourcery', '~> 0.15.0'
pod 'SwiftLint'
workaround available

Most helpful comment

Here's a post_install workaround:

post_install do |installer|
  headers_dir = installer.config.project_pods_root + 'Headers/'
  copied_dir = installer.config.project_pods_root + 'HeadersCopy/'
  puts "Fixing absolute symbolic links..."
  system "rsync --archive --copy-links --recursive #{headers_dir} #{copied_dir}"
  system "rm -rf #{headers_dir}"
  system "mv #{copied_dir} #{headers_dir}"
end

All 11 comments

I _think_ it has something to do with Clang modules requiring absolute paths but I'm not sure - @segiddins any insights on this one?

@amorde Thanks for the quick response! For now I am experimenting with using a post_install hack to copy the full files e.g.

$ rsync --archive --copy-links --recursive Pods/Headers/ Pods/HeadersCopy/
$ rm -rf Pods/Headers/
$ mv Pods/HeadersCopy/ Pods/Headers/

Although it bloats the size of the repo to have everything copied twice, it works.

Here's a post_install workaround:

post_install do |installer|
  headers_dir = installer.config.project_pods_root + 'Headers/'
  copied_dir = installer.config.project_pods_root + 'HeadersCopy/'
  puts "Fixing absolute symbolic links..."
  system "rsync --archive --copy-links --recursive #{headers_dir} #{copied_dir}"
  system "rm -rf #{headers_dir}"
  system "mv #{copied_dir} #{headers_dir}"
end

Thanks for the workaround!

Do we need to "wait for validation" is there a fix in place?

nope, that's me using the labels incorrectly I think

@chrisballinger, thanks for your workaround!

Yet, this workaround adds some warnings like this:

/<module-includes>:1:1: Umbrella header for module 'RxCocoa' does not include header '/RxCocoa.framework/Headers/RxCocoa-umbrella.h'

@chrisballinger does #8196 solve this issue? If so I can land it for 1.6.0.

@dnkoutso Just gave it a spin on our CI. It works!

thanks @chrisballinger will merge it for 1.6.0

@dnkoutso Thank you!!

Was this page helpful?
0 / 5 - 0 ratings