xcode 多平台支持podfile中的单个目标

ldfqzlk8  于 2023-01-14  发布在  其他
关注(0)|答案(5)|浏览(123)

有没有办法通过podfile为单个目标添加多个平台支持?
例如,我的项目在iOS和Mac上都是通用的。它们使用相同的代码库。因此,我没有为相同的代码创建多个目标,而是在同一个目标中添加了对iOS和MacOSX的支持。它构建得很好。
现在我想通过Cocoapods添加一个依赖项。我创建了一个pod文件,并指定我的目标对pod的依赖项。这里讨论的pod以类似的方式支持多个平台,即单个目标。
但现在,在构建我的项目时,它在iOS上失败了。
在Podfile中为单个目标指定多个平台会产生错误。
如果我只指定平台为iOS或Mac,那么有问题的项目无法在其他平台上构建。
以前有没有人经历过这种情况?我如何通过播客文件为一个目标添加多个平台?
我知道我可以通过在我的项目中创建多个目标来实现它。但我想把它作为我最后的选择。

vaj7vani

vaj7vani1#

def import_pods

pod 'CorePlot'

end

target 'FirstAppWithMacOS' do
    # define your platform here.
    platform :ios, '9.0'
    import_pods
end

target 'FirstMacOSApp' do
    # define your platform here.
    platform :osx, '10.10'
    import_pods
end

见下图我的项目:

bcs8qyzn

bcs8qyzn2#

平台设备由目标Build SettingsArchitectures部分中的Base SDKSupported Platforms控制。如果您没有为macOS和iOS设备创建单独的两个目标,那么您应该只有一个选择来支持这些平台条目,即为macOS平台复制新的两个现有构建配置,然后您可以单独配置设置。
例如,您有一个现有的基于iOS的项目,并且有两个默认构建配置,分别名为DebugRelease。选择 * 主Xcode项目 * -〉选择 * 项目名称(此处不是目标名称)* -〉选择顶部的 * 信息 * 部分-〉点击Configurations部分下的+按钮-〉选择Duplicate "Debug"/"Release" Configuration-〉将其重命名为Debug-macOS/Release-macOS或其他文件,请将原始的Debug/Release也重命名为Debug-iOS/Release-iOS
现在,您有两对配置可用于调试和归档目标平台,而目标平台只有一个构建设置。您也可以为macOS开发创建一个新方案,只需确保在不同操作中选择正确的配置即可。
谈到cocoapods上的主Podfile,如果你自己维护了一个cocopods库,想把它作为依赖项添加进去,最好在你的podspec文件中同时支持macOS和iOS平台,当然,你需要兼容这些平台,AFNetworking就是这样做的。下面是主要的转换任务,不要使用UIKit for macOS平台下的任何API。为了区分编译时间的平台差异,您可以使用这些宏。

#if TARGET_OS_IOS
   // iOS supported
#elif TARGET_OS_OSX
   // macOS supported
#endif

如果你想在你的独立项目目标中使用第三方库,首先检查兼容性问题,如果它只适用于iOS平台,你可以像这样只为一个平台指定依赖库,

pod 'PonyDebugger', :configurations => ['Debug-iOS', 'Release-iOS']

与macOS支持相同。
希望能有所帮助!

bpzcxfmw

bpzcxfmw3#

简短的回答

从CocoaPods 1.10.2开始不支持IS。不支持IS是有原因的,而且可能不会很快支持,或者只有在使用Xcode 13构建时才支持。

长长的回答

当把一个pod集成到一个目标时,CocoaPods(CP)必须执行几个步骤来实现这一点,我不会在这里列出所有步骤,但以下四个步骤与这个答案相关:
1.创建伞形标头。
1.构建(动态/静态)框架或静态库。
1.将所述伞形头添加到所述目标的头搜索路径。
1.将构建的框架/库与目标进行比较。
让我逐一介绍这些步骤:

1.创建伞形标题

伞形头的内容取决于pod构建的平台。例如,如果是macOS,它将导入Cocoa,如果是iOS,它将导入UIKit。伞形头以特殊方式处理,特别是在使用模块时(当处理Swift代码时,你也会想要使用模块,相信我),使用#ifdef使它们的一部分依赖于平台是一个相当糟糕的主意。因此,为了支持多个平台,CP需要为每个平台创建一个伞形标头。
请注意,这正是CP所做的,如果你将同一个pod集成到两个不同平台的两个目标中。例如,如果一个目标是macOS,一个是iOS,则会有两个伞形头,一个以-macOS.h结尾,一个以-iOS.h结尾。因此,理论上,这个功能是存在的,到目前为止,还没有办法为每个目标指定多个平台,因此创建的伞形头只能用于一个目标平台。2这可能就是Vikas Dadheech所说的:
如果我只指定iOS或Mac平台
则所讨论的项目无法在其他平台上构建。
目前创建的头文件只能在两个平台上运行,请注意这也适用于任何自动生成的模块Map文件(.modulemap)。

2.构建(动态/静态)框架或静态库

与之前一样,如何构建库/框架取决于平台,因为Podspec文件可以根据平台指定不同的构建选项,甚至可以根据平台选择构建中包含的不同文件,pod必须根据平台单独构建,即使两个平台使用相同的CPU指令集(例如ARM Mac和ARM iPad),并且代码不包含任何平台特定的内容。
和以前一样,当将相同的pod集成到不同平台的不同目标中时,就会有此功能,从而产生两个带平台后缀的库/框架。

3.将伞状标头添加到目标的标头搜索路径

现在它变得有点棘手了。假设我们有两个伞形头文件(也可能有两个模块Map文件),当构建它们集成到的目标时,只有其中一个必须可见,而哪一个取决于目标平台。当我们讨论不同的目标时,这没有问题,因为每个目标的不同构建设置很容易,但在这种情况下,它是一个单一的目标,这带来了一些暗示。
然而,即使这是可以解决的,例如,通过使设置依赖于SDK,毕竟你将需要一个不同的SDK每个平台,所以你可以这样做:

HEADER_SEARCH_PATHS[sdk=macosx*] =  ....
HEADER_SEARCH_PATHS[sdk=iphoneos*] = ...

以确保只有正确平台的标头和Map文件对于构建可见。

4.喜欢构建的框架/库到目标

问题来了如果你想使用Xcode的链接,你可以链接到你在步骤2中构建的macOS或iOS版本,但你不能链接到任何一个,这取决于你构建的目标平台。那么你如何确保二进制链接到正确的库,并且只链接到其中一个库呢?
你可以...

  • 把所有版本合并成一个通用的二进制文件,并且总是链接到这个文件。2只要你的目标平台有不同的CPU架构,这个方法就可以工作(例如,Mac为x86,iOS为ARM),但如果您的平台相同,则无法正常工作(如ARM Mac和ARM iPhone),在ARM Mac的指导下,这个选项几乎是死的,它已经不可能之前,当你的两个目标是iOS和TVOS,因为都已经ARM,太。

  • 我根本不使用Xcode的链接,而是手动设置链接标志,以及使用与上面标题相同的技巧设置库搜索路径。好吧,这只适用于静态库和框架,并且只有在手动设置目标依赖关系的情况下,才能可靠地用于新的Xcode构建系统。使用动态框架,有时候还必须手动复制框架(重新)正确地签名它们,并且手工管理依赖项。所有这些都是可能的,但是看起来相当脆弱,并且可能比我上面提到的有更多的含义。我想这是一个有点风险的方法,有很多可能的陷阱,并且一些设置根本就不会那样工作,无论你做什么。

  • 使用Xcode 13的选择性链接功能。这正是这里所需要的,苹果可能已经实现了它,因为CPU架构不再适合许多链接情况。但Xcode 13目前仍处于测试阶段,如果该功能依赖于该功能,它将需要使用Xcode 13进行构建,这需要Mac运行至少大苏尔。

eivnm1vs

eivnm1vs4#

如果你想在Podfile的一个目标中支持多个平台,你可以使用platform指令来指定你想要支持的平台。

platform :ios, '9.0'
    platform :watchos, '3.0'

您还可以为每个平台指定最低版本和最高版本。

platform :ios, '9.0'..'14.0'
up9lanfz

up9lanfz5#

我在我的一个有3个目标的项目中做了同样的实现。我创建了“def”共享pod,然后在所有3个目标中调用这个shared_pod。这样,它工作得很好。我只为iOS应用程序做了。

# Uncomment the next line to define a global platform for your project
 platform :ios, '9.0'

def shared_pods
    pod 'Stripe'
    pod 'Google/SignIn'
end

target 'App_Dev' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

    shared_pods
 end

target 'App_QA' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

    shared_pods
 end

target 'App_Release' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

    shared_pods
 end

相关问题