[R-es] Crear un paquete que usa una subrutina escrita en Fortran (en windows)

Ignacio Martinez ignacio82 en gmail.com
Lun Jul 27 14:24:57 CEST 2015


Hola,

Estoy aprendiendo a crear paquetes para R que llaman a subutinas escritas
en Fortran. En linux logre crear el paquete y funciona como esperaba.

Ahora estoy tratando de hacelo en windows. Cuando hago click en el boton de
'build and reload' en Rstudio me salen estos errores:

==> Rcmd.exe INSTALL --no-multiarch --with-keep.source MyPi
* installing to library
'C:/Users/IMartinez/Documents/R/R-3.2.1/library'* installing *source*
package 'MyPi' ...** libs
gfortran -m64 -shared -s -static-libgcc -o MyPi.dll tmp.def Fpi.o
-Ld:/RCompile/r-compiling/local/local320/lib/x64
-Ld:/RCompile/r-compiling/local/local320/lib
-LC:/Users/IMARTI~1/DOCUME~1/R/R-32~1.1/bin/x64 -lR
Fpi.o: In function `__fortranpi_MOD_dboard':
Fpi.f90:(.text+0xd7): undefined reference to `__stack_chk_fail'
Fpi.o: In function `pi_':
Fpi.f90:(.text+0x249): undefined reference to `__stack_chk_fail'
collect2: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'MyPi'* removing
'C:/Users/IMartinez/Documents/R/R-3.2.1/library/MyPi'

Exited with status 1.

Este es mi codigo en Fortran:

Module Fortranpi
IMPLICIT NONE
contains
subroutine dboard(darts, dartsscore)
  integer, intent(in)                    :: darts
  double precision, intent(out)          :: dartsscore
  double precision                       :: x_coord, y_coord
  integer                                :: score, n

score = 0
do n = 1, darts
  call random_number(x_coord)
  call random_number(y_coord)

  if ((x_coord**2 + y_coord**2) <= 1.0d0) then
  score = score + 1
  end if
end do

dartsscore = 4.0d0*score/darts

end subroutine dboard

subroutine pi(avepi, DARTS, ROUNDS) bind(C, name="pi_")
  use, intrinsic                         :: iso_c_binding, only :
c_double, c_int
  real(c_double), intent(out)            ::  avepi
  integer(c_int), intent(in)             ::  DARTS, ROUNDS
  integer                                ::  MASTER, rank, i, n
  integer, allocatable                   ::  seed(:)
  double precision                       ::  pi_est, homepi, pirecv, pisum
! we set it to zero in the sequential run
rank = 0! initialize the random number generator! we make sure the
seed is different for each task
call random_seed()
call random_seed(size = n)
allocate(seed(n))
seed = 12 + rank*11
call random_seed(put=seed(1:n))
deallocate(seed)

avepi = 0
do i = 0, ROUNDS-1
  call dboard(darts, pi_est)
  ! calculate the average value of pi over all iterations
  avepi = ((avepi*i) + pi_est)/(i + 1)
end do
end subroutine pi

end module Fortranpi

Una de las recomendaciones fue agregar -fno-stack-protector -lssp. Hice eso
pero todavia no puedo compilar el paquete
<http://i.stack.imgur.com/lC82X.png>

Si trato de compilar "a mano" en lugar de con el boton, me salen estos
errores <http://i.stack.imgur.com/WY4VD.png>

> system("R CMD SHLIB -fno-stack-protector -lssp ./src/Fpi.f90")
gfortran -m64 -shared -s -static-libgcc -o src/Fpi.dll tmp.def
./src/Fpi.o -fno-stack-protector -lssp
-Ld:/RCompile/r-compiling/local/local320/lib/x64
-Ld:/RCompile/r-compiling/local/local320/lib
-LC:/Users/IMARTI~1/DOCUME~1/R/R-32~1.1/bin/x64 -lR>
dyn.load("./src/Fpi.dll")
Error in inDL(x, as.logical(local), as.logical(now), ...) :
  unable to load shared object 'C:/Users/IMartinez/Projects/MyPi/./src/Fpi.dll':
  LoadLibrary failure:  %1 is not a valid Win32 application.
'C:/Users/IMartinez/Projects/MyPi/./src/Fpi.dll':
  LoadLibrary failure:  %1 is not a valid Win32 application.

Gracias por la ayuda!

Ignacio

PS: Hace un par de dias hice esta pregunta en stackoverflow
<http://stackoverflow.com/questions/31638934/r-package-with-fortran-module-on-windows-undefined-reference-to-stack-chk-fa?noredirect=1#comment51231196_31638934>
pero no todavia no tengo una respuesta.

	[[alternative HTML version deleted]]



Más información sobre la lista de distribución R-help-es