2014-05-20 112 views
2

我正在通讀「無縫R和C++與Rcpp集成」一書。我在Ubuntu 12.04上使用R版本3.1.0。我無法弄清楚如何正確鏈接必要的庫。我在R上的下面的代碼:Rcpp錯誤:/ usr/bin/ld找不到-lgfortran

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 <[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]> 

我也試圖使用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  
~$ 
+0

您是否嘗試過sourceCpp代替cxxfunction? –

回答

1

你可以運行下面的命令,請:

[email protected]:~$ 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   
[email protected]:~$ 

您需要爲您的機器提供libgfortrain-$VERSION-dev包裝。在gfortran的某個點通過r-base-dev暗示了這一點,並且其依賴於build-essentials

編輯:版本號在12.04版本中當然會有所不同;這是來自一臺運行13.10的機器。

編輯2,根據您的更新:您使用sourceCpp()是不正確的。你沒有告訴Rcpp你需要犰狳,所以Rcpp迴應說它不知道犰狳。你可以在使用Rcpp::depends()在cpp文件中,使用plugin=參數。

所以這裏是我將如何寫上面的代碼。然後,您可以叫上這將創建一個函數rcppSim()你可以調用該文件sourceCpp()

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

非常感謝 - 我認爲問題在於設置。我卸載了R,重新安裝了R,並更新了我的所有軟件包。重置我的PKG_CXXFLAGS和PKG_LIBS變量後,原始代碼將起作用。順便說一句,Rcpp是一個夢幻般的包。我相信它很快會成爲我最常使用的軟件包。 – TPW

+0

太棒了,很高興知道它現在起作用。隨意來到rcpp-devel。 –