c++ - 编译混合的 GNU Fortran/C++ MPI 共享库

标签 c++ fortran shared-libraries mpi

我正在尝试将 C++ MPI 包装器编译为 MPI Fortran 库,但我无法链接。 包装器是使用

编译的
mpic++ -c my_wrapper.cc -o my_wrapper.o 

my_wrapper.cc 内容如下:

#include "mpi.h"

extern"C" {
  void fortran_func_(int * comm,bool *do_init);
}

void c_func(MPI_Comm my_comm ) 
{
   MPI_Fint    fcomm;
   fcomm = MPI_Comm_c2f(my_comm);
   bool do_init = false;
   fortran_func_(&fcomm, &do_init);
}

库是使用编译的

  MPI_LINK_FLAGS = $(shell mpic++ --showme:link)
  mpif90 -shared my_wrapper.o $(FORTRAN-LIBS) $(MPI_LINK_FLAGS) -o my_libc++.a

这是链接错误:

  "std::ios_base::Init::Init()", referenced from:
      __static_initialization_and_destruction_0(int, int) in my_wrapper.o
  "std::ios_base::Init::~Init()", referenced from:
      __static_initialization_and_destruction_0(int, int) in my_wrapper.o
  "vtable for __cxxabiv1::__class_type_info", referenced from:
      typeinfo for MPI::Info in my_wrapper.o
      typeinfo for MPI::Errhandler in my_wrapper.o
      typeinfo for MPI::Win in my_wrapper.o
      typeinfo for MPI::Comm_Null in my_wrapper.o
      typeinfo for MPI::Group in my_wrapper.o
      typeinfo for MPI::Request in my_wrapper.o
      typeinfo for MPI::Status in my_wrapper.o
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__si_class_type_info", referenced from:
      typeinfo for MPI::Intercomm in my_wrapper.o
      typeinfo for MPI::Graphcomm in my_wrapper.o
      typeinfo for MPI::Cartcomm in my_wrapper.o
      typeinfo for MPI::Intracomm in my_wrapper.o
      typeinfo for MPI::Comm in my_wrapper.o
      typeinfo for MPI::Grequest in my_wrapper.o
      typeinfo for MPI::Prequest in my_wrapper.o
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete[](void*)", referenced from:
      MPI::Datatype::Get_contents(int, int, int, int*, long*, MPI::Datatype*) const in my_wrapper.o
      MPI::Comm::Alltoallw(void const*, int const*, int const*, MPI::Datatype const*, void*, int const*, int const*, MPI::Datatype const*) const in my_wrapper.o
      MPI::Intracomm::Create_cart(int, int const*, bool const*, bool) const in my_wrapper.o
      MPI::Intracomm::Spawn_multiple(int, char const**, char const***, int const*, MPI::Info const*, int) in my_wrapper.o
      MPI::Intracomm::Spawn_multiple(int, char const**, char const***, int const*, MPI::Info const*, int, int*) in my_wrapper.o
      MPI::Cartcomm::Get_topo(int, int*, bool*, int*) const in my_wrapper.o
      MPI::Cartcomm::Sub(bool const*) const in my_wrapper.o
      ...
  "operator delete(void*)", referenced from:
      MPI::Datatype::~Datatype() in my_wrapper.o
      MPI::Datatype::~Datatype() in my_wrapper.o
      MPI::Status::~Status() in my_wrapper.o
      MPI::Status::~Status() in my_wrapper.o
      MPI::Request::~Request() in my_wrapper.o
      MPI::Request::~Request() in my_wrapper.o
      MPI::Request::~Request() in my_wrapper.o
      ...
  "operator new[](unsigned long)", referenced from:
      MPI::Datatype::Get_contents(int, int, int, int*, long*, MPI::Datatype*) const in my_wrapper.o
      MPI::Comm::Alltoallw(void const*, int const*, int const*, MPI::Datatype const*, void*, int const*, int const*, MPI::Datatype const*) const in my_wrapper.o
      MPI::Intracomm::Create_cart(int, int const*, bool const*, bool) const in my_wrapper.o
      MPI::Intracomm::convert_info_to_mpi_info(int, MPI::Info const*) in my_wrapper.o
      MPI::Cartcomm::Get_topo(int, int*, bool*, int*) const in my_wrapper.o
      MPI::Cartcomm::Sub(bool const*) const in my_wrapper.o
      MPI::Cartcomm::Map(int, int const*, bool const*) const in my_wrapper.o
      ...
  "operator new(unsigned long)", referenced from:
      MPI::Intracomm::Clone() const in my_wrapper.o
      MPI::Cartcomm::Clone() const in my_wrapper.o
      MPI::Graphcomm::Clone() const in my_wrapper.o
      MPI::Intercomm::Clone() const in my_wrapper.o
  "___cxa_pure_virtual", referenced from:
      vtable for MPI::Comm in my_wrapper.o
  "___gxx_personality_v0", referenced from:
      Dwarf Exception Unwind Info (__eh_frame) in my_wrapper.o
  ld: symbol(s) not found for architecture x86_64
  collect2: error: ld returned 1 exit status

我找不到任何示例如何做这些事情(混合 Fortran/C++ 和 MPI)所以我在这里问,希望它在某些时候对其他人有用。

附言

如果我尝试用 mpic++ 编译它:

MPIF_LINK_FLAGS = $(shell mpif90 --showme:link)
mpic++ -shared my_wrapper.o $(FORTRAN-LIBS) $(MPIF_LINK_FLAGS) -o $@

我错过了很多来自 $(FORTRAN-LIBS) 的符号,当我链接到 mpif90 时我没有。 所以我想我最好将那些缺少的库添加到 Fortran 链接器中。

如果重要的话,我使用 Open MPI: 1.6

编辑 1: 通过将这些添加到 mpif90 链接所有编译:

-L/opt/local/lib/gcc47/ -lstdc++

确实,缺少一些标准的 C++ 东西

最佳答案

看来您正在使用 FORTRAN 链接器进行链接。它对 C++ 标准库一无所知,因此所有 C++ 标准库(std::ios_base 的这些部分)都将是“ undefined symbol ”。您需要更改链接命令,以添加 C++ 标准库。

由于您的组合既不完全是 FORTRAN 也不完全是 C++,因此 FORTRAN 和 C++ 链接器都不是完全合适的。您可能要考虑直接使用 ld。在这种情况下,您必须将 C++ 标准库和 FORTRAN 标准库列为要链接的库。

关于c++ - 编译混合的 GNU Fortran/C++ MPI 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15878648/

相关文章:

c++ - 在不明确时在转换运算符之间进行选择

c++ - 我如何在 OpenGL ES 1.x 中实现 glPushAttrib(GL_CURRENT_BIT)

arrays - 在 Fortran 90 中,是否必须事先声明数组维度?

fortran - gfortran 如何判断我正在编译 f90 还是 f95 代码?

qt - 无法在 "xcb"中加载 Qt 平台插件 ""即使找到了

c# - 是否可以从 .NET 核心在 linux 平台上调用共享库 (.so)?

c++ - 仅读取数字的 scanf 格式说明符

c++ - 使用 g++ 编译,但仍然获得对运算符 new 的 undefined reference

c - Makefile FFLAGS 描述

c++ - 使用 gcc 是否可以链接库,但前提是它存在?