Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
455 views
in Technique[技术] by (71.8m points)

linker - Rcpp error: /usr/bin/ld cannot find -lgfortran

I am working through the book "Seamless R and C++ Integration with Rcpp". I am using R version 3.1.0 on Ubuntu 12.04. I cannot figure out how to properly link the necessary libraries. I have the following code in R:

R> library(Rcpp)
R> library(RcppArmadillo)
R> suppressMessages(require(inline))
R> code <- '
+   arma::mat coeff = Rcpp::as<arma::mat>(a);
+   arma::mat errors = Rcpp::as<arma::mat>(u);
+   int m = errors.n_rows;
+   int n = errors.n_cols;
+   arma::mat simdata(m,n);
+   simdata.row(0) = arma::zeros<arma::mat>(1, n);
+   for (int row=1; row < m; row++) {
+     simdata.row(row) = simdata.row(row-1)*trans(coeff)
+                        + errors.row(row);
+   }
+   return Rcpp::wrap(simdata);
+ '
R> rcppSim <- cxxfunction(signature(a="numeric", u="numeric"),
+                        code, plugin="RcppArmadillo")
/usr/bin/ld: cannot find -lgfortran
collect2: error: ld returned 1 exit status
make: *** [file167d1a7cd1ad.so] Error 1

ERROR(s) during compilation: source code errors or compiler configuration errors!

Program source:
1: 
2: // includes from the plugin
3: #include <RcppArmadillo.h>
4: #include <Rcpp.h>
5: 
6: 
7: #ifndef BEGIN_RCPP
8: #define BEGIN_RCPP
9: #endif
10: 
11: #ifndef END_RCPP
12: #define END_RCPP
13: #endif
14: 
15: using namespace Rcpp;
16: 
17: 
18: // user includes
19: 
20: 
21: // declarations
22: extern "C" {
23: SEXP file167d1a7cd1ad( SEXP a, SEXP u) ;
24: }
25: 
26: // definition
27: 
28: SEXP file167d1a7cd1ad( SEXP a, SEXP u ){
29: BEGIN_RCPP
30: 
31:   arma::mat coeff = Rcpp::as<arma::mat>(a);
32:   arma::mat errors = Rcpp::as<arma::mat>(u);
33:   int m = errors.n_rows;
34:   int n = errors.n_cols;
35:   arma::mat simdata(m,n);
36:   simdata.row(0) = arma::zeros<arma::mat>(1, n);
37:   for (int row=1; row < m; row++) {
38:     simdata.row(row) = simdata.row(row-1)*trans(coeff)
39:                        + errors.row(row);
40:   }
41:   return Rcpp::wrap(simdata);
42: 
43: END_RCPP
44: }
45: 
46: 
Error in compileCode(f, code, language = language, verbose = verbose) : 
Compilation ERROR, function(s)/method(s) not created! 
/usr/bin/ld: cannot find -lgfortran
collect2: error: ld returned 1 exit status
make: *** [file167d1a7cd1ad.so] Error 1
Calls: cxxfunction -> compileCode
In addition: Warning message:
running command '/usr/lib/R/bin/R CMD SHLIB file167d1a7cd1ad.cpp 2>  
file167d1a7cd1ad.cpp.err.txt' had status 1 

Based on this response to a similar question,

http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2014-February/007245.html

it would appear that I simply need to install the FORTRAN compiler. However, I have installed gfortran using the Ubuntu package manager and still receive the same error. From terminal:

$ dpkg -s gfortran
Package: gfortran
Status: install ok installed
Priority: optional
Section: devel
Installed-Size: 33
Maintainer: Ubuntu Developers <[email protected]>
Architecture: i386
Source: gcc-defaults (1.112ubuntu5)
Version: 4:4.6.3-1ubuntu5
Provides: fortran-compiler
Depends: cpp (>= 4:4.6.3-1ubuntu5), gcc (>= 4:4.6.3-1ubuntu5), gfortran-4.6 
(>=   4.6.3-1~)
Suggests: gfortran-multilib, gfortran-doc
Description: GNU Fortran 95 compiler
This is the GNU Fortran 95 compiler, which compiles Fortran 95 on platforms
supported by the gcc compiler. It uses the gcc backend to generate optimized
code.

This is a dependency package providing the default GNU Fortran 95 compiler.
Original-Maintainer: Debian GCC Maintainers <[email protected]>

I have also been unsuccessful trying to use the CxxFlags() and LdFlags() functions. Any suggestions are greatly appreciated.

Running sourceCpp() produces the following:

R> rcppSim <- sourceCpp("~/Dropbox/Rcpp/rcppSim.cpp")
rcppSim.cpp: In function ‘SEXPREC* file167d1a7cd1ad(SEXP, SEXP)’:
rcppSim.cpp:31:1: error: ‘arma’ has not been declared
rcppSim.cpp:31:11: error: expected ‘;’ before ‘coeff’
rcppSim.cpp:32:1: error: ‘arma’ has not been declared
rcppSim.cpp:32:11: error: expected ‘;’ before ‘errors’
rcppSim.cpp:33:9: error: ‘errors’ was not declared in this scope
rcppSim.cpp:35:1: error: ‘arma’ has not been declared
rcppSim.cpp:35:11: error: expected ‘;’ before ‘simdata’
rcppSim.cpp:36:1: error: ‘simdata’ was not declared in this scope
rcppSim.cpp:36:18: error: ‘arma’ has not been declared
rcppSim.cpp:36:30: error: ‘arma’ has not been declared
rcppSim.cpp:38:47: error: ‘coeff’ was not declared in this scope
rcppSim.cpp:38:52: error: ‘trans’ was not declared in this scope
make: *** [rcppSim.o] Error 1
g++ -I/usr/share/R/include -DNDEBUG    -I"/usr/lib/R/library/Rcpp/include"
-I"/usr/lib/R/library/RcppArmadillo/include" -I"/usr/lib/R/library/Rcpp/include"     
-fpic  -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security   
-Werror=format-security -D_FORTIFY_SOURCE=2 -g  -c rcppSim.cpp -o rcppSim.o 
Error in sourceCpp("~/Dropbox/Rcpp/rcppSim.cpp") : 
Error 1 occurred building shared library.

Running the dpkg command gives:

~$ dpkg -l | grep libgfortran | cut -c-75
ii  libgfortran-4.7-dev                          4.7.3-2ubuntu1~12.04      
ii  libgfortran-4.8-dev                          4.8.1-2ubuntu1~12.04      
ii  libgfortran3                                 4.8.1-2ubuntu1~12.04      
~$ 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Can you run the following command, please:

edd@max:~$ dpkg -l | grep libgfortran | cut -c-75
ii  libgfortran-4.7-dev:amd64                     4.7.3-7ubuntu3           
ii  libgfortran-4.8-dev:amd64                     4.8.1-10ubuntu9          
ii  libgfortran3:amd64                            4.8.1-10ubuntu9          
edd@max:~$ 

You need the libgfortrain-$VERSION-dev package for your machine. At some point having gfortran implied this via r-base-dev and its dependence on build-essentials.

Edit: Version numbers will of course be different on your 12.04 release; this was from a machine running 13.10.

Edit 2, based on your update: Your use of sourceCpp() is incorrect. You are not telling Rcpp that you need Armadillo, so Rcpp responds by saying it does not know Armadillo. You can either use a Rcpp::depends() in the cpp file, or use the plugin= argument.

So here is how I would write the code you have above. You can then just call sourceCpp() on the file which will create a function rcppSim() you can call:

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::mat rcppSim(arma::mat coeff, arma::mat errors) {
   int m = errors.n_rows;
   int n = errors.n_cols;
   arma::mat simdata(m,n);
   simdata.row(0) = arma::zeros<arma::mat>(1, n);
   for (int row=1; row < m; row++) {
     simdata.row(row) = simdata.row(row-1)*trans(coeff) + errors.row(row);
   }
   return simdata;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...