【问题标题】:Can't link against static library with Mingw on Linux无法在 Linux 上使用 Mingw 链接静态库
【发布时间】:2021-04-04 17:13:04
【问题描述】:

我已经安装了GMP library 并尝试与mingw-w64-posix 进行交叉编译。

我的库在 /usr/local/lib 中。

我的编译命令如下所示:

x86_64-w64-mingw32-g++-posix src/factorial.cpp -o bin/factorial.win.o -I/usr/local/include -L/usr/local/lib -lgmp -lgmpxx

它抛出一个未定义的引用错误: (我可以从-L.... 中删除整个块,同样的错误。似乎库由于某种原因没有链接)

/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_]+0x27): undefined reference to `__gmpz_mul'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l]+0x26): undefined reference to `__gmpz_mul_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl[_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl]+0x1a): undefined reference to `__gmpz_init_set_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_[_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_]+0x2e): undefined reference to `__gmpz_init'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev[_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev]+0x14): undefined reference to `__gmpz_clear'
collect2: error: ld returned 1 exit status

但是,如果我将编译器更改为 g++,则一切正常。

【问题讨论】:

  • 老兄...... 什么是未定义的参考???请“编辑”您的帖子,然后复制/粘贴错误消息!
  • 对不起,我想念点击那个
  • 看起来您将标头包含为 C++ 代码,将库包含为 C 代码,并且损坏的 C++ 名称与基本 C 名称不匹配。
  • 你到底是什么意思?我包括 gmpxx.h 头文件(这是基本的 gmp c++​​ 头文件),并且我链接到 c++ 以及 gmp 的 c 静态库
  • 我认为 C++ 函数名称修饰没有标准,因此不同的编译器可能不兼容。

标签: c++ linux g++ mingw-w64 gmp


【解决方案1】:

好的-

  1. 链接错误(__gmpz_init、__gmpz_clear 等)是 GMP“内部问题”。它们应该来自 C 语言基础库 libgmp。

  2. 引用它们的代码(.text$ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3[ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3] 等)是“名称混乱的”C++。

  3. 我怀疑问题是你的“gmpxx”库是用一个不同的 C++编译器构建的,它有一个不同的“名称修改" 比 MinGW 的约定。

解决方案:

下载完整的 libGMP 源代码(例如,从 https://gmplib.org/ 下载,并使用您的 libmingw-w64-posix++ C++ 交叉编译器重建所有内容(包括 libgmpxx)。


附录:

我下载了gmp-6.2.1源码,发现这里有__gmpz_clear:

gmp-6.2.1\gmp-h.in

#define mpz_clear __gmpz_clear
__GMP_DECLSPEC void mpz_clear (mpz_ptr);

“gmp-h.in”是项目的“autoconf”使用的模板,用于为指定的目标环境生成libGMP源文件。

这又意味着:

  1. 您开始使用的项目(在您最初的问题中)没有为 MinGW 配置

...和...

  1. 当您尝试从源代码构建时,您没有正确运行“配置”。

建议:

  1. 尝试再次从源代码构建 libGMP。删除所有内容,从 libGMP tarball 中重新提取,并仔细按照安装说明进行操作:

    ./configure
    make
    make check       <= VERY IMPORTANT!!
    make install
    
  2. 我很好奇您的构建环境(Windows?Linux?)、编译器(确切的 MinGW 版本)和目标(如果您在 Windows 工作站上构建,您是否希望将 GMP 应用程序作为 Windows .exe 运行)?

【讨论】:

  • 听起来很对...你知道要为配置文件设置什么标志吗?我查看了文档,找到我需要设置的类型并不是很简单
  • 对不起。如果你真的需要“交叉编译”,那么你只需要阅读自述文件,尽力而为......看看会发生什么。如果您遇到问题或有具体问题,请随时提出新问题。但听起来你现在有了这个问题的答案。
  • 缺失的符号是从 factorial.cpp 引用的,而不是从 libgmpxx(它只包含几个 I/O 函数)。如果 libgmpxx 中缺少符号,首先要做的是重新排序标志:-lgmpxx-lgmp 之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多