【问题标题】:Can you automatically embed a iOS framework in your executable?你能在你的可执行文件中自动嵌入一个 iOS 框架吗?
【发布时间】:2014-10-28 05:49:37
【问题描述】:

我有一个 iOS 应用程序,它具有“框架 A”作为子项目并将其作为目标依赖项包含在内。 “框架 A”有“框架 B”有一个子项目,并将其作为目标依赖项包含在内。最后,“Framework B”将“Framework C”作为子项目,并将其作为目标依赖。

这个项目构建良好,在模拟器中完美运行,但立即因错误 dyld: Library not loaded: @rpath/Framework A.framework/Framework A 而崩溃。

问题在于“Framework A.framework”文件不会自动复制到应用程序的可执行文件中。您可以将“复制文件”构建阶段添加到您的应用程序目标,并指定应将“框架 A.framework”嵌入到可执行文件中,但此解决方案无法扩展。您仍然缺少“Framework B.framework”和“Framework C.framework”。

例如,假设您有一个复杂的依赖结构,如问题What is the correct process for linking static libraries that have common static libraries? 中所述。您必须手动将六个框架嵌入到您的可执行文件中,如果根框架添加了更多依赖项,则项目将不再构建。您必须记住手动嵌入任何新的依赖项。

那么,有谁知道 Xcode 是否有办法自动嵌入您的目标依赖框架(就像使用静态库一样),或者为什么 Apple 不这样做?尤其是在 iOS 中,将 Xcode 构建框架放到构建目录中然后对它们完全不做任何事情似乎毫无意义。

【问题讨论】:

    标签: ios xcode xcode6


    【解决方案1】:

    我找不到任何方法让 Xcode 自动执行此操作。最后,我更新了编写一个脚本,作为后期构建阶段添加

    frameworksDirectory=${CONFIGURATION_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Frameworks
    mkdir -p "${frameworksDirectory}"
    
    for framework in "${CONFIGURATION_BUILD_DIR}"/*.framework
    do
        if [ -d "${framework}" ]; then
            cp -r "${framework}" "${frameworksDirectory}"
        fi
    done
    
    for framework in "${CONFIGURATION_BUILD_DIR}/../Release${EFFECTIVE_PLATFORM_NAME}"/*.framework
    do
        if [ -d "${framework}" ]; then
            cp -r "${framework}" "${frameworksDirectory}"
        fi
    done
    

    【讨论】:

      【解决方案2】:

      如何自动复制框架的简短答案是使用依赖管理器。需要依赖管理器才能正确执行此操作。唯一的其他答案是避免多级依赖(这通常是首选,但并非总是可能)。

      您的脚本仅适用于每个框架仅构建一个版本的情况。它不会检测到正在构建同一框架的多个版本的情况,并且如果发生这种情况,可能会导致未定义的行为而不会发出警告。你可能对你的构建系统有特殊的了解,知道没有冲突的子框架,但 Xcode 没有。证明没有冲突意味着建立一个依赖管理器。

      在我看来,对依赖管理器的需求是过度使用框架的标志。但在某些情况下它是有用的。

      您不应该只是复制所有内容并希望它有效(这是 Xcode 不这样做的原因之一)。在我看来,目前最好的依赖管理器是Carthage。目前最流行的依赖管理器是CocoaPods

      有关此问题的更专业版本的更多讨论,请参阅Why are umbrella frameworks discouraged?

      【讨论】:

      • 它确实可以处理多个版本,因为框架的多个版本不可能在构建目录中,因为它们将具有相同的名称。实际上,我确实在使用此脚本的项目中构建了同一框架的多个版本。我也知道像 CocoaPods 和 Carthage 这样的依赖管理器,我选择在这种情况下不使用它们。
      • 当你构建同名的框架时,它们不会互相覆盖吗?您如何可靠地知道将包括哪一个?这就是我所说的未定义行为。
      • 明白了。您是正确的,如果您不验证是否正在构建所有相同的框架,那么您将拥有未定义的行为。一切都是从公共子模块指针中提取框架,所以在这种情况下这是不可能的。但是即使没有复制任何框架,问题的核心仍然存在,我仍然需要一种方法将所有依赖框架复制到二进制文件中。
      • 对。唯一通用的方法是使用依赖管理器。如果您有一个特殊情况,您知道“一切都会好起来”,那么您的脚本就可以了,但我认为您最好在顶部添加复制步骤,这样您就可以单点检查那个假设。 (或者使用依赖管理器。)缺乏可扩展性实际上是在“一切都会好起来”的假设中,而不是在“我必须添加一个复制步骤”的工作中。
      • 我无法将其理解为答案,而不是回复自我答案的冗长评论。你能澄清一下哪些部分是独立的吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多