【问题标题】:How to link against the correct Framework inside a XCFramework for different platforms with xcconfig files如何使用 xcconfig 文件在不同平台的 XCFramework 中链接正确的框架
【发布时间】:2021-05-22 16:47:06
【问题描述】:

情况

我刚刚迁移到最新的 XCode12.4,因此我已将所有依赖项预编译为 xcframeworks。现在我正在使用xcconfig 链接其中一些框架。 我有一个应用程序,它使用了几个预编译的xcframeworks

这是一个共享文件Dependencies/Frameworks.xcconfig,它提供对所有依赖项的轻松访问,并且与预编译的依赖项位于同一个存储库中。

/// Path into xcode specific builds
FRAMEWORKS_PATH_12_4 = Frameworks/XCode12.4
FRAMEWORKS_PATH_11_5 = Frameworks/XCode11.5 // old path, obsolete
FRAMEWORKS_PATH_10_3 = Frameworks/XCode10.3 // old path, obsolete

/// All firebase related frameworks
FIREBASE_FRAMEMWORKS = -framework FirebaseAnalytics -framework FirebaseCore -framework FirebaseCoreDiagnostics -framework FirebaseCrashlytics -framework FirebaseInstallations -framework GoogleAppMeasurement -framework GoogleDataTransport -framework GoogleUtilities -framework PromisesObjC -framework nanopb 

/// Summary of all Frameworks provided by this repo
ALL_FRAMEWORKS = -framework ZipArchive -framework Alamofire -framework RxSwift -framework RxCocoa -framework RxRelay -framework Snapkit -framework SVGKit -framework Lottie -framework AudioKit -framework NSLoggerSwift $(FIREBASE_FRAMEMWORKS)

现在我的应用程序中的框架链接到 2 个框架,看起来像这样

/// Include the dependency repo definitions
#include "../Dependencies/Frameworks.xcconfig"

/// Define this for the carthage build step
DEPENDENCIES_PATH[config=RC]         = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
DEPENDENCIES_PATH[config=Release]    = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
DEPENDENCIES_PATH[config=T1]         = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
DEPENDENCIES_PATH[config=Debug]      = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)

/// Setup search paths
FRAMEWORK_SEARCH_PATHS = $(inherited) $(DEPENDENCIES_PATH)/**

/// Include required frameworks
OTHER_LDFLAGS = $(inherited) -framework Alamofire -framework ZipArchive

问题

现在,当我针对通用设备构建或存档时,一切都很好。但是当我为模拟器构建时,我得到了这个错误

Could not find module 'Alamofire' for target 'x86_64-apple-ios-simulator'; found: arm64, armv7-apple-ios, arm64-apple-ios, arm, armv7

我认为这是由于这里的递归搜索路径

/// Setup search paths
FRAMEWORK_SEARCH_PATHS = $(inherited) $(DEPENDENCIES_PATH)/**

当我删除递归搜索路径时,我收到此错误

No such module 'Alamofire'

解决方法

似乎可行的是告诉编译器像这样深入查看xcframework 内部

/// Setup search paths
FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*] = $(inherited) $(DEPENDENCIES_PATH)/Alamofire.xcframework/ios-arm64_armv7 $(inherited) $(DEPENDENCIES_PATH)/ZipArchive.xcframework/ios-arm64_armv7
FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) $(DEPENDENCIES_PATH)/Alamofire.xcframework/ios-arm64_i386_x86_64-simulator $(DEPENDENCIES_PATH)/ZipArchive.xcframework/ios-arm64_i386_x86_64-simulator

但老实说,我在项目中有几十个依赖项,维护这些是超级乏味的。

问题

我如何告诉我的框架 xcconfig 文件,它应该在 inside xcframework 内的正确架构文件夹中查找实际的 framework

【问题讨论】:

    标签: ios xcode linker xcframework


    【解决方案1】:

    在 Xcode 中,将 Run Script 预构建操作添加到您的方案中。

    将此脚本放入运行脚本预构建操作中:

    OLD_DIR="${PWD}"
    rm -rf "${CONFIGURATION_TEMP_DIR}/XCFrameworkSlices"
    mkdir -p "${CONFIGURATION_TEMP_DIR}/XCFrameworkSlices"
    cd "${CONFIGURATION_TEMP_DIR}/XCFrameworkSlices"
    SUFFIX="arm[v6][74]"
    if [[ ! -z "$LLVM_TARGET_TRIPLE_SUFFIX" ]]; then
       SUFFIX=$LLVM_TARGET_TRIPLE_SUFFIX
    fi
    find $DEPENDENCIES_PATH/*.xcframework/$SWIFT_PLATFORM_TARGET_PREFIX-*$SUFFIX -type d -depth 0 -print0 | xargs -0 -I {} sh -c 'ln -s "$1" "./$(basename $(dirname \"$1\"))"' - {}
    cd "${OLD_DIR}"
    

    在 xcconfig 中:

    DEPENDENCIES_PATH_RC         = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
    DEPENDENCIES_PATH_Release    = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
    DEPENDENCIES_PATH_T1         = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
    DEPENDENCIES_PATH_Debug      = $(SRCROOT)/../Dependencies/$(FRAMEWORKS_PATH_12_4)
    
    DEPENDENCIES_PATH = $(DEPENDENCIES_PATH_$(CONFIGURATION))
    FRAMEWORK_SEARCH_PATHS = $(inherited) $CONFIGURATION_TEMP_DIR/XCFrameworkSlices/**
    

    【讨论】:

    • Mh,这似乎有效..但第一次清理失败后..我已将脚本提取到“sh”文件中并在 ru-script 阶段调用它,如下所示@ 987654323@ 有关如何在清理后的第一次构建中运行它的任何提示? (存档根本不工作,因为它总是干净的构建..顺便说一下错误是“没有这样的模块......”
    • 添加新的聚合目标(位于目标类型选择器的其他选项卡中),将shell脚本构建阶段放入聚合目标,将聚合目标放入iOS目标的依赖项列表中
    • 好吧,在没有提取脚本的情况下也会发生这种情况。当我将脚本直接粘贴到阶段时,它也会失败。
    • 不幸的是仍然与聚合目标相同
    • 酷,我会在我的回答中解决这个问题。
    猜你喜欢
    • 2021-06-24
    • 2020-08-06
    • 2020-03-24
    • 2021-06-26
    • 1970-01-01
    • 2011-12-19
    • 2017-08-22
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多