c++ - 有没有一种智能的方法可以在编译时知道要链接到的库的名称? (Linux/库本图)

标签 c++ compilation linked-list libraries

请多多包涵。我真的很想知道,因为我很好奇答案:

有没有一种智能的方法可以在编译时知道要链接到的库的名称?

请允许我举一个例子,完美地说明我提出问题的原因。

我是 C++ 新手。我正在学习编译、链接和诸如 boost 之类的库。我刚刚发现了 boost/filesystem 并想尝试一下。编译时遇到麻烦,我使用了以下极简代码:


// file boost_example.cpp
 #include "boost/filesystem.hpp"<br/>
 #include <iostream><p></p>

<p>int main()
{
        std::cout<<"Hello";
        return 0;
}
</p>

我试图编译它,但是作为一个新手,我犯了一个新手错误:我忘记链接到正确的库!

     g++ boost_example.cpp -o run

确切地说,我遇到了 this chapter of this fine book 中解释的问题。 .
我知道我已经安装了 boost(我被告知要安装它来编译另一个项目)。我试图从其他项目的 Makefile 中复制,但以下内容不起作用:
<pre> g++ boost_example.cpp -o run -lbooster</pre> <pre> g++ boost_example.cpp -o run -lboost</pre> 试图从代码中的#include 行做出有根据的猜测,我尝试了以下方法无济于事: <pre> g++ boost_example.cpp -o run -lboost_filesystem</pre> 到那时,我已经开始疯狂地搜索网络。我讨厌搜索引擎,因为大多数时候,你找不到你要找的东西。我找到了以下内容,但他们无济于事,浪费了我的时间:
Boost library link problem under kubuntu
C++/Boost linker errors

由于我是一个 RTFM 类型的人,我实际上已经查看了我想使用的库的官方文档:http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm但我没有找到任何编译信息。

在某个阶段,我受到启发来检查我在系统上实际安装的内容:

$ locate boost_file
/usr/lib/libboost_filesystem-mt.a
/usr/lib/libboost_filesystem-mt.so
/usr/lib/libboost_filesystem-mt.so.1.38.0
因此,我找到了要链接的库的正确名称。以下工作:
<pre> g++ boost_example.cpp -o run -lboost_filesystem-mt</pre>

现在,除了使用(可能)智能猜测工作和搜索网络之外,还有更智能的方法来查找要链接的库的名称吗?我永远猜不到库名 boost_filesystem-mt给定标题 "boost/filesystem.hpp" .

更糟糕的是:boost_filesystem-mt is not mentioned anywhere在官方网站上! (我猜它取决于发行版/打包)。

再一次,我在提问之前总是先说明 RTFM,我发现 this chapter of the aforementioned book ,所以我在/usr/lib/的系统上检查了我能找到的内容:

$ ls /usr/lib/<em>boost</em>
/usr/lib/libboost_date_time-mt.a           /usr/lib/libboost_prg_exec_monitor-mt.so.1.38.0
/usr/lib/libboost_date_time-mt.so          /usr/lib/libboost_program_options-mt.a
/usr/lib/libboost_date_time-mt.so.1.38.0   /usr/lib/libboost_program_options-mt.so
/usr/lib/libbooster.a                      /usr/lib/libboost_program_options-mt.so.1.38.0
/usr/lib/libbooster.so                     /usr/lib/libboost_python-mt.a
/usr/lib/libbooster.so.0                   /usr/lib/libboost_python-mt-py25.a
/usr/lib/libbooster.so.0.0.0               /usr/lib/libboost_python-mt-py25.so
/usr/lib/libboost_filesystem-mt.a          /usr/lib/libboost_python-mt-py25.so.1.38.0
/usr/lib/libboost_filesystem-mt.so         /usr/lib/libboost_python-mt-py26.a
/usr/lib/libboost_filesystem-mt.so.1.38.0  /usr/lib/libboost_python-mt-py26.so
/usr/lib/libboost_graph-mt.a               /usr/lib/libboost_python-mt-py26.so.1.38.0
/usr/lib/libboost_graph-mt.so              /usr/lib/libboost_python-mt.so
/usr/lib/libboost_graph-mt.so.1.38.0       /usr/lib/libboost_regex-mt.a
/usr/lib/libboost_iostreams-mt.a           /usr/lib/libboost_regex-mt.so
/usr/lib/libboost_iostreams-mt.so          /usr/lib/libboost_regex-mt.so.1.38.0
/usr/lib/libboost_iostreams-mt.so.1.38.0   /usr/lib/libboost_serialization-mt.a
/usr/lib/libboost_math_c99f-mt.a           /usr/lib/libboost_serialization-mt.so
/usr/lib/libboost_math_c99f-mt.so          /usr/lib/libboost_serialization-mt.so.1.38.0
/usr/lib/libboost_math_c99f-mt.so.1.38.0   /usr/lib/libboost_signals-mt.a
/usr/lib/libboost_math_c99l-mt.a           /usr/lib/libboost_signals-mt.so
/usr/lib/libboost_math_c99l-mt.so          /usr/lib/libboost_signals-mt.so.1.38.0
/usr/lib/libboost_math_c99l-mt.so.1.38.0   /usr/lib/libboost_system-mt.a
/usr/lib/libboost_math_c99-mt.a            /usr/lib/libboost_system-mt.so
/usr/lib/libboost_math_c99-mt.so           /usr/lib/libboost_system-mt.so.1.38.0
/usr/lib/libboost_math_c99-mt.so.1.38.0    /usr/lib/libboost_thread-mt.a
/usr/lib/libboost_math_tr1f-mt.a           /usr/lib/libboost_thread-mt.so
/usr/lib/libboost_math_tr1f-mt.so          /usr/lib/libboost_thread-mt.so.1.38.0
/usr/lib/libboost_math_tr1f-mt.so.1.38.0   /usr/lib/libboost_unit_test_framework-mt.a
/usr/lib/libboost_math_tr1l-mt.a           /usr/lib/libboost_unit_test_framework-mt.so
/usr/lib/libboost_math_tr1l-mt.so          /usr/lib/libboost_unit_test_framework-mt.so.1.38.0
/usr/lib/libboost_math_tr1l-mt.so.1.38.0   /usr/lib/libboost_wave-mt.a
/usr/lib/libboost_math_tr1-mt.a            /usr/lib/libboost_wave-mt.so
/usr/lib/libboost_math_tr1-mt.so           /usr/lib/libboost_wave-mt.so.1.38.0
/usr/lib/libboost_math_tr1-mt.so.1.38.0    /usr/lib/libboost_wserialization-mt.a
/usr/lib/libboost_prg_exec_monitor-mt.a    /usr/lib/libboost_wserialization-mt.so
/usr/lib/libboost_prg_exec_monitor-mt.so   /usr/lib/libboost_wserialization-mt.so.1.38.0

现在我很难过,因为我真的不知道如何将上述内容与 list of boost libraries 关联起来。 .

我为这个冗长的例子道歉,但它完美地说明了我的问题:

除了猜测、搜索网络、询问其他人、反复试验等...有没有更智能的方法来找到一个应该链接到的库的名称?不是吗?那些应该记录在某处的东西?

我当然有兴趣知道关于 boost 的答案,但我的问题更笼统,适用于任何库。

顺便说一句,我对 linux 软件包的名称(无论是 .deb 还是 .rpm)有一个非常相似的问题。如果我被告知要编译我需要的某个或某个软件,例如PRCE 或FooBar,我如何准确知道要安装的软件包的名称?我知道如何使用 apt-cache(用于 Kubuntu debs),但一些包命名并不直观,我经常最终安装我并不真正需要的包......

最佳答案

我有时会使用一种蛮力方法,但您必须知道在哪些目录中查找您需要的库(/lib、/usr/lib 和/usr/local/lib 是通常的嫌疑人) .我创建了一个 shell 脚本,我称之为“gnm”(“grep nm”的缩写,它使用的两个实用程序),内容如下。如果您创建这样的文本文件,请记住使其可执行(chmod +x gnm)。

#!/bin/sh
if [ $# -lt 2 ] ; then
  echo Usage: $0 pattern file[s]
  exit
fi
pattern=$1
shift
while [ $# -gt 0 ] ; do
  nm $1 | grep $pattern > /dev/null
  if [ $? -eq 0 ] ; then
    echo $1
  fi
  shift
done

当我搜索定义特定符号的库时,我会发出类似以下的命令:

gnm symbol /usr/lib/*.a 

例如,您提到的来源给了我以下链接错误:

boost_example.cpp:(.text+0x38): undefined reference to `boost::system::get_system_category()'
boost_example.cpp:(.text+0x44): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x50): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x5c): undefined reference to `boost::system::get_generic_category()'
boost_example.cpp:(.text+0x68): undefined reference to `boost::system::get_system_category()'

所以我使用命令:

gnm get_system_category /usr/lib/*.a

报告:

/usr/lib/libboost_filesystem.a
/usr/lib/libboost_system.a

尝试其中的第一个会导致相同的错误,但第二个有效:

g++ boost_example.cpp -lboost_system -o run

我不知道为什么我需要你需要文件系统的系统库;可能是不同版本的 Boost。

关于c++ - 有没有一种智能的方法可以在编译时知道要链接到的库的名称? (Linux/库本图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3467153/

相关文章:

包含宏的 C++ 方法声明

java - 编译模拟器的问题(java)

Java 泛型类型在没有中间变量的情况下失败

c - 如何正确添加到链表数组?

c++ - 类范围内的二维 vector

java - C++ 和 Java 应用程序的最佳数据库

compilation - 如果从命令行运行 Julia 脚本,是否每次都需要重新编译?

c++ - 在编译时不知道返回类型时如何避免向下转换?

c - 如何使用 O(N) 空间复杂度在链表中查找循环

c++ - 请告诉我这段代码有什么问题