C++/LapackE 代码在 Windows 上编译良好,但相同的代码在 Linux 上编译失败

Posted

技术标签:

【中文标题】C++/LapackE 代码在 Windows 上编译良好,但相同的代码在 Linux 上编译失败【英文标题】:C++/LapackE code compiling fine on Windows, but the identical code fails compilation on Linux 【发布时间】:2016-12-14 01:19:19 【问题描述】:

使用 LapackE 和 MPI 库用 C++ 编写的代码在我使用 GNU C++ 4.9.2 的 Windows 上编译和运行良好。

将该代码迁移到 Linux (CentOS) 服务器编译失败! Linux 机器上的 GNU C++ 是 4.4.7。在这两种情况下,我都使用了相同的 LapackE 头文件。 MPI 在 Linux 机器上运行良好。

在检查两台机器上的预处理器输出文件后,我可以将错误消息与以下情况联系起来:原始代码中的 complex 声明被 _Complex 替换。以下是在 Linux 上编译时出现问题的复杂动态数组 HAMILTONIAN 的声明示例:

来源: lapack_complex_double* 汉密尔顿式;

在 WINDOWS 预处理中。文件(效果很好): _lapack_complex_double* 汉密尔顿式;

在 LINUX PrePROC 中。文件(编译失败): 双 _Complex* 汉密尔顿式;

这可能是与 GCC 的不同版本有关的问题吗?

我尝试过#define _Complex complex,但最终没有用。

一些报告的 C99 _Complex 和 C++ complex 的互操作性问题:possible similar problem。

请帮忙。谢谢!

【问题讨论】:

显而易见的答案是,/home 中包含的头文件之一使用了<complex>"minMathsForEPM.h" 中的某些内容,但没有明确地#include 他们自己。因此,您需要自己做。 @ Sam Varshavchik :棘手的事情在最后一段,如果在“工作代码”(第二个代码)中添加程序,那么它不起作用并且所有错误都是相关的复杂数量的声明。在 Windows 上编译时不会发生这种情况。 你还没有解释“问题”是什么。从总体上看,重新编码包含文件是一件小事,可以在几秒钟内发送出去。 “问题”似乎已经解决:重新排序包含文件。 @Sam Varshavchik:真的!我在最后一段中添加了另一个解释。这就是问题的本质。请帮忙。谢谢! Boki,如果你 g++ -E mysourcefile.cpp(假设 g++ 编译器因为 centos)编译器将吐出预处理器的结果而不是可执行文件,结合常规构建时得到的编译器错误应该可以帮助您深入了解真正出了什么问题。为获得最佳结果,请使用与常规构建相同的编译器标志。 【参考方案1】:

即使我删除 "extern "C" 并在代码的第 1 块中保留 #include "Headers_LAPACKE/..." ,它也可以编译。

这样做。 LAPACK 标头中包含#if __cplusplus 检查,它们的设计使用户代码不需要也不应该有extern "C" 包围它们。

【讨论】:

@Ben Voigt:感谢 Ben 的反馈。如果我删除 extern "C" 我会收到更多错误。附加的类型如下:1) 错误:先前声明的“float _complex_ lapack_make_complex_float(float, float)”与“C++”链接。 2) error: conflict with new declaration with 'C' links 这与 LapackE 标题中的以下行有关:lapack_complex_float lapack_make_complex_float( float re, float im ); 在这个站点,gcc.gnu.org/ml/libstdc++/2007-02/msg00168.html,据说“目前 C++ 不会解析 C99 复杂类型的语法,我知道知道这样做的建议......”。但编译工作在 Windows 上。 @Ben Voigt :补充一下我上面的评论,额外的错误都与 LapackE 头文件有关。 这可能是我在 Windows 机器上使用的 GCC 版本(4.9.4)与 Linux 机器上的版本(4.4.7)吗? 库头版本是否相同?【参考方案2】:

首先,将 GCC 编译器设置为 4.8 或更高版本:在我的情况下,我们必须保留旧的 GCC 4.4.7 并同时安装 GCC 4.9.2。为了能够在 MPI 编译中使用较新的版本,必须将其添加到 PATH 的前面。为此,请参阅How to change default GCC compiler to be used with MPI on Linux CentOS的答案

其次,当使用 LapackE(Lapack 的 C 包装器)进行编译时,必须使用以下预处理器选项 (-D):

-D LAPACK_COMPLEX_STRUCTURE -D HAVE_LAPACK_CONFIG_H -D ADD_

示例:

bash-4.1$ mpiCC main.cpp -L/home/USER1/lapack-3.6.1 -llapacke -llapack -lblas -lm -Wall -D LAPACK_COMPLEX_STRUCTURE -D HAVE_LAPACK_CONFIG_H -D ADD_

确保:

bash-4.1$ gcc --version

给出 4.8 或更高。就我而言,它是:gcc (GCC) 4.9.3

【讨论】:

以上是关于C++/LapackE 代码在 Windows 上编译良好,但相同的代码在 Linux 上编译失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使 armadillo-5.200.1(+openblas 或 lapacke)与 Visual Studio 2010 一起工作?

是否有首选的规范方式在 Windows 上分发 C/C++ 开发包(无源代码)?

Linux原生C库。如何配置Visual Studio代码在Windows上使用它们?

如何在Windows 10上使用C#更改DNS

为啥这个 C 语言中的 SIMD 示例代码可以用 minGW 编译,但可执行文件不能在我的 Windows 机器上运行?

将 POSIX C 代码移植到 Windows