Ignacio Martinez
2015-Jul-27 12:24 UTC
[R-es] Crear un paquete que usa una subrutina escrita en Fortran (en windows)
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]]