为什么我的静态库会导致iOS链接器错误?

111

我在将混合语言框架连接到项目时遇到了问题。

  1. 我使用Swift和Objective-C类创建了一个框架。

  2. 主要逻辑存储在Swift文件中。例如,一个调用NSLog("Swift log was called")方法的类。

  3. Objective-C文件有一个类,其中包含一个方法,在该方法中我创建一个Swift类的实例并调用Swift-log方法。

  4. 我将这个框架与我的Objective-C项目链接起来,我可以在这个项目中调用所有我需要的东西,但是当我想要构建这个项目时,我会收到错误信息 linker command failed with exit code 1 (use -v to see invocation)

    还有警告:

ld: warning: Could not find auto-linked library 'swiftFoundation'
ld: warning: Could not find auto-linked library 'swiftDarwin'
ld: warning: Could not find auto-linked library 'swiftCoreFoundation'
ld: warning: Could not find auto-linked library 'swiftCore'
ld: warning: Could not find auto-linked library 'swiftCoreGraphics'
ld: warning: Could not find auto-linked library 'swiftObjectiveC'
ld: warning: Could not find auto-linked library 'swiftDispatch'
ld: warning: Could not find auto-linked library 'swiftSwiftOnoneSupport'

我也看到了通过导入空的Swift文件来解决问题的方法,但这会使项目中出现无用的文件。


@PhilippHolly 我需要一个不包含空文件的解决方案。 - Yaroslav Skachkov
很抱歉,我目前还没有找到任何解决方案。如果你找到了什么,请告诉我。 - phips28
你好,这个有什么解决方案吗? - Akila Devinda
21个回答

194
  1. 在Xcode中打开ios/YourAppName.xcodeproj
  2. 在左侧的项目导航器中右键单击“你的应用名称”,然后点击“新建文件…”
  3. 创建一个空的Swift文件并将其添加到项目中(确保在添加时选择了“你的应用名称”目标)
  4. 当Xcode询问时,按下“创建桥接头文件”,然后不要删除Swift文件。
  5. 重新运行构建。

这应该能解决问题。


2
如果我已经有一个现有的桥接头文件,问题仍然存在怎么办?我正在运行 MacOS MojaveXCode 11.3.1 - blastervla
如果你已经有桥接文件,有人可以解释一下吗? - bona912
4
Xcode 12.4没有要求创建桥接头文件(Bridging Header)。 - John Stuart

99

我的情况是在添加了Swift Pods库之后的React-Native项目。也许只需要第二步就可以:

  1. 添加一个新的Swift文件和一个桥接头文件:

1) 文件 -> 新建 -> 文件 <code>File -> New -> File</code>

2) 选择 Swift文件 Select <code>Swift File</code>

3) 确认 创建桥接头文件 enter image description here

  1. 进入构建设置并将始终嵌入Swift标准库设置为YES Always Embed Swift Standard Libraries

我应该把文件放在哪里,是在Pods文件夹下还是项目文件夹下? - lutakyn
@lutakyn 我已经把它放进项目中了。 - AlVelig
创建桥接文件后不要删除虚拟的Swift文件!保留它,否则构建将失败。 - Nader Ghanbari
2
步骤“创建桥接标头”对我不可见。它对我来说是“保存文件”。 - dcangulo
1
@dcangulo 只有当你的文件名包含 "bridging-header" 时,才会出现这些步骤。 - Luca Davanzo

93

显然,对于纯粹的Objective-C项目,您需要将$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)添加到目标的库搜索路径中。当我在将一个用Swift编写的库包含到一个Objective-C项目中时,这对我起作用了。


11
这个方法运行得非常完美!如果有人想知道具体怎么做的话,请按照以下步骤进行: 在文件浏览器中点击你的 Xcode 项目 -> 在“Targets”下选择你的目标 -> 选择“Build Settings”选项卡 -> 搜索 “Library Search Paths”,并将 $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) 添加到“Debug”和“Release”部分中。 - LarryFisherman
6
很遗憾,当使用Swift 5和Xcode 10.2时,这个技巧似乎已经失效了——可能是因为iOS 12.2现在有了系统范围的Swift库。 - megastep
4
对于那些刚接触Xcode的人,确保选择了“全部(All)”,并且它是蓝色的,否则您可能找不到库搜索路径。 - amar
1
尝试将以下内容添加到目标的库搜索路径中:$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) - gom1
1
它编译通过了,但是在应用程序启动时崩溃了:“此 libswiftCore.dylib 副本需要 12.2.0 之前的操作系统版本”。如果你想解决这个问题,只需在项目中添加一个空的 Swift 文件,保留它永远,然后它就能正常工作。(该问题源于您在应用中同时使用了 Objective-C 和 Swift 代码) - Fantasim
显示剩余3条评论

26

我已经导出了Unity项目。之前,只要添加一个空的Swift文件并按“创建Bridging Header”即可正常工作。

但最近我升级了我的Xcode到12.3版本,结果它就无法工作了。

因此,我尝试了其他几种方法。

我在“构建设置 > 搜索路径 > 库搜索路径”中添加了$(SDKROOT)/usr/lib/swift

但仍然不起作用。所以,我在相同的路径下添加了:

$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)

$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)

现在它可以完美地运行了。虽然没有找到确切的问题或解决方案,但是以这种方式可以正常运行。

我只是在“构建设置 > 搜索路径 > 库搜索路径”中添加了以下三个:

  1. $(SDKROOT)/usr/lib/swift
  2. $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)
  3. $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)

分别添加TOOLCHAIN_DIR目录无法使其工作。只有当我添加$(SDKROOT)/usr/lib/swift时,它才能正常工作。


14
在Xcode 12.5中经过测试,$(SDKROOT)/usr/lib/swift需要是第一个。 - xhg
2
谢谢,它适用于Xcode 13.1。 - Anonimys
1
谢谢,它适用于Xcode 13.2。 - moralejaSinCuentoNiProverbio
1
Xcode 13.4.1 - 它起作用了。谢谢! 我尝试了空的 Swift 文件,手动创建桥接头文件,删除这些行 - 什么都不起作用。 最终的解决方案包括将这3行添加到主目标中,并从另一个依赖于主目标的目标中删除这些行。 - Ruzard

22

对于 XCode 11 beta 4,库搜索路径应为:

$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)

1
我必须将此添加到每个目标的Library搜索路径属性中,而不仅仅是主应用程序。因此,包括我的手表套件和Siri意图目标。 - Tap Forms
1
任何带有 Swift 代码的目标都需要在 XCode 11 中具有上述路径。 - gom1
1
请注意,如果您仍在使用Xcode 12,它可能会破坏您的构建。 - scaly

15
  1. 右键项目名称,添加一个新的swift文件,并将其命名为File.swift。
  2. 它会要求你创建一个新的桥接头文件,请接受。
  3. 再次运行该项目。

13

3
你是第二个建议这种解决方案的人 : )。正如我在问题描述的评论中所说,我需要一个不需要空的Swift文件的解决方案。 - Yaroslav Skachkov

10

如果您在更新xCode到12版本后遇到了错误,比如

无法找到或使用自动链接的库“swiftWebKit”

还有两个错误。

只需将$(SDKROOT)/usr/lib/swift添加到构建设置>搜索路径>库搜索路径中即可。

希望可以帮到您:)


1
@SehiiVolynets,请使用斜体(使用 * 括号)来表示路径。 - maciejwww
@maciejwww,"italics"和"星号括号"是什么意思?应该使用哪一个? - easytarget
我是指StackOverflow上的格式化策略。使用星号括号可以将文本格式化为斜体:*text* --> text。对于GUI中的路径,建议使用斜体粗体(双星号:**text**)字体。然而,在这种情况下,我认为最好使用粗体字体而不是斜体。现在,我的评论已经不再需要,因为@Niko已经编辑了你的答案。请查看并与您的版本进行比较。有关文本格式和示例的简短信息,请单击此处。 - maciejwww
对我有用!感谢 Xcode 12.5 iOS 14.5。 - Robert Bentley

9

若您的 Xcode 版本 >= 12.2

请前往

构建设置(BuildSettings) -> 链接(Linking) -> 运行路径搜索路径(runpath search path)

并将 /usr/lib/swift 添加为第一个参数,如下所示:

enter image description here


有人能解释一下为什么要用-1吗?因为我试过这个方法后,只要改变一行代码就不需要再不停地清理=>重建了。注意:我还需要将“启用位码”设置为“否”。 - Cristiano Santos
对我来说运行得很好,非常感谢! - Patrick DaVader
在命令行上进行链接时,-L /usr/lib/swift 的效果非常好。这比使用等效的 -L $(SDKROOT)/usr/lib/swift 要短得多。谢谢! - tompark

7

Xcode 12.5,React Native。

更改:将“Library Search Paths”从Swift-5.0更改为Swift-5.2。enter image description here


非常感谢您!将库搜索路径从swift-5.0更改为swift-5.2使我的应用程序最终构建和运行(与手表应用程序或小部件无关)。 - Pauli Kettunen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接