link fortran 和 c++ 使用 CMake - 跳过不兼容 ... 错误

link fortran and c++ using CMake - skipping incompatible ... Error

一位同事确实向我发送了一个 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: skipping incompatible C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.dll.a when searching for -lgfortran c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.a when searching for -lgfortran c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:/MinGW/lib/gcc/mingw32/6.3.0\libgfortran.a when searching for -lgfortran c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.dll.a when searching for -lgfortran c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:/MinGW/lib/gcc/mingw32/6.3.0/libgfortran.a when searching for -lgfortran c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -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++ 代码缺少 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

然后编译,link,运行(通过我正在使用的 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 环境中完全可用。