Calling Lapack DLL from gfortran - r

I have installed R on Windows, which creates a file C:\programs\R\R-3.5.2\modules\x64\lapack.dll . The Fortran compiler used to build R is gfortran. How can I call Lapack routines from gfortran? I tried
gfortran C:\programs\R\R-3.5.2\modules\x64\lapack.dll xlin.f
where xlin.f is the driver and get the error message
C:...\ccwsB76i.o:xlin.f:(.text+0x120): undefined reference to `sgesv_'

You can always check using the gendef program (available as part of MinGW-w64 installations) what functions/subroutines a DLL contains. Apparently "modules\x64\lapack.dll" in the installation of R for Windows is not the library that you want. The correct one is "bin\x64\Rlapack.dll"!
But this is not the end of the story. At least in case of installation of R 3.6.1, that library contains only double precision variants of the LAPACK routines. So, I needed to transform your program to use REAL*8 and DGESV. But then this worked:
> set "PATH=C:\Program Files\R\R-3.6.1\bin\x64;%PATH%"
> set "PATH=C:\msys64\mingw64\bin;%PATH%"
> gfortran xlin.f "C:\Program Files\R\R-3.6.1\bin\x64\Rlapack.dll"
> a.exe
1.0000000597179521
1.0000000618499254
1.0000000465843075
which I was able to reproduce in Linux with the default LAPACK library.

Related

ld: unknown option: -platform_version when building R packages from source

Certain R packages, such as mgcv, fail to compile from source with clang 10+ (under macOS 10.14 and R version 3.6+). The error reported during compilation is
ld: unknown option: -platform_version
How do I resolve this error and compile these packages?
The problem with ld is the same as in Clang 10 fails to link C++ application with CMake on macOS 10.12. However, the suggestion to add the flag -DCMAKE_CXX_FLAGS="-mlinker-version=305" is not applicable to the R package compilation process. For R, you need to add -mlinker-version=305 to LDFLAGS to your Makevars file, typically located in $HOME/.R/.
My Makevars is based on this GitHub gist. I changed LDFLAGS from this:
LDFLAGS+=-L$(HO)/llvm/lib -Wl,-rpath,$(HO)/llvm/lib
to this:
LDFLAGS+=-L$(HO)/llvm/lib -Wl,-rpath,$(HO)/llvm/lib -mlinker-version=305
That resolved the ld error when compiling mgcv from source.
For the igraph package, adding the mlinker flag to LDFLAGS was not enough; it had to be added to the C++ flags as well. In the gist Makevars above, this is done by adding -mlinker-version=305 to STD_FLAGS, which then adds the flag to CXX**FLAGS for all C++ versions.
UPDATE, June 24 2020: unfortunately, some packages (rJava in my case) fail to use the STD_FLAGS. My workaround was to put the mlinker flag in the C compiler invocation:
CC=$(CCACHE) $(HO)/llvm/bin/clang -mlinker-version=305

Building and installing JAGS locally

I'm trying to build and install JAGS on a cluster that uses GPFS as its filesystem. I'm running into problems with the configure script:
./configure --prefix=$HOME/JAGS/ --with-lapack=/cm/shared/apps/lapack/gcc/64/3.6.0/liblapack.so
Error:
configure: error: "You need to install the LAPACK library"
I'm specifying the location of the dynamic library, but the script doesn't accept that it exists on the system. What is the cause of this?
I figured out the issue. I needed to link to BLAS by using the "--with-blas" flag. The configure script does not have an error message for a missing BLAS link, it instead treats it as a missing reference to the LAPACK library.

Compiling Fortran code for R package under Windows: Undefined reference to REXIT, RWARN, RCHKUSR

I am working on an R package containing Fortran source files. The structure of the Fortran code is rather complex, with many dependencies, therefore I have a Makefile in the src folder for the compilation of the shared library.
So far I have been compiling this package on my machine running Ubuntu 14.04, without any problems. I am now trying to compile it on Windows using Rtools, and I am running into a problem when linking the objects to produce the shared library. More precisely, the linker does not find the functions REXIT, RWARN and RCHKUSR, as I get the following error messages:
undefined reference to `rchkusr_'
undefined reference to `rexit_'
undefined reference to `rwarn_'
These functions are supposed to be in the shared library R.dll (libR.so under Linux). I checked this library with Dependencies Walker and I could find these functions. I have tried to link with -I C:/Program\ Files/R/R-3.1.1/bin/i386/R.dll to make explicit the reference to the shared library. I have tried to recompile with -fno-underscoring to make sure the underscores were not the problem. Nothing helped.
Any ideas where the problem could come from? Any suggestions would be more than welcome!
Under Linux I did not have to do anything special, the linker found the functions without specifying anything in the Makefile.
I am using R version 3.1.1 and Rtools version 3.1.
Many thanks for your help.
After fiddling with the Makefile, I finally found the solution to my problem: The flags I was trying to pass to the linker were wrong. Only the path of the shared library R.dll should be specified, using -L, and the name of the library should be specified using the flag -lR at the end of the command. In short, I specified
gfortran -shared *.o -o myLib.dll -L C:/Program\ Files/R/R-3.1.1/bin/i386 -lR
to create myLib.dll and it worked! I guess I got confused because under Linux there is no need to specify anything, the linker finds the shared library on its own.
Probably not the best and most portable solution I can get (I now have two Makefiles to deal with, Makefile for Linux and Makefile.win for Windows...), but good enough for now.

compiling armadillo with Rtools/MinGW

I'm trying in vain to compile the armadillo linear algebra library for windows. Using the armadillo-4.200.0 source, I have Rtools-3.1 installed and in the path, msys from MinGW installed.
Because my ultimate goal is to use Rcpp and RcppArmadillo, my thought is that I need to use the same compiler for making armadillo as will be used to compile my Rcpp/RcppArmadillo files. Unfortunately, when trying to compile armadillo:
$ ./configure
[...snip...]
-- The CXX compiler identification is unknown
-- Check for working CXX compiler: cl
CMake Warning at CMakeLists.txt:3 (PROJECT):
To use the NMake generator, cmake must be run from a shell that can use the
compiler cl from the command line. This environment does not contain
INCLUDE, LIB, or LIBPATH, and these must be set for the cl compiler to
work.
CMake Error: your CXX compiler: "cl" was not found. Please set CMAKE_CXX_COMPILER to a valid compiler path or name.
[...snip...]
(I tried setting CMAKE_CXX_COMPILER to my Rtools gcc.exe with no luck.)
I believe that it is looking for the visual C compiler, though the docs imply that it can be done solely with the mingw or cygwin compiler environments.
Either:
Is there a problem with compiling the armadillo library and subsequent Rcpp code with different versions of the compiler? (Rtools-3.1 has gcc version 4.6.3, MinGW has gcc version 4.8.1.)
Is there a clean method for compiling armadillo with just the Rtools collection?
(Win7 x64, R-3.1.0, cygwin gcc 4.8.2, rtools 3.1 with gcc 4.6.3.)
RcppArmadillo ships its own copy of Armadillo to avoid exactly this problem. As RcppArmadillpo is used from R, it can rely on R (and R's configuration) to get LAPACK, BLAS, etc pp. We don't need to run configure to use Armadillo from R, and so we don't do.
RcppArmadillo installs the usual R CMD INSTALL ... way; this is tested before every release and has worked reliably.
As you say "your ultimate goal is to use Rcpp and RcppArmadillo", you are in fact done at the R CMD INSTALL .... You can replicate the step from source, and test the package -- all that should "just work".
The other thing to keep in mind is what the "Writing R Extensions" and "R Installation and Administration" manuals have to say about your compiler. As far is R is concerned, your g++ 4.8.* does not exist. Only the Rtools version matters, or you get into non-standard land real quick.

R won't call gfortran compiled object?

I made a simple fortran routine
subroutine add(x,y)
real(8) :: x,y
y = x + 3
end subroutine
saved as test.f90.
I compile with
gfortran -shared test.f90 -o test.so
In R (in the same directory), I use
dyn.load('test.so')
but it gives me this error:
Error in dyn.load("test.so") :
unable to load shared object '/Users/Steven/Documents/PhD/npsR/test.so':
dlopen(/Users/Steven/Documents/PhD/npsR/test.so, 6): Symbol not found: ___addtf3
Referenced from: /usr/local/gfortran/lib/libquadmath.0.dylib
Expected in: /Library/Frameworks/R.framework/Resources/lib/libgcc_s.1.dylib
in /usr/local/gfortran/lib/libquadmath.0.dylib
Does anyone know why? I'm using mac osx Lion, with R v2.15.0 and gfortran 4.6.2.
Thank you!
Unless you really understand what you're doing, you should use gfortran that comes with R tools. The missing symbol in libgcc isn't surprising since you're trying to run code compiled with a 4.6 gfortran in a 4.2 runtime environment.
You can only use the gfortran version that was used to build R.
Since you are on Lion and presumably have Xcode installed you can get the appropriate version of gfortran from here: http://r.research.att.com/tools/
Go to section: "Apple Xcode gcc-42 add-ons" and choose the appropriate version.
You'll have to get rid of your gfortran 4.6.2 completely or make it inaccessible by changing PATH if possible (which I doubt unless it is in /opt/...).
And do use R CMD SHLIB since that will pass the correct options to compiler and linker.

Resources