【问题标题】:Error when linking GSL with -static将 GSL 与 -static 链接时出错
【发布时间】:2017-01-30 16:38:53
【问题描述】:

我用 C++ 编写了一个程序。只要我不使用 g++ 的“-static”选项,链接和运行就可以工作。但我必须使用默认设置从 Antergos USB-Live Stick 运行它,并且不包含 GSL。在他们推荐的 GSL 手册中

$ g++ -c main.cpp
$ g++ -static main.o -lgsl -lgslcblas -lm -lnlopt

但是对于这段代码,我收到一条错误消息:

/usr/bin/ld: cannot find -lgsl
/usr/bin/ld: cannot find -lgslcblas
collect2: Fehler: ld gab 1 als End-Status zurück

我尝试使用 this question,但它对我不起作用。当我跑步时

$ g++ -O2 -o test main.cpp -lgsl -lgslcblas -lnlopt -lm
$ lld test

打印出来

linux-vdso.so.1 (0x00007fffa5b95000)
libgsl.so.19 => /usr/lib/libgsl.so.19 (0x00007f8748c9a000)
libgslcblas.so.0 => /usr/lib/libgslcblas.so.0 (0x00007f8748a5d000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f87486d5000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f87483d1000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f87481ba000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f8747e1c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87490fe000)

所以我尝试创建一个符号链接,但我也有“libgsl.so”

$ ls /usr/lib/libgsl
libgslcblas.so        libgslcblas.so.0.0.0  libgsl.so.19          
libgslcblas.so.0      libgsl.so             libgsl.so.19.3.0  

我在做傻事吗?感谢您的帮助。

【问题讨论】:

    标签: g++ static-linking archlinux gsl


    【解决方案1】:

    当您传递-lgsl 时,默认情况下您请求链接器 查找并链接共享库libgsl.so 或静态 库libgsl.a 并更喜欢共享库,如果两者都找到 在同一个搜索目录中。链接器将首先搜索任何 您使用 -L/path/to/search 选项指定的目录, 按照您指定的顺序,然后在其默认搜索目录中 (/usr/lib 等)。 -lgslcblas 也是如此。

    但是当您将链接选项-static 传递给gcc/g++ 时,它会阻止 与任何共享库链接。共享库,libgsl.solibgslcblas.so 将被忽略。静态库libgsl.alibgslblas.a,必须是 在某些或其他搜索目录中找到链接到 成功。

    链接器说:

    /usr/bin/ld: cannot find -lgsl
    /usr/bin/ld: cannot find -lgslcblas
    

    因为它找不到那些静态库 - 大概是因为你 还没有安装。

    你没有说你正在使用什么 linux 发行版,但如果包 提供libgsllibgslcblas 的被称为libgsl[suffix] 那么就会有一个对应的包叫libgsl-dev,libgsl-devel, 或类似的。这将是包的开发版本, 供想开发与libgsl链接的软件的人使用 或libgslcblas。开发包将需要 libgsl 包作为依赖项 - 所以它会安装相同的东西 - 并且还包含 库的头文件和库的静态版本

    因此,您需要为您的发行版安装 libgsl 开发包。 以 Ubuntu 为例,即libgsl-dev:

    稍后

    我认为您的发行版 Arch Linux 没有单独的开发包。你 需要从源代码构建静态库。为此,您需要 至少要安装:

    GNU Make
    GNU autotools (autoconf, automake, libtool)
    GCC (C compiler)
    texinfo
    

    然后进行默认构建:

    • https://savannah.gnu.org/git/?group=gsl获取gsl源码包 通过克隆 git repo 或下载当前的 tar.gz tarball 并提取它。

    • cd 进入包目录。

    • 运行./autogen.sh。如果 GNU autotools 先决条件,这将成功 完成了。

    • 运行./configure --enable-maintainer-mode./autogen.sh 会提示您)。 如果满足包依赖关系,这将成功 并且环境健全性检查通过。

    • 运行make

    • 如果 make 完成且没有错误 - 这将需要几分钟 - 然后,以 root 身份,运行 make install

    如果一切顺利,这将安装您缺少的静态库:

    /usr/local/lib/libgsl.a
    /usr/local/lib/libgslcblas.a
    

    您应该不需要修改链接命令来让链接器找到 他们:/usr/local/lib 是默认的链接器搜索路径。

    【讨论】:

    • 感谢您的快速答复。是的,我没有libgsl.a。我有 Arch Linux,因此我安装了 gsl 2.3-1。但是存储库没有任何开发包。你能告诉我this page 是不是正确的吗?
    • @D.Nagel 从this 看来,Arch Linux 不做单独的开发包,如果静态库不在库存包中,你必须自己从源代码构建它们.从 git repo 或 tar.gz 获取源代码的链接是正确的。源包是一个 GNU autotools 包。你知道如何构建这些吗?
    • 我试过了,但我不知道。我下载了 release-2.3,但它不包含 configure 文件,只有一个 configure.ac。当我运行autoconf configure.ac 时,我收到一些错误。 configure.ac:6: error: possibly undefined macro: AM_INIT_AUTOMAKEconfigure.ac:8: error: possibly undefined macro: AM_MAINTAINER_MODE
    • @D.Nagel 更新的答案可能会有所帮助
    猜你喜欢
    • 2011-11-22
    • 2021-11-18
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2012-06-20
    • 1970-01-01
    相关资源
    最近更新 更多