【问题标题】:Xcode "ld: library not found [...] for architecture x86_64"Xcode “ld: library not found [...] for architecture x86_64”
【发布时间】:2016-05-21 03:48:58
【问题描述】:

我想在我的 swift-project 中包含 libgpg-error 和 libgcrypt 并创建了以下 module.modulemaps:

libgpg错误:

module libgpgerror {
    header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/gpg-error.h"
    link "'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib'"
    export *
}

libgcrypt:

module libgcrypt {
    header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
    link "'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/libgcrypt-1.6.5.dylib'"
    export *
}

我还在项目和目标中添加了“Swift 编译器 - 搜索路径/导入路径”:/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/**。 模块已找到,路径正确。

但是,如果我想编译项目,我会收到以下错误:

ld: library not found for -l'/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib' for architecture x86_64

如果我这样做了

file /Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib

我得到了输出

/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/libgpgerror-1.21.dylib: Mach-O 64-bit dynamically linked shared library x86_64

所以看来图书馆在正确的地方,也有正确的架构。


编辑

我找到了一种解决方法:我从模块映射中删除了链接指令并手动链接了库;这似乎有效。但为什么呢?

module libgpgerror {
    header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgpgerror/gpg-error.h"
    export *
}

【问题讨论】:

  • 你在使用 Swift 包管理器吗?您是如何手动链接库的?
  • 我能够通过在 swift build 命令中明确指定 dylib 路径来构建它。 swift build -Xlinker -L/usr/local/lib/ -Xcc -I/usr/local/include/
  • 如果你不添加链接指令,你可以指定-luv 标志并生成一个xcodeproj,它将设置必要的标志:swift build -Xlinker -L/usr/local/lib/ -Xcc -I/usr/local/include/ -Xlinker -luv --generate-xcodeproj
  • 我不使用包管理器;我“手动”编译了 libgpgerror(使用make)。要手动链接库,我只是将 dylib 拖到 Xcode 并确保它已添加到我项目目标中的 Linked Frameworks and Libraries-section。

标签: xcode build shared-libraries ld


【解决方案1】:

链接指令仅指定链接库的名称。也就是说,它应该为库指定链接器标志的后缀。该指令似乎采用“-l”并连接名称以生成链接器标志。

这意味着指定模块映射的正确方法如下。

module CGcrypt {
    header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
    link "gcrypt"
    export *
}

这将生成链接器标志-lgcrypt,这是正确的链接器标志。

但是,还有另一个问题是链接器需要能够找到 gcrypt 的 dylib 文件,并且默认情况下它只查看某些路径。这些路径可以通过运行clang -Xlinker -v 找到。我的输出如下所示:

tylercloutier$ clang -Xlinker -v
@(#)PROGRAM:ld  PROJECT:ld64-264.3.101
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
Library search paths:
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/lib
... more stuff ...

现在我不确定,但我怀疑正常的搜索路径可能是

/usr/lib
/usr/local/lib

但我认为 Xcode 已将我的搜索路径更改为指向 MacOSX10.11.sdk/usr/lib,顺便说一下,它与 /usr/lib 具有基本相同的文件集(它们没有符号链接)。事实上,在 El Capitan 中,由于系统完整性保护,即使 sudo 也不允许您编辑 /usr/lib

因此,我遇到的问题是,即使我已将库安装到 /usr/local/lib,clang 也无法链接它们。为了解决这个问题,我可以明确指定搜索路径。

swift build -Xlinker -L/usr/local/lib/

我们要去参加比赛了。我什至可以生成一个 xcodeproj,它已经在Other Linker Flags 中设置了适当的链接器标志。

swift build -Xlinker -L/usr/local/lib/ --generate-xcodeproj

如果您在模块映射文件中省略了链接指令,您可以将其指定为标志:

module CGcrypt {
    header "/Volumes/Xcode/Programme/Swifts/KCAnon/KCAnon_Client/Libs/libgcrypt/gcrypt.h"
    export *
}

像这样

swift build -Xlinker -L/usr/local/lib/ -lgcrypt

如何更改默认库搜索路径,我不知道。但是,如果其他人可以阐明这件事,那就太好了!

【讨论】:

  • 至少在 Xcode 中,您可以简单地添加另一个库搜索路径。该解决方案有效; ??️