Rcpp警告:"未找到选项'-L /usr/local/Cellar/gfortran/4.8.2/gfortran'的目录"

13
这个问题与其他一些问题有关,比如RccpArmadilloelement-wise-multiplication
然而,我的设置是这样的,我不知道我必须编辑/符号链接什么才能使Rccp在没有警告的情况下运行。
我使用最新的R版本,在Mac 10.9(mavericks)上。
一开始,我尝试了从这里RccpvsR得到的以下代码,但是我收到了一个错误:
ld: library not found for -lgfortran
clang: error: linker command failed with exit code 1 (use -v to see invocation)`  

然后,基于 RccpArmadillo 我进行了以下操作:
# Update FLIBS in ~/.R/Makevars
FLIBS=-L/usr/local/Cellar/gfortran/4.8.2/gfortran
#Re-Install from source
install.packages(c("Rcpp","RcppArmadillo","inline"),type="source")
#Restart R

这只是为了尝试而已,因为我没有 /usr/local/Cellar/gfortran/ 目录。实际上,我的所有 libgfortran* 文件都在这里(在macports目录中):

>ls /opt/local/lib/gcc48/libgfortran.*
/opt/local/lib/gcc48/libgfortran.3.dylib       /opt/local/lib/gcc48/libgfortran.dylib
/opt/local/lib/gcc48/libgfortran.a       /opt/local/lib/gcc48/libgfortran.spec

我这里有一个路径:/opt/local/lib/gcc48/gcc/x86_64-apple-darwin13/4.8.3/libgfortranbegin.a,但是我任何地方都没有gfortran文件。

然后我再次尝试了代码RccpvsR,令人惊讶的是,它起作用了!除了我收到一个警告之外:

ld: warning: directory not found for option '-L/usr/local/Cellar/gfortran/4.8.2/gfortran' 

因为当然,它并不存在,但是由那段代码创建的函数cosineRcpp可以正常运行。

因此,我想问一下是否需要将/opt/local/lib/gcc48/下的libgfortran文件建立符号链接:

ln -s /opt/local/lib/gcc48/libgfortran.* /usr/local/lib/

然后删除/编辑该行:

FLIBS=-L/usr/local/Cellar/gfortran/4.8.2/gfortran

~/.R/Makevars 中,或者如果我需要安装新的东西。

感谢您提前花费的时间!


1
你是在使用OS X吗?你可能想在r-sig-mac上询问;我认为你需要Xcode命令行工具或类似的东西。rcpp-devel列表也可能有所帮助。我在Linux上,这些东西“只是工作的”。 - Dirk Eddelbuettel
是的,我编辑了这个问题。我使用的是Mac 10.9.5,并且使用最新的R版本。我也安装了Xcode。无论如何,谢谢! - Javier
请查看Simon的“R on Mac”页面获取gfortran。我认为您可能需要安装其他东西。 - Dirk Eddelbuettel
仅仅安装Xcode是不够的。现在(自OSX 10.7以来),您还需要从Xcode内部安装命令行工具。ATT网站提供的gfortran版本是gfortran-4.2.3,并且警告您大多数其他版本都是不完整的,并明确警告不要使用来自HPC的版本(无论那是什么)。 - IRTFM
@BondedDust:我相信我已经安装了命令行工具,因为我过去需要/使用过它。我晚些时候会在家里检查一下,但我很确定我有它。 - Javier
2个回答

27

简短回答

只需要将 libgfortran 的路径放入 FLIBS 中即可,例如:

FLIBS=-L/opt/local/lib/gcc48/

如果您感到舒适,可以将其中的文件建立符号链接到/usr/local/lib/。然而,这种解决方案相当脆弱,因为如果您更新了gfortran或将其移动到其他目录,则很容易忘记更新此路径。

稍微详细些,您可以查询gfortran以获取libgfortran.dylib的路径,例如:

gfortran -print-file-name=libgfortran.dylib

您可以直接在Makevars文件中执行此操作;例如:

FLIBS = -L`gfortran -print-file-name=libgfortran.dylib | xargs dirname`

过时的长回答

尝试直接从gfortran输出中解析出适当的FLIBS

首先,一些背景知识。 /usr/local/Cellar目录是OS X上包管理器homebrew使用的默认路径。将其视为macports的替代方法。

现在,Homebrew提供了gfortran及其相关库作为gcc软件包的一部分,因此它安装FORTRAN库的路径已经发生了改变。然而,这些路径(通常)可以通过gfortran -print-search-dirs来发现。例如,在我的系统上,

gfortran -print-search-dirs
将给我。
install: /usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/
programs: =/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/bin/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/bin/
libraries: =/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../x86_64-apple-darwin14.0.0/4.9.2/:/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../:/lib/x86_64-apple-darwin14.0.0/4.9.2/:/lib/:/usr/lib/x86_64-apple-darwin14.0.0/4.9.2/:/usr/lib/

使用 R 进行分割并打印,我看到:

[[1]]
[1] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/"

[[2]]
[1] "/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                    
[2] "/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                    
[3] "/usr/local/Cellar/gcc/4.9.2_1/libexec/gcc/x86_64-apple-darwin14.0.0/"                                                                                          
[4] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                
[5] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/"                                                                                      
[6] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/bin/x86_64-apple-darwin14.0.0/4.9.2/"
[7] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/bin/"                                

[[3]]
[1] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                
[2] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/x86_64-apple-darwin14.0.0/4.9.2/"
[3] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/"                                
[4] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../x86_64-apple-darwin14.0.0/4.9.2/"                                       
[5] "/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../"                                                                       
[6] "/lib/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                                                         
[7] "/lib/"                                                                                                                                                         
[8] "/usr/lib/x86_64-apple-darwin14.0.0/4.9.2/"                                                                                                                     
[9] "/usr/lib/"  

在我的情况下,libgfortran 实际上存储在这里:

/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../

因此,这就是我们想要传递给FLIBS的路径。但是,提取出来有点麻烦,因此让我们告诉FLIBS使用gfortran通常使用的任何路径:

gfortran -print-search-dirs | grep ^libraries: | sed 's|libraries: =||'

这很不错,但我们希望将库路径以适合编译器的格式呈现;即在前面加上-L。让我们用sed来做到这一点:

gfortran -print-search-dirs | grep ^libraries: | sed 's|libraries: =||' | sed 's|:| -L|g' | sed 's|^|-L|'

这个输出(为了易读而分割)

-L/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/
-L/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/x86_64-apple-darwin14.0.0/4.9.2/
-L/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../../../../x86_64-apple-darwin14.0.0/lib/
-L/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../x86_64-apple-darwin14.0.0/4.9.2/
-L/usr/local/Cellar/gcc/4.9.2_1/lib/gcc/4.9/gcc/x86_64-apple-darwin14.0.0/4.9.2/../../../
-L/lib/x86_64-apple-darwin14.0.0/4.9.2/
-L/lib/
-L/usr/lib/x86_64-apple-darwin14.0.0/4.9.2/
-L/usr/lib/

所有这些都意味着以下内容应该适用于您,至少在OS X上,但通常情况下应该适用于任何安装了gfortran(只要它在PATH上)的平台:

FLIBS=`gfortran -print-search-dirs | grep ^libraries: | sed 's|libraries: =||' | sed 's|:| -L|g' | sed 's|^|-L|'`

这并不完美,例如如果你的路径中有空格,它将失败-- 如果确实存在,则1)你值得得到的结果和2)这也应该是一个相对容易解决的问题。


2
哦,太好了 :) 感谢您提供的所有详细信息。我们应该更新Rcpp FAQ中相应的问题吗? - Dirk Eddelbuettel
1
@kevin Ushey:我知道Homebrew,但由于我从未使用过它,所以我不知道/usr/local/Cellar是默认目录。现在,我喜欢你的简短回答(它有效),而且我真的非常喜欢你的长回答(也有效)。非常感谢你的帮助! - Javier

2

@kevin-ushey的答案需要稍作修改(至少我需要;我使用Prezto),需要将单引号添加到grep '^libraries:',结果如下:

FLIBS=`gfortran -print-search-dirs | grep '^libraries:' | sed 's|libraries: =||' | sed 's|:| -L|g' | sed 's|^|-L|'`

将那行代码添加到我的~/.R/Makevars文件中就解决了问题!

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