【问题标题】:Header management with static libraries in Xcode 4Xcode 4 中使用静态库的标头管理
【发布时间】:2011-09-11 12:16:43
【问题描述】:

在 Xcode 4 中导入静态库头文件是否有最佳实践?我的大部分项目都依赖于其他几个项目,因此我最近开始使用工作区功能从一个地方构建所有需要的模块(我觉得这很方便)。

糟糕的是,我们不能在 iOS 上使用自定义框架,因此依赖项必须构建为静态库,并且我遇到了标题搜索路径的问题。框架将它们的头文件保存在框架包中,而静态库则没有这个选项。我讨厌为我导入的每个库单独设置用户标题搜索路径。理想情况下,我想将依赖项目拖到工作区,将库添加到主目标并构建,无需进一步设置。是否支持此工作流程?

【问题讨论】:

    标签: xcode4 static-libraries header-files


    【解决方案1】:

    我目前最好的解决方案是将所有支持库保存在一个公共文件夹中(比如Support),将标题搜索路径设置为Support/**。感觉笨拙,但有效。

    【讨论】:

    • 我这几天一直在努力寻找一个优雅的解决方案。你的是我迄今为止找到的最好的。
    • @zoul 你能扩展一下吗?我看过的教程都没有解释这个过程。我所做的是 1)创建一个静态可可触摸库,2)将 xcodeproj 文件拖放到客户端项目中的“依赖项”组中,3)将其添加到目标依赖项和链接二进制文件,以及 4)尝试设置标题搜索路径......并且没有办法让这最后一步工作:(
    • @entonio, here’s a nice tutorial 你可能还没读过。它还包括设置标题路径,希望它在发布两年后仍然是最新的。
    【解决方案2】:

    我的工作相当复杂,但对我来说效果很好。

    在静态库项目的设置中,在“Packaging”部分,我将“Wrapper Extension”设置为“framework”。然后我改变:

    "Public Headers Folder Path" to "$(PRODUCT_NAME).$(WRAPPER_EXTENSION)/Headers"
    

    "Private Headers Folder Path" to $(PRODUCT_NAME).$(WRAPPER_EXTENSION)/PrivateHeaders
    

    构建产品的最终结果是一个名为“MyLibraryName.framework”的文件夹,其内容看起来就像……嗯……一个框架。我喜欢的一件事是我可以在我的代码中使用框架风格的包含:

    #include <MyLibraryName/blah.h>
    

    缺点是(在“zoul”的回答中发现)“存档”命令无法正常工作。它不起作用的原因是因为 Archive 命令将最终构建产品和目标构建产品分隔到单独的目录中。正常的“构建”不会这样做。当您归档时,系统会尝试在最终构建产品目录中查找静态库头文件,但由于系统将它们放在静态库的目标构建目录中,因此无法找到它们。

    如果你仔细想想,Xcode 认为你的静态库的目标只有一个“产品”。该产品是“libMyLibraryName.a”。但实际上目标有两种产品……一种是库,另一种是库的标题集。 Archive 命令的问题是库被复制为构建产品,但标题不是。当您尝试运行存档时,最终会出现“找不到标题”。

    要解决这个问题,我要做的是使用运行脚本构建阶段。脚本如下所示(用 Ruby 编写):

    if ENV["TARGET_BUILD_DIR"] != ENV["BUILT_PRODUCTS_DIR"] then
      $product_name = ENV['PRODUCT_NAME']
      $wrapper_extension = ENV['WRAPPER_EXTENSION']
      $target_build_dir = ENV['TARGET_BUILD_DIR']
      $built_products_dir = ENV['BUILT_PRODUCTS_DIR']
    
      $source_file = File.join($target_build_dir, $product_name + "." + $wrapper_extension)
      $dest_file = File.join($built_products_dir, $product_name + "." + $wrapper_extension)
    
      system "ln -s #{$source_file} #{$dest_file}" if File.exist?($source_file)
    end
    

    如果目标构建目录和构建产品目录不匹配...创建一个符号链接到我在构建产品目录中创建的假“框架”。

    正如我所说,这是一个复杂的方案,但它很有效,让我可以使用我喜欢的框架风格的包含。如果 Xcode 允许 iOS 开发人员创建框架(这也意味着 iOS 允许开发人员创建动态库,这是 Apple 不愿意做的事情),或者如果 Apple 会创建框架的变体……一个包,那么整个混乱将会大大简化包含一个静态库和附带的头文件(一个 static_framework?),这样您就有一个包含头文件和静态库的构建产品。

    【讨论】:

      【解决方案3】:

      我发现我可以将静态库头设置为复制到Headers 文件夹(而不是默认的/usr/local/include)。该文件夹将出现在 build-products 文件夹中,我可以将 User Header Search Paths 设置为 $(BUILT_PRODUCTS_DIR) 和递归。

      如果所有库都设置为将其公共标头复制到此文件夹,我确实得到了所需的行为 - 添加新依赖项时,我只需将项目拖到工作区,设置链接依赖项,我很高兴去吧。

      【讨论】:

      • 不幸的是,这在当前的 Xcode 中不能可靠地工作,存档构建由于某种原因而失败。我欢迎更好的解决方案。
      猜你喜欢
      • 2013-01-05
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 2011-11-18
      • 2011-12-07
      • 2012-04-14
      • 2012-03-19
      相关资源
      最近更新 更多