如何创建包含静态库的 pod?

Posted

技术标签:

【中文标题】如何创建包含静态库的 pod?【英文标题】:How to create a pod that includes static libraries? 【发布时间】:2015-10-31 13:28:14 【问题描述】:

我正在努力使我的图书馆像 CocoaPod 一样工作,如果有任何帮助,我将不胜感激。

我以前从未制作过 Pod,我觉得我已经做好了一切准备工作......如果它是一个简单的 Pod,只是未编译 .h/.m/@ 987654324@ 文件,但是,我的库包含已编译的 .a 文件,这是我的库使用的静态库。

我在 Xcode 中的项目设置为将我的 Objective-C 库编译为 .a 库。如果我在 Xcode 中编译它,它会毫无问题地生成这个文件,但是,当我尝试 lint podspec 时,我得到的链接器错误似乎与我试图链接到的静态库有关。

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" => "nhgrif@gmail.com" 
  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

我也尝试了其他方法,例如将库设为子规范,但似乎没有任何效果。

尽管在 Xcode 中编译良好,但 linter 给出了链接器错误:

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.

向上滚动输出,我可以找到以下错误:

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)

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)

这似乎表明该项目存在问题...但我可以将其编译为.a 没有问题。我还通过将原始源文件或生成的 .a 文件(我的 libSQLConnect.a,而不仅仅是 libFreeTDS.a)拖到 iOS 项目中来使用这个库。

那么我如何让这个作为一个 pod 工作呢?

图书馆可以找到here on Github。

【问题讨论】:

在旧版本中,我使用pod lib create NAME --static 完成了此操作。不确定是否仍然有效。 【参考方案1】:

看起来您需要与 libiconv 链接。添加:

s.libraries = 'iconv'

在您的 pod 中将带您到达那里。

我已在 Github 中向您发送了包含修复的拉取请求。

【讨论】:

我以为我已经尝试过了,但我想我的库名称错误(我想我正在尝试libiconv 或其他东西)。 @nhgrif iconv 到底是什么。我试图在你的 github 项目中搜索它,但我没有看到任何 iconv.a 文件? .我有一个类似的问题,我正在尝试解决。 @Max libiconv 是一个标准的编码转换库:gnu.org/software/libiconv 它将在大多数使用 GNU 的操作系统中可用。也许陈述你的问题?【参考方案2】:

我无法帮助您解决 CocoaPod 问题。

但如果您支持 iOS8+,那么我建议您将 Carthage 作为附加/替代依赖管理器。您不会遇到您所描述的问题类型。我提出这个建议只是因为我过去使用过 CocoaPods,并且对它的工作方式感到沮丧。所以我一直将我的项目切换到 Carthage,因为我发现它比 CocoaPods 处理起来要简单得多,并且不涉及任何 Ruby 黑客(没有 pod 规范)或在你的项目文件中踩踏。但是,它基于使用框架(因此是 iOS8+ 要求)而不是静态库,因此它是否适合您取决于您​​要实现的目标。

PS。不,我不是 Carthage 的维护者。我只是碰巧更喜欢它:-)

【讨论】:

这与我使用的依赖管理器无关。这是关于使用最流行的依赖管理器制作我想要分发的东西。 如果您想发布根本无法回答他的问题的内容,您可以随时对问题发表评论而不是发布答案。..

以上是关于如何创建包含静态库的 pod?的主要内容,如果未能解决你的问题,请参考以下文章

用CocoaPod创建私有的静态库(不公开源码)

如何使用cmake生成基于静态库的动态链接库

更改静态库的包含路径

Linux 静态库和共享(动态)库的创建与使用详解

linux中,包含静态库的动态库导出时,静态库的函数也被一并导出

iOS之深入解析静态Pod与动态Pod