【问题标题】:How to compile source that uses dylib path on macOS Sierra from the shell如何从 shell 编译在 macOS Sierra 上使用 dylib 路径的源代码
【发布时间】:2017-10-03 00:44:25
【问题描述】:

我正在编译一些源代码,这些源代码需要我已经构建的其他项目中的一些 dylib。我来了

ld:未找到架构 x86_64 的符号

每当我执行时

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

我知道 g++ 无法找到已编译的 dylib(安装在 /usr/local/include),因为该错误还提到了许多属于 dylib 的特定符号。

我已经试过了:

  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 graph library 编译教程示例。

缺少的符号与我安装的图形库有关。错误信息是:

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
  • 编辑您的问题以添加这些详细信息。
  • 要获得有关失败链接的帮助,您至少需要发布失败的链接命令行及其输出,逐字。关于你所做工作的粗略报告太模糊了,我们无法猜测。

标签: g++ macos-sierra dylib


【解决方案1】:

您可以设置-rpath 来搜索库。链接二进制文件后,您必须修改库的搜索路径,例如。 g.:

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 查看与您的可执行文件链接的所有库。

请参阅 ldinstall_name_tool 的手册页以获取有关 rpath 的更多信息。 install_name_tool 也可以用-add_rpath 添加更多的rpath。

【讨论】:

    【解决方案2】:

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

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

    您在编译二进制文件时会调用 -Wl,-undefined,dynamic_lookup

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

    然后添加 rpath 标志,在使用 @macmoonshine 显示的 install_name_tool 更改名称之后,但请确保指向正确的路径。默认情况下,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】:

      看起来您正在构建 x86_64 示例,您是否检查过您安装的 .dylib 也是 x86_64 的?

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-11
        • 2017-04-27
        • 2020-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-10
        相关资源
        最近更新 更多