Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a pod that includes static libraries?

I'm struggling with making my library work as a CocoaPod and would appreciate any assistance that points me in the correct direction.

I've never made a Pod before, and I feel like I've got everything right to the point that this would work... if it were a simple pod with just uncompiled .h/.m/.swift files, however, my library contains a compiled .a file, a static library, that my library uses.

My project in Xcode is set up to compile my Objective-C library into a .a library. If I compile this in Xcode, it generates this file with no problem at all, however, when I try to lint the podspec, I get linker errors that seem to be related to the static library I'm trying to link to.

SQLConnect.podspec

#
# Be sure to run `pod lib lint NAME.podspec' to ensure this is a
# valid spec and remove all comments before submitting the spec.
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
  s.name                = "SQLConnect"
  s.version             = "1.2.0"
  s.summary             = "Connects apps to SQL Server"
  s.description         = <<-DESC
                            A library for connecting Objective-C & Swift apps to SQL Server
                        DESC
  s.homepage            = "http://importblogkit.com"
  s.license             = 'MIT'
  s.authors             = { "Nick Griffith" => "[email protected]" }
  s.social_media_url    = 'https://twitter.com/importBlogKit'
  s.source              = { :git => "https://github.com/nhgrif/SQLConnect.git", :tag => s.version.to_s }

  s.platform                = :ios, '8.0'
  s.ios.deployment_target   = '8.0'
  s.requires_arc            = true
  s.public_header_files     = 'SQLConnect/*.h', 'SQLConnect/SQLSettings/*.h', 'SQLConnect/SQLControllers/*.h', 'SQLConnect/SQLConnection/*.h'
  s.source_files            = 'SQLConnect/**/*.{h,m}'
  s.preserve_paths          = 'SQLConnect/**/*.*'
  s.vendored_libraries      = 'SQLConnect/FreeTDS/libfreetds.a'
  s.xcconfig                = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/SQLConnect/**" }
end

I've tried other approaches as well, like making the library a subspec, but nothing seems to work.

Despite this compiling fine in Xcode, the linter gives linker errors:

The following build commands failed:
    Ld /var/folders/yj/h_f7h7ws3zzfd__f847qys3m0000gn/T/CocoaPods/Lint/build/Pods.build/Release-iphonesimulator/Pods-SQLConnect.build/Objects-normal/i386/SQLConnect normal i386
    Ld /var/folders/yj/h_f7h7ws3zzfd__f847qys3m0000gn/T/CocoaPods/Lint/build/Pods.build/Release-iphonesimulator/Pods-SQLConnect.build/Objects-normal/x86_64/SQLConnect normal x86_64
(2 failures)
 -> SQLConnect (1.2.0)
    - ERROR | [iOS] Returned an unsuccessful exit code.
    - NOTE  |  clang: error: linker command failed with exit code 1 (use -v to see invocation)

Analyzed 1 podspec.

[!] The spec did not pass validation.

Scrolling up through the output, I can find these errors:

Undefined symbols for architecture i386:
  "_iconv", referenced from:
      _tds_iconv_init in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _skip_one_input_sequence in libfreetds.a(iconv.o)
      _tds_iconv_fread in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_close, _tds_iconv_get , _tds_iconv , _tds_iconv_alloc , _tds_iconv_free , _tds_iconv_from_collate , _tds_iconv_open , _tds_iconv_fread )
  "_iconv_close", referenced from:
      _tds_iconv_init in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _skip_one_input_sequence in libfreetds.a(iconv.o)
      __iconv_close in libfreetds.a(iconv.o)
      _tds_set_iconv_name in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_close)
  "_iconv_open", referenced from:
      _tds_iconv_init in libfreetds.a(iconv.o)
      _tds_iconv_info_init in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _skip_one_input_sequence in libfreetds.a(iconv.o)
      _tds_set_iconv_name in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_open)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

and

Undefined symbols for architecture x86_64:
  "_iconv", referenced from:
      _tds_iconv_open in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _tds_iconv_fread in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_close, _tds_iconv_get , _tds_iconv , _tds_iconv_alloc , _tds_iconv_free , _tds_iconv_from_collate , _tds_iconv_open , _tds_iconv_fread )
  "_iconv_close", referenced from:
      _tds_iconv_open in libfreetds.a(iconv.o)
      _tds_iconv_info_close in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _tds_set_iconv_name in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_close)
  "_iconv_open", referenced from:
      _tds_iconv_open in libfreetds.a(iconv.o)
      _tds_iconv_info_init in libfreetds.a(iconv.o)
      _tds_iconv in libfreetds.a(iconv.o)
      _tds_set_iconv_name in libfreetds.a(iconv.o)
     (maybe you meant: _tds_iconv_open)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This seems to indicate there's a problem with the project... but I can compile it to a .a with no problems. I've also used this library both by dragging the raw source files or the resulting .a file (my libSQLConnect.a, not just the libFreeTDS.a) into an iOS project.

So how do I make this work as a pod?

The library can be found here on Github.

like image 641
nhgrif Avatar asked Aug 08 '15 02:08

nhgrif


People also ask

What is a static pod?

Static pods are pods created and managed by kubelet daemon on a specific node without API server observing them. If the static pod crashes, kubelet restarts them. Control plane is not involved in lifecycle of static pod.

Is Cocoapods static or dynamic?

CocoaPods pod-linkage plugin. In SwiftKey, we have a dynamic framework that we use to share code between the app and the keyboard extension, and all the pods are linked statically except for some of them that are linked dynamically because they are linked to the app and keyboard extension too.


1 Answers

Looks like you need to link with libiconv. Adding:

s.libraries = 'iconv'

in your pod will get you there.

I have sent you a pull request in Github with the fix.

like image 200
pevasquez Avatar answered Oct 15 '22 20:10

pevasquez