【问题标题】:link fortran and c++ using CMake - skipping incompatible ... Error使用 CMake 链接 fortran 和 c++ - 跳过不兼容的...错误
【发布时间】:2021-05-24 13:26:24
【问题描述】:

一位同事确实向我发送了一个 Fortran 函数以包含在我的 C++ 程序中。 到目前为止,我的程序中的所有内容都是用 C++ 编码的。 为了简单起见(尤其是依赖项和安装),我想我会用 C++ 重新编码。 不幸的是,代码非常复杂,包含许多goto 语句和其他我不太熟悉的东西。 (我从未使用过 Fortran,这是来自一个古老的科学 Fortran 77 程序)

因此,我想直接在 C++ 中调用 Fortran 函数。 一个先决条件是,我正在为我的程序使用 CMake,并且所有内容(如链接)都必须在 CMake 文件中完成。此外,CMake 文件应尽可能简单,因为只有科学家在没有复杂的编程背景的情况下工作和扩展程序。

我在互联网上找到了很多方法和解决方案 - 但是,大多数处理模块和库非常复杂 - 我只需要调用一个函数,我们不使用库等。

不幸的是,我在执行代码时遇到了很多错误:

c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe : 跳过不兼容的 C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.dll.a 搜索 -lgfortran 时 c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 跳过不兼容的 C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.a 搜索 -lgfortran 时 c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 跳过不兼容的 C:/MinGW/lib/gcc/mingw32/6.3.0\libgfortran.a 搜索 -lgfortran 时 c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 跳过不兼容的 C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.dll.a 搜索 -lgfortran 时 c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 跳过不兼容的 C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.a 搜索 -lgfortran 时 c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: 找不到-lgfortran

我的主要问题是:这些错误是由于我的代码问题还是与我的环境问题有关?

这是我的代码的样子:

main.cpp

#include <iostream>

extern double f_add(double *, double *, double *);

int main() {
    double a = 1.;
    double b = 2.;
    double c;
    f_add(&a, &b, &c);

    std::cout << c << std::endl;
}

f_add.f

  real function f_add(a, b, c)
  real a,b,c
  c = a+b
  end

CMakeLists.txt

cmake_minimum_required(VERSION 3.17)
project(test_cpp)

set(CMAKE_CXX_STANDARD 14)
SET (CMAKE_Fortran_COMPILER  gfortran)
ENABLE_LANGUAGE(Fortran)

set(SOURCE_FILES
        main.cpp
        f_add.f
        )

add_executable(test_cpp ${SOURCE_FILES})

【问题讨论】:

  • 实际的链接命令是什么样子的?你的 C++ 编译器版本是什么?你的 Fortran 编译器版本是多少?他们使用哪些标志?
  • 看起来你有 g++ 9.2.0 和 gfortran 6.3.0。这可能有助于确保您对每个版本都使用相同的版本。 (当您设法构建某些东西时,您也可能无法匹配 realdouble。)
  • 因此一个想法是卸载 MinGW 并重新安装?
  • 好的,安装 MinGW 新工作 - 有点。现在我收到undefined reference to f_add... 错误
  • @francescalus 因为这解决了我的问题,所以您可以将其作为答案。我现在需要用新的错误消息提出另一个问题

标签: c++ cmake fortran


【解决方案1】:

我认为您的 C++ 代码缺少 extern "C" 以及对 Fortran 代码的一些额外更正。例如,以下将起作用:

#include <iostream>
extern "C" {
    double f_add(double, double);
}
int main() {
    double a = 1.;
    double b = 2.;
    double c;
    c = f_add(a, b);
    std::cout << c << std::endl;
}

和,

function f_add(a, b) result(c) bind(C, name = "f_add")
    use iso_c_binding, only: c_double
    implicit none ! remove this line if your F77 code has implicitly-declared variables.
    real(c_double), intent(in), value   :: a, b
    real(c_double)                      :: c
    c = a + b
end function f_add

然后编译、链接和运行(通过我正在使用的 MinGW GNU 10.1),

gfortran -c f_add.f90
g++ -c main.cpp
g++ *.o -o main.exe
./main.exe

输出是,

3

我没有在 MinGW 中安装 CMake,但通过上述修改设置它应该很简单。如果有帮助,您的 CMake 文件可以在 Linux 环境中完全正常运行。

【讨论】:

  • 感谢您的提示。一件主要的事情是我们使用 CMake 而不是通过终端编译、链接和运行它 - 你知道正确的 CMakeLists.txt 文件是什么样的吗?
  • 我在 WSL 子系统中测试了您的 CMakeLists.txt(使用 CMake 3.16),它工作得很好。因此,只要您安装了 gfortran 和 g++ 并且在 PATH 变量中可用,它也应该在 MinGW 中工作。只需确保您的系统上安装了最新的 gfortran(识别 Fortran 2003)即可。我不确定哪个 GFortran 版本实现了它,但任何高于 GNU GCC 7.0.0 的版本都应该能够编译它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多