即使添加到 /etc/ld.so.conf 并且 ldconfig 已运行,g++ 也无法在 /usr/local/lib/ 中找到 .so 文件

即使添加到 /etc/ld.so.conf 并且 ldconfig 已运行,g++ 也无法在 /usr/local/lib/ 中找到 .so 文件

我运行的是 Ubuntu 16.04。我有一个 C++ 源文件second.cpp,如下所示:

#include <iostream>
#include <boost/filesystem/operations.hpp>

namespace bfs = boost::filesystem;

int main(){
    bfs::path p("second.cpp");
    if (bfs::exists(p))
        std::cout << p.leaf() << std::endl;
}

当我运行时$ g++ -o second second.cpp,我得到以下信息:

/tmp/ccyWlRx6.o: 在函数boost::filesystem::path::leaf() const': second.cpp:(.text._ZNK5boost10filesystem4path4leafEv[_ZNK5boost10filesystem4path4leafEv]+0x2e): undefined reference toboost::filesystem::path::filename() const' /tmp/ccyWlRx6.o: 在函数 boost boost::filesystem::exists(boost::filesystem::path const&)': second.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x2f): undefined reference to::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)' collect2: 错误:ld 返回 1 退出状态

但是,如果我运行g++ -o second second.cpp -lboost_filesystem,代码编译时不会出现错误。libboost_filesystem.alibboost_filesystem.so、 和libboost_filesystem.so.1.67.0都在 中/usr/local/lib

/etc/ld.so.conf看起来像这样:

include /etc/ld.so.conf.d/*.conf
/usr/local/lib

我已经跑了sudo ldconfig

这是正常行为吗?根据我所读到的内容,在我看来,/usr/local/lib链接器应该自动包含其中的文件。如果情况并非如此,有什么方法可以实现这一目标吗?感谢您的帮助!

答案1

这是正常行为吗?

当然如此。如果您不告诉编译器驱动程序-l boost_filesystem甚至寻找与其链接的库,它就不会这样做,并且使用该库的程序将不会链接,正如您所看到的。你的编译器并不神奇。如果您的程序需要链接编译器默认识别的 C/C++/GCC 运行时库以外的库,则需要告诉编译器该库。

你的问题的标题是一个谎言。正如你所观察到的……

我运行g++ -o second second.cpp -lboost_filesystem,代码编译没有错误。

…g++找到库/usr/local/lib: 一旦你正确地执行操作并实际告诉它要查找的库的名称。

另请注意,出于同样的原因,讨论-L是转移注意力的。你没有使用-L,但 g++ 找到了这个库反正;所以包含库的目录不在编译器的默认库搜索路径中显然没有问题。

既然你甚至没有尝试过跑步该程序,根据你的问题,动态加载器是否找到该库存在未知。但它可能会。

答案2

如果你想让链接器在不寻常的位置找到库,你需要使用一个-L选项来指定库所在的目录。

如果您希望运行时链接器在运行时查找相同的库,请使用链接器向二进制文件-R添加标签。RUNPATH

ldconfig 在 20 世纪 80 年代使用这种a.out格式,因为它没有RUNPATH添加到ELF.

答案3

我认为您似乎需要在 /etc/ld.so.conf.d 下创建一个配置文件,
而不是将条目添加到 /etc/ld.so.conf 中。

/etc/ld.so.conf 从 /etc/ld.so.conf.d
目录读取所有配置文件,该目录包含库文件路径的配置文件。
配置文件名称不是由系统定义的,因此您可以将其命名为
任何您想要的名称,例如locallib.conf
所以,像这样的事情,

/etc/ld.so.conf.d/locallib.conf

包含
/usr/local/lib

然后跑完之后ldconfig

其他方式。
这仅启用本地环境(不是系统全局)。
将库路径条目添加到您的.bashrc.

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH

通过 启用环境变量
. ./.bashrc
请不要忘记使用以下命令检查变量。

echo $LD_LIBRARY_PATH

相关内容