如何在macOS Sierra上从shell编译使用dylib路径的源代码

11
我正在编译一些需要其他已构建项目中的dylibs的源代码。我遇到了以下错误:

ld: 找不到符号以供架构x86_64使用

每当我执行时。

g++ some_code.cpp -I/usr/local/include -o executable_binary

我知道 g++ 无法找到已编译的动态库(安装在 /usr/local/include),因为错误还提到了很多特定的符号,这些符号是动态库的一部分。

我已经尝试过:

  1. 执行 install_name_tool -id "@/usr/local/lib/requiredlib.dylib" /usr/local/lib/requiredlib.dylib
  2. -L/usr/local/lib 添加到编译选项中。
  3. 显式添加所有 dylib 路径到编译选项中。
  4. 尝试添加 DYLD_LIBRARY_PATH,但由于 Sierra 不允许出于安全原因设置该变量,因此不成功。

我知道可能可以添加 DYLD_LIBRARY_PATH,但那需要禁用 SIP。我可以这样做,但如果有更干净的方法,我就不想这样做。

P.S.:我正在尝试编译 Tulip 图形库 的教程示例。

缺失的符号与我安装的图形库有关。错误消息如下:

Undefined symbols for architecture x86_64:
  "tlp::saveGraph(tlp::Graph*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, tlp::PluginProgress*)", referenced from:
      _main in tutorial001-02ee7e.o
  "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, tlp::Graph const*)", referenced from:
      _main in tutorial001-02ee7e.o
ld: symbol(s) not found for architecture x86_64

无论何时我执行ls /usr/local/lib/requiredlib.dylib,都会看到Tulip编译的所有库。

g++ -v输出:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

执行ls /usr/local/include/tulip/命令后,我可以获取到我打算使用的库的*.h文件列表。


不太清楚您缺少哪些符号,使用哪个版本的g ++等。而且,您编译的库肯定没有安装在 /usr/local/include 中。 - pvg
1
编辑你的问题并添加这些细节。 - pvg
要获得无法链接的帮助,您需要至少发布失败的链接命令行及其输出,逐字逐句。模糊的报告无法使我们超越猜测。 - Mike Kinghan
3个回答

6

此外,您还可以查看ldundefined选项。

指定如何处理未定义符号。选项有:error、warning、suppress或dynamic_lookup。默认值为error。

在编译二进制文件时,您可以像这样调用它:-Wl,-undefined,dynamic_lookup

您还可以利用-lazy-lx-lazy-library path,以便在调用其中第一个函数之前不会加载库,这在某些情况下可能会有所帮助。

然后,在使用install_name_tool更改名称后,还需要添加rpath标志,但请确保将其指向正确的路径。默认情况下,Tulip安装在默认库文件夹/usr/local中,但在安装指南中建议将其安装在用户管理的目录中。

对于Tulip所需的所有库,可以使用以下命令:

install_name_tool -change ./build-release/lib/libtulip-core-4.11.dylib '@rpath/libtulip-core-4.11.dylib' tutorial001

在编译教程时,同时使用-Wl,-rpath,./build-release/lib


3
您可以设置-rpath来搜索库。在链接二进制文件后,您需要修改库的搜索路径,例如:
g++ some_code.cpp -I/usr/local/include -o binary \
    -L/usr/local/lib -lrequiredlib -Wl,-rpath,/usr/local/lib
install_name_tool -change /usr/local/lib/librequiredlib.dylib \
    '@rpath/librequiredlib.dylib' binary
install_name_tool 命令会更改二进制文件中的库名称,以便在 rpath 中搜索该库。如果您不确定正确的名称,请使用 otool -L binary 查看与可执行文件链接的所有库。
有关 rpath 的更多信息,请查看 ldinstall_name_tool 的 man 页面。 install_name_tool 也可以使用 -add_rpath 添加更多 rpaths。

0

看起来你正在构建x86_64示例,你检查一下你安装的.dylibs也是x86_64了吗?

使用otoolfile命令确定你的dylibs是x86_64。例如,尝试像这样运行file /usr/local/lib/requiredlib.dylib。如果你在输出中没有看到这个:

requiredlib.dylib(用于架构x86_64):Mach-O 64位动态链接共享库x86_64

那么你的问题就是在构建库和构建应该使用这些库的代码时不匹配的架构。


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