【问题标题】:Weak linking static library in XcodeXcode中的弱链接静态库
【发布时间】:2021-11-06 00:31:10
【问题描述】:

我正在尝试实现与静态库的弱链接。我看过“Static Library on iOS”和“How Jesse Pinkman cracked Dynamic Library on iOS”这两篇文章,真的很有帮助。

但是,我无法实现我想要的。我开发了两个框架,我们称它们为MainFeature,它们可以安装为 pod 和 swift 包。

Main 不依赖于FeatureFeature 也不依赖于Main,但如果MainFeature 都存在于开发者的podfile 中,那么Main 可以使用Feature 的功能。这是通过在其 podspec 中的 Main 的框架搜索路径上添加 Framework 的路径来实现的。

Main.podspec

# This works when use_frameworks! is added in the podfile.
s.pod_target_xcconfig = {
    "FRAMEWORK_SEARCH_PATHS" => [
      "$(inherited)",
      "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
}

这样,Main 可以通过以下方式使用Feature 的功能

#if canImport(Feature)
print("SUCCESS!!!")
let feat = Feature()
feat.test()
#else
print(“Failed to import Feature“)
#endif

当集成开发人员没有在他的 podfile 中包含 use_frameworks!(例如 React Native)时,问题就开始了。 MainFeature 然后构建为静态库,它可以编译但它永远不会进入 SUCCESS 块。

看完上面的文章,我相信正确的做法应该是这样的

Main.podspec

s.pod_target_xcconfig = {
    "LIBRARY_SEARCH_PATHS" => [
      "$(inherited)",
      "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
    "SWIFT_INCLUDE_PATHS" => [
        "$(inherited)",
        "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
  }

也许还可以添加

  Main.podspec

  s.pod_target_xcconfig = {
   …
    'OTHER_LDFLAGS' => [
        "$(inherited)",
        '-ObjC',
        '-weak_library -l"Feature"'
    ],
    …
  }

我已经在Feature 一侧尝试了上述两种Defines module = YES/NO

Feature.podspec

s.pod_target_xcconfig = {
    'DEFINES_MODULE' => 'YES'
}

但是,上述方法均无效。有谁知道我可能做错了什么,或者指出我的方向?

【问题讨论】:

    标签: ios swift objective-c xcode cocoapods


    【解决方案1】:

    我最终嘲笑了您的需求here

    但是,我只能通过以下方式解决您的问题的一半(没有use_frameworks):

    Main.podspec
    
    # To include Swift Module
    'OTHER_SWIFT_FLAGS' => ['$(inherited)', '-Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Feature/Feature.modulemap"']
    

    Podspec 方面:

    • 不知道为什么 cocoapod 设置需要 modulemap 文件路径(可能是库链接较弱时)

    Podfile 端:

    • 没有use_frameworks 也可以工作
    • 它不适用于use_frameworks,因为在指定路径中找不到modulemap 文件(因为它只考虑静态路径场景)& Xcode 会认为它是必需的。不确定如何在 Podspec 中选择性地指定 modulemap 文件。

    我希望我能提供帮助,即使它已经完成了一半。

    【讨论】:

    • 这太棒了!谢谢!我必须找到一种方法让它在有和没有use_frameworks 的情况下工作,但这是向前迈出的一大步。你对-Xcc -fmodule-map-file 的结论如何?我明天将对其进行迭代,如果我能做到,我会告诉你。
    • 为了结束 -Xcc -fmodule-map-file,我查看了 CocoaPods 生成的 clang.llvm.org/docs/Modules.html#module-mapsxcconfigs。要使其在使用和不使用use_frameworks 的情况下工作,可能有几个选项: 1. 为每个 pod 指定 use_frameworks,CocoaPods 目前不支持 AFAIR。 2.客户端使用pre_installpost_install钩子。
    【解决方案2】:

    @e_pie 如果您清楚 Main 的依赖,我认为您正在尝试做的是 post_install 的东西>功能

    所以,你尝试的东西实际上是完美的,但应该像这样放在 post_install 在 App 的 Podfile 中:

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        if target.name == "Main"
          target.build_configurations.each do |config|
            config.build_settings['FRAMEWORK_SEARCH_PATHS'] = "${PODS_CONFIGURATION_BUILD_DIR}/Feature"
          end
        end
      end
    end
    

    希望对你有帮助,如果没有,请告诉我。

    【讨论】:

    • 首先感谢您的回答!我无权访问应用程序的文件,这可能是任何决定集成我的 pod 的开发人员。所以我正在尝试寻找另一种解决方案。
    • 明确一点,应用程序和 Pod 构建良好。 #if canImport 是否有可能不适用于静态库?我应该以其他方式做吗?例如。在Feature 一侧带有编译器标志,因为我将拥有$(inherited) Main 一侧,我可以检查它是否存在。
    • #if canImport 应该与模块一起使用,因此当我在其 podspec 中包含'DEFINES_MODULE' => 'YES' 时,我希望它可以与Feature 一起使用
    • @e_pie 我对你想要达到的目标有点困惑。 ----- 1. 如果Feature 链接到Main#if canImport 将起作用 2. 我认为编译器标志是基于每个目标的。因此,如果它们是独立的,MainFeature 将无法使用它。 3. 我认为DEFINES_MODULE 是默认的。 ----- 我建议在已链接 Feature 的 App Target 上检查相同的 #if canImport 代码。你怎么看。
    • Tbh 我不确定我想要实现的目标是否仅适用于 Swift。目标是拥有一个 SDK Main,如果在 podfile 中添加了 Feature,它可以使用 SDK Feature 中的功能。我无权访问 App 及其 podfile,这是在别人的另一边。我知道这可以在 ObjC 中使用互操作性来完成,因为在那里我可以检查运行时是否存在 Feature。我不介意这发生在构建时还是运行时,但由于这两个 SDK 都是用 Swift 编写的,所以我试图避免互操作性。
    猜你喜欢
    • 2018-12-06
    • 2023-04-03
    • 1970-01-01
    • 2018-01-23
    • 2017-01-31
    • 2013-01-20
    • 2012-01-28
    • 2011-07-15
    • 1970-01-01
    相关资源
    最近更新 更多