导入 Swift 包管理器依赖项时出现 'no such module' 错误
Getting 'no such module' error when importing a Swift Package Manager dependency
我是 运行 Xcode 11 Beta 4。
我正在使用 CocoaPods,并希望将我的依赖项之一与 Swift 包管理器一起用作静态库而不是框架。
在使用 Xcode 11 创建的新项目上,可以成功导入依赖项,但在我现有的 CocoaPods 工作区上,却没有。
我认为这可能相关,但我也在 Xcode 中收到此 link 警告:
directory not found for option '-L/Users/username/Library/Developer/Xcode/DerivedData/App-axanznliwntexmdfdskitsxlfypz/Build/Products/Release-iphoneos
报警后我去查看目录是否存在,确实存在。
除了 CocoaPods 的存在之外,我在新创建的项目和我的旧项目之间找不到任何有意义的区别。
不胜感激。
事实证明,Swift 包管理器隐式依赖于项目的配置名称。我把它们放在 live/qa 而不是 Release/Debug,将它们改回去解决了这个问题。很奇怪,但我希望它能为你省去一些麻烦,亲爱的 reader。
在解决这个问题整整一周之后,我开发了一个使用方案和预操作的解决方法。
我有一个名为 "Beta" 的配置,所以 Xcode 无法编译 SPM 依赖项。我意识到 Xcode 将 SPM 依赖项编译为 Swift 模块并将文件添加到 DeriverData 的 Build/Products/Release-iphoneos 文件夹中。
所以我在 Xcode 中创建了一个方案,并在构建预操作中添加了这个 运行 脚本:
cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"
此脚本 运行 在构建过程之前,将 Xcode 默认生成的文件和模块复制到 Release-iphoneos 文件夹到配置文件夹,Beta-iphoneos,就我而言。
将 Release-iphoneos 中的内容复制到您的 $configuration$-iphoneos 文件夹后 Xcode 应该可以正确编译、构建和 运行 您的项目。
根据@AlexandreMorgado 的回答,似乎最好在编译源代码之前的构建阶段运行 此脚本。然后存档的时候就可以了
if [ -d "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" ] && [ "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" != "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/" ]
then
cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"
fi
为了保持增量构建工作,我必须像这样指定 "Fix SPM" 构建阶段的输出文件:
清除派生数据解决了我的问题。我有 Microsoft Azure Devops CI 管道,要清除派生数据我必须编辑 Xcode 构建任务并在“操作”字段中添加此命令:clean
.
在通过 Swift 包管理器添加库(在我的例子中是 FASwiftUI 之后,我不得不将它添加到
项目设置 -> 常规 -> 我的目标 ->
Frameworks, Libraries, and Embedded Content
在导入语句中可见。
我没有为它添加任何脚本。
我刚刚 运行 遇到了类似的问题,发现我的方案引用了旧配置,即不再存在的配置。一旦我将它们更新为正确的配置,构建就成功了。
(我在最初 post 一年多后才发表此评论。可能我 运行 的内容与最初报道的内容完全不同。不过,我花了很多时间花了很长时间来追踪问题,所以我想留下一张纸条,可能会节省其他人的时间。)
对我有用的方法:我删除了 import WebMIDIKit
行并重新添加了它。
我刚刚 运行 从命令行 运行 xcodebuild
遇到了类似的问题。我正在传递 CONFIGURATION_BUILD_DIR=build
但发现它需要是 绝对路径: CONFIGURATION_BUILD_DIR=$(pwd)/build
解决了问题。
解决方案
let package = Package(
name: "PackageName",
dependencies: [
// YOU MUST ADD THE DEPENDENCY BOTH HERE [1] AND BELOW [2]
.package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
],
targets: [
.target(
name: "PackageName",
/*[2]*/ dependencies: ["FASwiftUI"], // [2] <<<--------- Added here as well
]
)
说明
我正在开发一个 Swift 包,它必须向任何导入它的人提供 FontAwesome 图标。
我的 SwiftUI 预览 canvas.
中显示“没有这样的模块 'FASwiftUI'”
我通过将“FASwiftUI”添加到 BOTH 包的依赖项数组 AS WELL AS 到 目标本身 .
中的依赖项数组
完整Package.swift 文件
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "PackageName",
platforms: [
.macOS(.v11),
.iOS(.v14)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "PackageName",
targets: ["PackageName"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/nalexn/ViewInspector", from: "0.8.1"),
.package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "PackageName",
dependencies: ["FASwiftUI"], // <<<--------- Added this here
resources: [
.process("Assets")
]
),
.testTarget(
name: "PackageNameTests",
dependencies: ["PackageName", "ViewInspector"])
]
)
根据@sliwinski.lukas的回答,在我的例子中,${CONFIGURATION} 正在输出“Release”,所以它只是复制 Release 文件夹本身,这并不好。我只是硬编码了我的配置名称,并翻转了 Release 和 MyConfiguration,它就起作用了。我将以下代码放在“构建阶段”选项卡中的“编译源代码”之前:
cp -f -R "${SYMROOT}/MyConfiguration${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" || true
同样重要的是,我必须将它添加到使用 SPM 的项目中,而不是在主应用程序中。
我可以更清楚地了解你的困境吗...
我正在开发一个相当大的 iOS 应用程序(6680 个文件),其结果由许多框架和混合包的 podfiles、swift 包、遗留 ObjC 代码(仍然数量超过更新的 Swift 东西)。
每当我们处理 swift 包时,我们都需要将它们包装在框架中,因为当我们的远程 (Jenkins) 构建系统吞噬所有内容以生成二进制文件以进行内部质量检查时,它会简化 podfile 和依赖项解析 &最终,企业和 AppStore 发布。
今天早些时候,我正在处理一个这样的 swift 包装在框架中的包,上面列出的所有问题都让我感到震惊。
在存储、推送可用代码然后将我存储的框架包装器重新应用到 swift 包之后,我使用了不同于打开项目工作区的路径,其中收集了一堆项目和目标。
打开单独的框架包装器似乎已将 XCode (13.3.1) 踢入提交状态,此时,目标设置“框架、库和可嵌入”部分实际上能够显示 swift 包的“Foo”二进制文件。添加它,然后一切都很好。
因此,如果您仍然遇到问题,请尝试通过打开较小的小块来简化问题。或者开始制作这些包装器框架(如果可能的话),这样您就可以在将它们集成到 XC 的盘子上之前实际管理更小的部分。
我是 运行 Xcode 11 Beta 4。 我正在使用 CocoaPods,并希望将我的依赖项之一与 Swift 包管理器一起用作静态库而不是框架。 在使用 Xcode 11 创建的新项目上,可以成功导入依赖项,但在我现有的 CocoaPods 工作区上,却没有。
我认为这可能相关,但我也在 Xcode 中收到此 link 警告:
directory not found for option '-L/Users/username/Library/Developer/Xcode/DerivedData/App-axanznliwntexmdfdskitsxlfypz/Build/Products/Release-iphoneos
报警后我去查看目录是否存在,确实存在。 除了 CocoaPods 的存在之外,我在新创建的项目和我的旧项目之间找不到任何有意义的区别。
不胜感激。
事实证明,Swift 包管理器隐式依赖于项目的配置名称。我把它们放在 live/qa 而不是 Release/Debug,将它们改回去解决了这个问题。很奇怪,但我希望它能为你省去一些麻烦,亲爱的 reader。
在解决这个问题整整一周之后,我开发了一个使用方案和预操作的解决方法。
我有一个名为 "Beta" 的配置,所以 Xcode 无法编译 SPM 依赖项。我意识到 Xcode 将 SPM 依赖项编译为 Swift 模块并将文件添加到 DeriverData 的 Build/Products/Release-iphoneos 文件夹中。
所以我在 Xcode 中创建了一个方案,并在构建预操作中添加了这个 运行 脚本:
cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"
此脚本 运行 在构建过程之前,将 Xcode 默认生成的文件和模块复制到 Release-iphoneos 文件夹到配置文件夹,Beta-iphoneos,就我而言。
将 Release-iphoneos 中的内容复制到您的 $configuration$-iphoneos 文件夹后 Xcode 应该可以正确编译、构建和 运行 您的项目。
根据@AlexandreMorgado 的回答,似乎最好在编译源代码之前的构建阶段运行 此脚本。然后存档的时候就可以了
if [ -d "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" ] && [ "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" != "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/" ]
then
cp -f -R "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/"
fi
为了保持增量构建工作,我必须像这样指定 "Fix SPM" 构建阶段的输出文件:
清除派生数据解决了我的问题。我有 Microsoft Azure Devops CI 管道,要清除派生数据我必须编辑 Xcode 构建任务并在“操作”字段中添加此命令:clean
.
在通过 Swift 包管理器添加库(在我的例子中是 FASwiftUI 之后,我不得不将它添加到
项目设置 -> 常规 -> 我的目标 ->
Frameworks, Libraries, and Embedded Content
在导入语句中可见。
我没有为它添加任何脚本。
我刚刚 运行 遇到了类似的问题,发现我的方案引用了旧配置,即不再存在的配置。一旦我将它们更新为正确的配置,构建就成功了。
(我在最初 post 一年多后才发表此评论。可能我 运行 的内容与最初报道的内容完全不同。不过,我花了很多时间花了很长时间来追踪问题,所以我想留下一张纸条,可能会节省其他人的时间。)
对我有用的方法:我删除了 import WebMIDIKit
行并重新添加了它。
我刚刚 运行 从命令行 运行 xcodebuild
遇到了类似的问题。我正在传递 CONFIGURATION_BUILD_DIR=build
但发现它需要是 绝对路径: CONFIGURATION_BUILD_DIR=$(pwd)/build
解决了问题。
解决方案
let package = Package(
name: "PackageName",
dependencies: [
// YOU MUST ADD THE DEPENDENCY BOTH HERE [1] AND BELOW [2]
.package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
],
targets: [
.target(
name: "PackageName",
/*[2]*/ dependencies: ["FASwiftUI"], // [2] <<<--------- Added here as well
]
)
说明
我正在开发一个 Swift 包,它必须向任何导入它的人提供 FontAwesome 图标。
我的 SwiftUI 预览 canvas.
中显示“没有这样的模块 'FASwiftUI'”我通过将“FASwiftUI”添加到 BOTH 包的依赖项数组 AS WELL AS 到 目标本身 .
中的依赖项数组完整Package.swift 文件
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "PackageName",
platforms: [
.macOS(.v11),
.iOS(.v14)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "PackageName",
targets: ["PackageName"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/nalexn/ViewInspector", from: "0.8.1"),
.package(url: "https://github.com/mattmaddux/FASwiftUI", from: "1.0.4")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "PackageName",
dependencies: ["FASwiftUI"], // <<<--------- Added this here
resources: [
.process("Assets")
]
),
.testTarget(
name: "PackageNameTests",
dependencies: ["PackageName", "ViewInspector"])
]
)
根据@sliwinski.lukas的回答,在我的例子中,${CONFIGURATION} 正在输出“Release”,所以它只是复制 Release 文件夹本身,这并不好。我只是硬编码了我的配置名称,并翻转了 Release 和 MyConfiguration,它就起作用了。我将以下代码放在“构建阶段”选项卡中的“编译源代码”之前:
cp -f -R "${SYMROOT}/MyConfiguration${EFFECTIVE_PLATFORM_NAME}/" "${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/" || true
同样重要的是,我必须将它添加到使用 SPM 的项目中,而不是在主应用程序中。
我可以更清楚地了解你的困境吗...
我正在开发一个相当大的 iOS 应用程序(6680 个文件),其结果由许多框架和混合包的 podfiles、swift 包、遗留 ObjC 代码(仍然数量超过更新的 Swift 东西)。
每当我们处理 swift 包时,我们都需要将它们包装在框架中,因为当我们的远程 (Jenkins) 构建系统吞噬所有内容以生成二进制文件以进行内部质量检查时,它会简化 podfile 和依赖项解析 &最终,企业和 AppStore 发布。
今天早些时候,我正在处理一个这样的 swift 包装在框架中的包,上面列出的所有问题都让我感到震惊。
在存储、推送可用代码然后将我存储的框架包装器重新应用到 swift 包之后,我使用了不同于打开项目工作区的路径,其中收集了一堆项目和目标。
打开单独的框架包装器似乎已将 XCode (13.3.1) 踢入提交状态,此时,目标设置“框架、库和可嵌入”部分实际上能够显示 swift 包的“Foo”二进制文件。添加它,然后一切都很好。
因此,如果您仍然遇到问题,请尝试通过打开较小的小块来简化问题。或者开始制作这些包装器框架(如果可能的话),这样您就可以在将它们集成到 XC 的盘子上之前实际管理更小的部分。