Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Podspec CocoaPods 1.0 compatibility #127

Closed
vixentael opened this issue Aug 23, 2016 · 6 comments
Closed

Podspec CocoaPods 1.0 compatibility #127

vixentael opened this issue Aug 23, 2016 · 6 comments
Labels
O-iOS 📱 Operating system: iOS

Comments

@vixentael
Copy link
Contributor

The given:

Creating a new iOS project, linking themis master as CocoaPod.

The problem:

If you create new project using CocoaPods v1.0.1, your podfile includes use_frameworks! and links to the HEAD of master branch, then Pods can't be installed.

podfile:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '9.0'
project 'NoWorkingPodsDemo/NoWorkingPodsDemo.xcodeproj'
inhibit_all_warnings!
use_frameworks!

install! 'cocoapods', :deterministic_uuids => false

target :"NoWorkingPodsDemo" do

   # example should work with head
  pod 'themis', :git => "https://github.com/cossacklabs/themis.git"

end

Error log

Analyzing dependencies
Pre-downloading: `themis` from `https://github.com/cossacklabs/themis.git`
^[[A^[[A[!] Unable to find a specification for 'themis'.

[!] Unable to load a podspec from `themis.podspec`, skipping:

Pod::DSLError
@vixentael vixentael added the O-iOS 📱 Operating system: iOS label Aug 23, 2016
@vixentael
Copy link
Contributor Author

vixentael commented Aug 23, 2016

Solutions v1

  • Update Header Search Path (to fix build themis/soter sources)
  • Add Library Search Path and link to ssl, crypto libraries

Updated PodSpec:

podspec:

Pod::Spec.new do |s|
    s.name = "themis"
    s.version = "0.9.3"
    s.summary = "Data security library for network communication and data storage for iOS and OS X "
    s.description = "Themis is a data security library, providing users with high-quality security services for secure messaging of any kinds and flexible data storage. Themis is aimed at modern development practices, with high level OOP wrappers for Ruby, Python, PHP, Java / Android and iOS / OSX. It is designed with ease of use in mind, high security and cross-platform availability."
    s.homepage = "http://cossacklabs.com"
    s.license = { :type => 'Apache 2.0'}
    s.source = { :git => "https://github.com/cossacklabs/themis.git", :branch => "pods_1_0" }
    s.author = {'cossacklabs' => 'info@cossacklabs.com'}

    s.dependency 'OpenSSL-Universal', '1.0.1.19'

    s.ios.deployment_target = '7.0'
    s.osx.deployment_target = '10.9'

    s.xcconfig = { 'OTHER_CFLAGS' => '-DLIBRESSL', 'USE_HEADERMAP' => 'NO', 
        'HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/themis/src" "${PODS_ROOT}/themis/src/wrappers/themis/Obj-C"',
        'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/OpenSSL-Universal/lib-ios"' }

    # open ssl
    s.libraries = 'ssl', 'crypto'

    s.subspec 'core' do |ss|
        ss.source_files = "src/themis/*.{h,c}", "src/soter/**/*.{c,h}"
        ss.header_mappings_dir = "src"
        ss.header_dir = 'src'
        ss.preserve_paths = "src/themis/*.h", "src/soter/**/*.h"
        ss.public_header_files = "src/themis/*.h", "src/soter/**/*.h"
    end

    s.subspec 'objcwrapper' do |ss|
        ss.header_mappings_dir = 'src/wrappers/themis/Obj-C/objcthemis'
        ss.source_files = "src/wrappers/themis/Obj-C/objcthemis/*.{m,h}"
        ss.public_header_files = 'src/wrappers/themis/Obj-C/objcthemis/*.h'
        ss.header_dir = 'objcthemis'
        ss.dependency 'themis/core'
    end
end

Result =>

podfile looks liks

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '9.0'
project 'WorkingWithStaticLib/WorkingWithStaticLib.xcodeproj'
inhibit_all_warnings!
use_frameworks!

#install! 'cocoapods', :deterministic_uuids => false

target :"WorkingWithStaticLib" do
  pod 'themis', :podspec => 'themis.podspec'
end

pre_install do |installer|
    # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
    def installer.verify_no_static_framework_transitive_dependencies; end
end

Demo project is compiling fine.

However, linting pod spec cause error -->

Linting error (pods 1.0)

pod spec lint themis.podspec

error
The 'Pods-App' target has transitive dependencies that include static binaries

@vixentael
Copy link
Contributor Author

vixentael commented Aug 23, 2016

I found solution for linting podspec with static library (add --use-libraries argument, read more)

pod spec lint themis.podspec --use-libraries

Result ==>

Podspec with dependency to Podspec that includes .a library can be linted :)

🎉 🎉 🎉 🎉 🎉

@vixentael
Copy link
Contributor Author

Solution v2

Adding openssl dynamic framework to themis wrapper, linking podspec to the dynamic framework.

Dynamic frameworks

The idea behind is to build OpenSSL as dynamic framework. The problem is that dynamic frameworks need a lot of extra work to do (like, to create separate iOS/MacOS Xcode workspaces to be able to generate frameworks).

However, @jcavar has done incredible work and created PRs for this:

krzyzanowskim/OpenSSL#26
krzyzanowskim/OpenSSL#27

I've grabbed generated dynamic frameworks and added them to themis objcwrapper sources (see pods_1.0 branch).

Podspec

  • Link to frameworks.
  • Drop iOS 7.
Pod::Spec.new do |s|
    s.name = "themis"
    s.version = "0.9.3"
    s.summary = "Data security library for network communication and data storage for iOS and OS X "
    s.description = "Themis is a data security library, providing users with high-quality security services for secure messaging of any kinds and flexible data storage. Themis is aimed at modern development practices, with high level OOP wrappers for Ruby, Python, PHP, Java / Android and iOS / OSX. It is designed with ease of use in mind, high security and cross-platform availability."
    s.homepage = "http://cossacklabs.com"
    s.license = { :type => 'Apache 2.0'}
    s.source = { :git => "https://github.com/cossacklabs/themis.git", :branch => "pods_1_0" }
    s.author = {'cossacklabs' => 'info@cossacklabs.com'}

    s.ios.vendored_frameworks  = 'src/wrappers/themis/Obj-C/openssl_frameworks/ios/openssl.framework'
    s.osx.vendored_frameworks  = 'src/wrappers/themis/Obj-C/openssl_frameworks/macos/openssl.framework'

    s.ios.deployment_target = '8.0'
    s.osx.deployment_target = '10.9'
    s.requires_arc = false

    s.xcconfig = { 'OTHER_CFLAGS' => '-DLIBRESSL', 'USE_HEADERMAP' => 'NO', 
        'HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/themis/src" "${PODS_ROOT}/themis/src/wrappers/themis/Obj-C"' }

    s.subspec 'core' do |ss|
        ss.source_files = "src/themis/*.{h,c}", "src/soter/**/*.{c,h}"
        ss.header_mappings_dir = "src"
        ss.header_dir = 'src'
        ss.preserve_paths = "src/themis/*.h", "src/soter/**/*.h"
        ss.public_header_files = "src/themis/*.h", "src/soter/**/*.h"
    end

    s.subspec 'objcwrapper' do |ss|
        ss.header_mappings_dir = 'src/wrappers/themis/Obj-C/objcthemis'
        ss.source_files = "src/wrappers/themis/Obj-C/objcthemis/*.{m,h}"
        ss.public_header_files = 'src/wrappers/themis/Obj-C/objcthemis/*.h'
        ss.header_dir = 'objcthemis'
        ss.dependency 'themis/core'
    end
end

Build error

Unfortunately, project build causes errors Could not build module Foundation.

screen shot 2016-08-23 at 13 19 29

Possible reason

Maybe connected with this CP bug:

CocoaPods/CocoaPods#5408

Result

Well, project cannot be built :) And podspec cannot be linted :)

Any suggestions? Wait for CP fix? Or is it header issue?

@vixentael vixentael changed the title Podspec 1.0 compatibility Podspec CocoaPods 1.0 compatibility (aka static libs) Aug 23, 2016
@vixentael
Copy link
Contributor Author

vixentael commented Aug 23, 2016

Last issue may be fixed by disabling modules, as described on apple forums.

So, resulting wrapper contains built-in openssl frameworks and disabling modules flag.

Podspec

Link to frameworks.
Drop iOS 7.
Disable modules.

Pod::Spec.new do |s|
    s.name = "themis"
    s.version = "0.9.3"
    s.summary = "Data security library for network communication and data storage for iOS and OS X "
    s.description = "Themis is a data security library, providing users with high-quality security services for secure messaging of any kinds and flexible data storage. Themis is aimed at modern development practices, with high level OOP wrappers for Ruby, Python, PHP, Java / Android and iOS / OSX. It is designed with ease of use in mind, high security and cross-platform availability."
    s.homepage = "http://cossacklabs.com"
    s.license = { :type => 'Apache 2.0'}
    s.source = { :git => "https://github.com/cossacklabs/themis.git", :branch => "pods_1_0" }
    s.author = {'cossacklabs' => 'info@cossacklabs.com'}

    s.ios.vendored_frameworks  = 'src/wrappers/themis/Obj-C/openssl_frameworks/ios/openssl.framework'
    s.osx.vendored_frameworks  = 'src/wrappers/themis/Obj-C/openssl_frameworks/macos/openssl.framework'

    s.ios.deployment_target = '8.0'
    s.osx.deployment_target = '10.9'
    s.requires_arc = false

    s.xcconfig = { 'OTHER_CFLAGS' => '-DLIBRESSL', 'USE_HEADERMAP' => 'NO', 
        'HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/themis/src" "${PODS_ROOT}/themis/src/wrappers/themis/Obj-C"',
        'CLANG_ENABLE_MODULES' => 'NO' }


    s.subspec 'core' do |ss|
        ss.source_files = "src/themis/*.{h,c}", "src/soter/**/*.{c,h}"
        ss.header_mappings_dir = "src"
        ss.header_dir = 'src'
        ss.preserve_paths = "src/themis/*.h", "src/soter/**/*.h"
        ss.public_header_files = "src/themis/*.h", "src/soter/**/*.h"
    end

    s.subspec 'objcwrapper' do |ss|
        ss.header_mappings_dir = 'src/wrappers/themis/Obj-C/objcthemis'
        ss.source_files = "src/wrappers/themis/Obj-C/objcthemis/*.{m,h}"
        ss.public_header_files = 'src/wrappers/themis/Obj-C/objcthemis/*.h'
        ss.header_dir = 'objcthemis'
        ss.dependency 'themis/core'
    end
end

Project is now building successfully, but you may need to use Themis via Bridging header.

(CocoaPods/CocoaPods#4420)

#ifndef DemoWithFrameworks_Bridging_Header_h
#define DemoWithFrameworks_Bridging_Header_h

    #import <objcthemis/objcthemis.h>

#endif /* DemoWithFrameworks_Bridging_Header_h */

Linting

However, linting on CP 1.0 fails due to

    - ERROR | [themis/core,themis/objcwrapper] xcodebuild: Returned an unsuccessful exit code.
    - ERROR | xcodebuild:  /var/folders/1v/7l7m798s24g1xqrh1kdxb2mr0000gn/T/CocoaPods/Lint/App/main.m:1:1: error: use of '@import' when modules are disabled
    - ERROR | xcodebuild:  /var/folders/1v/7l7m798s24g1xqrh1kdxb2mr0000gn/T/CocoaPods/Lint/App/main.m:2:1: error: use of '@import' when modules are disabled
    - ERROR | xcodebuild:  /var/folders/1v/7l7m798s24g1xqrh1kdxb2mr0000gn/T/CocoaPods/Lint/App/main.m:3:1: error: use of '@import' when modules are disabled
    - NOTE  | [themis/core,themis/objcwrapper] xcodebuild:  themis/src/soter/openssl/soter_openssl.h:21:10: fatal error: 'openssl/evp.h' file not found

¯_(ツ)_/¯

@vixentael vixentael changed the title Podspec CocoaPods 1.0 compatibility (aka static libs) Podspec CocoaPods 1.0 compatibility Aug 24, 2016
@vixentael
Copy link
Contributor Author

I split this discussion into two threads, see issue #128 for further dynamic frameworks discussion

@vixentael
Copy link
Contributor Author

Pushed new podspec and tag 0.9.3.1

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
O-iOS 📱 Operating system: iOS
Projects
None yet
Development

No branches or pull requests

1 participant