Rcpp报错:/usr/bin/ld无法找到-lgfortran。

3

我正在学习《Seamless R and C++ Integration with Rcpp》,内容涉及编程。我使用的是Ubuntu 12.04上的R版本3.1.0。我无法正确链接所需的库。以下是我在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 

基于对类似问题的回答,

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

看起来我只需要安装FORTRAN编译器。然而,我已经使用Ubuntu软件包管理器安装了gfortran,但仍然收到相同的错误信息。从终端窗口中:

$ dpkg -s gfortran
Package: gfortran
Status: install ok installed
Priority: optional
Section: devel
Installed-Size: 33
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
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 <debian-gcc@lists.debian.org>

我尝试使用CxxFlags()和LdFlags()函数,但都没有成功。如有建议,请不吝赐教。

运行sourceCpp()会产生以下结果:

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.

运行dpkg命令会得到:
~$ 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      
~$ 

你尝试过使用sourceCpp而不是cxxfunction吗? - Romain Francois
1个回答

2
请运行以下命令:
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:~$ 

您需要为您的机器安装libgfortran-$VERSION-dev包,以支持IT技术相关内容。曾经通过gfortran和其对build-essentials的依赖关系来暗示这一点。

编辑:版本号在您的12.04版本中可能会有所不同;这是从运行13.10的计算机上获得的。

编辑2,根据您的更新:您使用sourceCpp()的方式是错误的。您没有告诉Rcpp您需要Armadillo,因此Rcpp会回复说无法识别Armadillo。您可以在cpp文件中使用Rcpp::depends()或使用plugin=参数。任选一种方式即可

以下是我将您上面的代码写成的形式。然后,您只需调用sourceCpp()函数即可创建一个名为rcppSim()的函数供您调用:

#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;
}

非常感谢 - 我认为问题出在设置上。我卸载了 R,重新安装了 R,并更新了所有的包。在重置了我的 PKG_CXXFLAGS 和 PKG_LIBS 变量之后,原始代码可以运行了。顺便说一句,Rcpp 是一个很棒的包。我相信它很快会成为我最常用的包。 - TPW
太好了,很高兴现在它可以工作了。欢迎随时来到rcpp-devel。 - Dirk Eddelbuettel
我遇到了同样的错误,最终执行 ~$ sudo apt-get install libgfortran-* 安装了所有版本以解决它。 - Rγσ ξηg Lιαη Ημ 雷欧
你应该不需要那个。看看我其他的答案,推荐使用r-base-dev,它应该拉取正确的默认版本,这应该是你所需要的全部内容。 - Dirk Eddelbuettel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接