是否有一种智能方法可以在编译时知道要链接到的库的名称? (Linux的/ Kubuntu的)

时间:2010-08-12 11:33:11

标签: c++ compilation linked-list libraries

请耐心等待。我真的想知道,因为我对答案感到好奇:

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

请允许我举一个例子,说明我提问的原因。

我是C ++新手。我正在学习编译,链接和像boost这样的库。我刚刚发现了boost / filesystem并想尝试一下。遇到麻烦后,我使用了以下极简主义代码:


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

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

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

     g++ boost_example.cpp -o run

确切地说,我遇到了this chapter of this fine book中解释的问题 我知道我已经安装了升级版(我被告知安装它来编译另一个项目)。我试图从其他项目的Makefile中复制,但以下内容不起作用:
     g++ boost_example.cpp -o run -lbooster
     g++ boost_example.cpp -o run -lboost
试图从代码中的#include行做出有根据的猜测,我尝试了以下无济于事:
     g++ boost_example.cpp -o run -lboost_filesystem
到那时,我开始疯狂地搜索网页。我讨厌搜索引擎,因为大多数时候,你找不到你正在寻找的东西。我找到了以下但他们没有帮助,只是浪费我的时间:
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
因此,我找到了要链接的库的正确名称。以下工作:
     g++ boost_example.cpp -o run -lboost_filesystem-mt

现在,除了使用(可能)智能猜测工作和搜索网络之外,是否有更智能的方法来查找要链接到的库的名称?鉴于标题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/boost
/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相关联。

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

除了猜测,搜索网页,询问其他人,反复试验等等...是否有更智能的方法来查找应链接到的图书馆的名称?不是那些应该在某处记录的东西?

就提升而言,我当然有兴趣知道答案,但我的问题更通用,适用于任何图书馆。

顺便说一下,我对linux包的名称有一个非常相似的问题(是.deb或.rpm)。如果我被告知要编译我需要的这样或那样的软件,比如PRCE或FooBar,我怎么知道要安装的软件包的名称呢?我知道如何使用apt-cache(对于Kubuntu debs),但是一些软件包命名不直观,我经常最终安装我不需要的软件包......

4 个答案:

答案 0 :(得分:8)

我有时会使用一种暴力方法,但是您必须知道要查找所需库的目录(/ 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。

答案 1 :(得分:3)

我刚刚发现了最聪明,最官方的方式(在我的系统上)来找出链接标志。 以下内容仅适用于Debian或Debian派生分布的增强(就像我的Kubuntu一样)。对于任何系统上的任何库,其他回复可能更通用。

根据安装的boost版本,您可能在Debian类发行版上有以下文件:
/usr/share/doc/libboost1.38-doc/README.Debian
部分内容如下:

--------

The following table shows which components use a library (shared or
static) and the corresponding "-l" flag.  Note that only the
multithreaded version of the libraries is shipped.

  Component              Link Flag                    Library Type
  ---------              ---------                    ------------
  Boost.Date_Time        -lboost_date_time-mt           static  shared
  Boost.Filesystem       -lboost_filesystem-mt          static  shared
  Boost.Graph            -lboost_graph-mt               static  shared
  Boost.IOStreams        -lboost_iostreams-mt           static  shared
  Boost.Math             -lboost_math_c99-mt            static  shared
                         -lboost_math_c99f-mt           static  shared
                         -lboost_math_c99l-mt           static  shared
  Boost.MPI              -lboost_mpi-mt                 static  shared
  Boost.Program_options  -lboost_program_options-mt     static  shared
  Boost.Python           -lboost_python-mt-py24         static  shared
                         -lboost_python-mt-py25         static  shared
  Boost.Regex            -lboost_regex-mt               static  shared
  Boost.Serialization    -lboost_serialization-mt       static  shared
                         -lboost_wserialization-mt      static  shared
  Boost.Signals          -lboost_signals-mt             static  shared
  Boost.System           -lboost_system-mt              static  shared
  Boost.Test             -lboost_prg_exec_monitor-mt    static  shared
                         -lboost_unit_test_framework-mt static  shared
  Boost.Thread           -lboost_thread-mt              static  shared
  Boost.Wave             -lboost_wave-mt                static  shared


只需要找到适合文档的地方!

答案 2 :(得分:2)

答案 3 :(得分:1)

  • 一种可能性是检查rpm / deb软件包的文件列表。 在Ubuntu系统上,可以通过发出以下命令来完成:
  

dpkg -L libboost-filesystem-dev

  • 另一种可能性是使用pkg-config。它是一个帮助确定某些库的编译标志的程序(虽然它不支持Ubuntu上的提升)

  • 您可以使用Autoconf - 可以找到检查提升的宏here。使用Autoconf有助于保持您的源平台/分发独立。