Reputation: 125
I am trying to write the CMakeLists.txt for coupling a simple FORTRAN program which calls a C++ function using iso_c_binding. When I use gfortran as the FORTRAN compiler, the code works perfectly, but when I switch to openMPI (mpif90) instead of gfortran, I get the error:
CMakeFiles/test.exe.dir/main.f90.o: In function `MAIN__':
main.f90:(.text+0x2d): undefined reference to `mpi_init_'
main.f90:(.text+0x47): undefined reference to `mpi_comm_size_'
main.f90:(.text+0x61): undefined reference to `mpi_comm_rank_'
main.f90:(.text+0x1c3): undefined reference to `mpi_finalize_'
collect2: ld returned 1 exit status
make[2]: *** [test.exe] Error 1
make[1]: *** [CMakeFiles/test.exe.dir/all] Error 2
make: *** [all] Error 2
I am attaching the gfortran version (working). In order to switch to the mpif90, I just uncomment the commented lines in the main.f90:
program main
use iso_c_binding
implicit none
! include 'mpif.h'
interface
function func (n,x) bind (C, name="func")
import
integer(c_int):: func
integer(c_int):: n
real(c_double), dimension(1:n), intent(in):: x
end function func
end interface
integer(c_int):: n
real(c_double), dimension(:), allocatable:: x
integer(c_int):: result
! integer, parameter:: master = 0
! integer:: numtasks, taskid, ierr, dest
! integer status(mpi_status_size)
! call mpi_init(ierr)
! call mpi_comm_size(mpi_comm_world, numtasks, ierr)
! call mpi_comm_rank(mpi_comm_world, taskid, ierr)
! if (taskid .eq. master) then
n = 3
allocate(x(1:n))
x = (/1., 2., 3./)
result = func(n,x)
deallocate(x)
! end if
! call mpi_finalize(ierr)
end program main
func.c:
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern"C" {
#endif
int func(int& n, double x[]) {
std::cout << x[0] << " " << x[1] << " " << x[2] << std::endl;
return 0;
}
#ifdef __cplusplus
}
#endif
CMakeLists.txt:
PROJECT(test)
cmake_minimum_required(VERSION 2.6)
enable_language(C Fortran)
# -------------------------
# Setting the compilers
# -------------------------
#set (CMAKE_Fortran_COMPILER /usr/local/openmpi/bin/mpif90)
set (CMAKE_Fortran_COMPILER /usr/bin/gfortran)
set (CMAKE_C_COMPILER /usr/bin/g++)
# -------------------------
# Setting the flags
# -------------------------
set_source_files_properties(main.f90 func.cpp PROPERTIES COMPILE_FLAGS "-c -lstdc++")
# -------------------------
# Making the executable
# -------------------------
ADD_EXECUTABLE(test.exe main.f90 func.cpp)
I would appreciate any help on this issue.
Upvotes: 1
Views: 1488
Reputation: 46
The problem is that you are not linking to MPI anywhere. Besides, setting the CMAKE_Fortran_compiler by hand is the wrong way to do it as it is not portable at all. Here is a simplified version of what I have in one of my projects. Note that I am using the FindMPI module that comes with recent versions of cmake. I do not know if cmake version 2.6 has that module but you can easily find it online.
cmake_minimum_required (VERSION 2.8)
project(DYNAMO Fortran C)
find_package(MPI REQUIRED)
set(DYNAMO_LINK_LIBRARIES ${MPI_Fortran_LIBRARIES})
set(DYNAMO_SRCS main.f90)
add_executable(dynamo ${DYNAMO_SRCS})
set_target_properties(dynamo PROPERTIES COMPILE_FLAGS "${MPI_Fortran_COMPILE_FLAGS}")
set_target_properties(dynamo PROPERTIES LINK_FLAGS "${MPI_Fortran_LINK_FLAGS}")
target_link_libraries(dynamo ${DYNAMO_LINK_LIBRARIES})
install(TARGETS dynamo RUNTIME DESTINATION bin)
Upvotes: 3