I created a R library that uses a Fortran module. Everything works like a charm on linux.
Now I'm trying to make it work on Windows. I cloned my git repository on a windows computer, and when I press the build and reload
button on Rstudio I get these errors:
==> 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.
What am I missing?
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
As recommended in this post, I added -fno-stack-protector -lssp
but it did not help. Maybe I added it in the wrong place?
I also tried doing by hand and I get these errors:
> 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.
Following @cdeterman instructions i did the following:
I created
Makevars.win
in mysrc
with the following line:PKG_FCFLAGS="-fno-stack-protector"
Then I also changed useDynLin(Fpi) in the NAMESPACE to useDynLib(MyPi).
This I what I get:
==> 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
installing to C:/Users/IMartinez/Documents/R/R-3.2.1/library/MyPi/libs/x64
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) :
DLL 'MyPi' not found: maybe not installed for this architecture?
Error: loading failed
Execution halted
ERROR: loading failed
* removing 'C:/Users/IMartinez/Documents/R/R-3.2.1/library/MyPi'
* restoring previous 'C:/Users/IMartinez/Documents/R/R-3.2.1/library/MyPi'
Exited with status 1.