关于外部库的已编译程序使用的问题

时间:2010-11-22 22:10:12

标签: c++ linux ubuntu

我知道这可能是一个非常愚蠢的问题,但我是编译语言的新手(我的域主要是脚本语言,如PHP,Python或JavaScript)。

我正在为一个项目学习C ++,它是我可以使用的唯一语言。

我在Ubuntu 10.10中编写了一个程序然后编译它。我可以像这样从cmd运行生成的二进制文件,它可以工作:

sudo ./compiled-program

但是,我在程序中使用了一些外部库(OpenCV)。这是否意味着我将运行该程序的所有计算机都必须安装OpenCV?或者OpenCV捆绑在已编译的二进制文件中?它可以在没有安装OpenCV的PC上运行吗?

7 个答案:

答案 0 :(得分:2)

您应该阅读有关libraries的一些内容,特别是静态库和动态库之间的区别。引用基本定义,以便得到重点:

  

静态库,也称为   archive,由一组例程组成   复制到目标中   编译器应用程序,链接器,   或者生成器,生成目标文件和   一个独立的可执行文件。

     

[...]

     

动态链接涉及加载   图书馆的子程序(可能是   称为DLL,特别是在   Windows,或作为DSO(动态共享   对象)在类Unix系统下)进入   应用程序在加载时或   运行时,而不是链接它们   在编译时

答案 1 :(得分:2)

根本不是一个愚蠢的问题!

这种“正常”的方式 - 是你的程序已经链接到“共享库” - 在这种情况下,是的,用户需要OpenCV(或任何捆绑包括共享库)才能工作。

如果您编译为静态可执行文件(使用-static)标志,那么它和所有库将直接包含在您的可执行文件中,更大的可执行文件浪费更多内存,因为它没有使用共享库。

有一些方法可以编译程序以将您的OpenCV库链接为静态 - 但只有当捆绑包包含静态库“.a”而不是共享库时才能这样做“所以”。

答案 2 :(得分:2)

如果必须针对依赖项构建代码,例如OpenCV,则取决于您是进行静态链接还是动态链接。

请参阅此处有哪些部分涵盖了这些想法:http://en.wikipedia.org/wiki/Library_(computing

对于初学者,请尝试在命令行上执行此操作:

ldd compiled-program

您将获得这样的输出(例如,我在ldd中的python二进制文件上/usr/bin}:

birryree@lilun:/usr/bin$ ldd python
        linux-gate.so.1 =>  (0xb7ff7000)
        libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7fd5000)
        libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7fd1000)
        libutil.so.1 => /lib/i686/cmov/libutil.so.1 (0xb7fcd000)
        libssl.so.0.9.8 => /usr/lib/i686/cmov/libssl.so.0.9.8 (0xb7f82000)
        libcrypto.so.0.9.8 => /usr/lib/i686/cmov/libcrypto.so.0.9.8 (0xb7e2a000)
        libz.so.1 => /usr/lib/libz.so.1 (0xb7e16000)
        libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7df0000)
        libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7caa000)
        /lib/ld-linux.so.2 (0x80000000)

Python需要很多额外的东西,比如libssl(OpenSSL的一部分),GNU C库(libc)以及其他一些东西。

现在,如果您要将这个东西转移到其他系统,您要么希望它们具有与您类似的环境,将其作为源分发并使用类似autotools / GNU Build System的内容来构建它,或者你可以放弃所有这些,并将所有内容静态地链接到你的二进制文件,这将带来你的可执行文件所需的所有东西,而不需要动态链接。

答案 3 :(得分:1)

如果你已经“编译”了OpenCV,那么运行你的应用的机器也需要它。您需要在安装应用程序时复制库,或确保它们已安装。

答案 4 :(得分:1)

这取决于你是在编译共享(动态)库还是将其编译成可执行文件(针对静态库进行编译)。如果您要编译共享库,则需要分发共享库...否则......您不需要。

答案 5 :(得分:1)

有两种库,静态和动态加载。 静态加载的库与您的二进制文件连接,而动态加载的库在运行时加载。

答案 6 :(得分:1)

这取决于可执行文件是statically-built还是dynamically linked。在静态构建的可执行文件中,可执行需求的库文件被编译到可执行文件中,并且不需要携带额外的库文件。在动态链接的可执行文件中,可执行文件需要的库文件在运行时链接,因此在运行时需要库文件的副本。