xcode 在Mac M1(Big Sur,Monterey)上为Rcpp和其他工具配置编译器

wpcxdonn  于 2023-02-25  发布在  Mac
关注(0)|答案(3)|浏览(205)

我尝试在我的M1 Mac上使用需要Rcpp in R的软件包,在购买这台电脑后,我一直无法启动和运行它。我将它更新到Monterey,希望这将修复一些安装问题,但它没有。我尝试从this page运行Rcpp检查,但我得到以下错误:

> Rcpp::sourceCpp("~/github/helloworld.cpp")
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0'
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib'
ld: library not found for -lgfortran
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [sourceCpp_4.so] Error 1
clang++ -arch arm64 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -I../inst/include   -I"/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/RcppArmadillo/include" -I"/Users/afredston/github" -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c helloworld.cpp -o helloworld.o
clang++ -arch arm64 -std=gnu++14 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o sourceCpp_4.so helloworld.o -L/Library/Frameworks/R.framework/Resources/lib -lRlapack -L/Library/Frameworks/R.framework/Resources/lib -lRblas -L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
Error in Rcpp::sourceCpp("~/github/helloworld.cpp") : 
  Error 1 occurred building shared library.

我知道它不能"找到" gfortran。我为 Monterey 安装了gfortranthis release。当我在终端中键入which gfortran时,它返回/opt/homebrew/bin/gfortran。(也许这个版本的gfortran需要的Xcode工具太新了--它说的是13.2,而当我运行clang --version时,它说的是13.0--但我没有。t see for Monterey的gfortran的另一个版本?)
我还在R中将/opt/homebrew/bin:附加到PATH,现在看起来如下所示:
一个二个一个一个
我检查的其他内容:

  • Xcode命令行工具已安装(which clang返回/usr/bin/clang)。
  • 文件~/.R/Makevars~/.Renviron不存在。

以下是我的会话信息:

R version 4.1.1 (2021-08-10)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Monterey 12.1

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_4.1.1           tools_4.1.1              RcppArmadillo_0.10.7.5.0
[4] Rcpp_1.0.7
owfi6suc

owfi6suc1#

背景
目前(2023年2月20日),CRAN使用Xcode 13.1命令行工具中的Apple Clang和GNU Fortran 12的一个实验性分支来构建苹果芯片的R 4.2二进制文件。
如果您从CRAN(即here)获得R,则在构建包含来自源代码的C/C ++/Fortran代码的R包之前(以及在使用Rcpp等之前),您需要在系统上复制CRAN的编译器设置。
更复杂的问题是Apple Clang不支持OpenMP,所以你需要做更多的工作来编译使用多线程的程序。你可以通过构建R本身,所有的R包,以及所有来自LLVM Clang源代码的外部库来绕过这个问题,LLVM Clang * 确实 * 支持OpenMP,但是这种方法很麻烦,"仅供Maven使用"。
有一种another方法已经被一些人测试过,包括macOS R的维护者Simon Urbanek。它是实验性的,也是"仅供Maven使用"的,但它在我的机器上工作,比自己学习构建R和其他库要简单得多。

获取工作刀具链的说明

  • 警告:这些产品不提供保修,可能随时损坏。假定您对C/C ++/Fortran程序编译、Makefile语法和Unix shell有一定程度的熟悉。鼓励每个人查阅official文档,该文档比SO上的答案更容易维护。与往常一样,sudo风险自负。*

我将尝试同时介绍编译器和OpenMP支持。我将假设您是从零开始。尽管您可能会发现重新开始会有帮助,但您可以随意跳过已经执行的步骤。
我已经在运行大苏尔的机器上测试了这些指令,但它们在 Monterey 和文图拉也应该工作。
1.从CRANhere下载一个R4.2二进制文件并安装。确保选择为苹果芯片构建的二进制文件。
1.跑

$ sudo xcode-select --install

以安装最新发布版本的Apple Xcode命令行工具,其中包括Apple Clang。您可以从浏览器here获取早期版本。但是,您安装的版本不应早于CRAN用于构建R二进制文件的版本。
1.下载提供的GNU Fortran二进制文件here,并通过解压缩到root进行安装:

$ curl -LO https://mac.r-project.org/tools/gfortran-12.0.1-20220312-is-darwin20-arm64.tar.xz
$ sudo tar xvf gfortran-12.0.1-20220312-is-darwin20-arm64.tar.xz -C /
$ sudo ln -sfn $(xcrun --show-sdk-path) /opt/R/arm64/gfortran/SDK

最后一个命令更新安装中的符号链接,使其指向命令行工具安装中的SDK
1.下载一个适合你的Apple Clang版本here的OpenMP运行时,然后解压到root进行安装。你可以用clang --version查询你的Apple Clang版本。例如,我有1300.0.29.3版本,所以我这样做了:

$ curl -LO https://mac.r-project.org/openmp/openmp-12.0.1-darwin20-Release.tar.gz
$ sudo tar xvf openmp-12.0.1-darwin20-Release.tar.gz -C /

解压缩后,您应在系统中找到以下文件:

/usr/local/lib/libomp.dylib
/usr/local/include/ompt.h
/usr/local/include/omp.h
/usr/local/include/omp-tools.h

1.将以下行添加到$(HOME)/.R/Makevars,如有必要,创建该文件。

CPPFLAGS += -I/usr/local/include -Xclang -fopenmp
LDFLAGS += -L/usr/local/lib -lomp

1.测试您是否能够使用R编译具有OpenMP支持的C或C++程序,同时从GNU Fortran安装链接相关库(由R CMD CONFIG FLIBS输出中的-l标志指示)。
最透明的方法是直接使用R CMD SHLIB,在临时目录中创建一个空的源文件omp_test.c,并添加以下行:

#ifdef _OPENMP
# include <omp.h>
#endif

#include <Rinternals.h>

SEXP omp_test(void)
{
#ifdef _OPENMP
    Rprintf("OpenMP threads available: %d\n", omp_get_max_threads());
#else
    Rprintf("OpenMP not supported\n");
#endif
    return R_NilValue;
}

编译:

$ R CMD SHLIB omp_test.c $(R CMD CONFIG FLIBS)

然后从R调用编译后的C函数:

$ R -e 'dyn.load("omp_test.so"); invisible(.Call("omp_test"))'
OpenMP threads available: 8

如果编译器或链接器抛出错误,或者如果您发现OpenMP仍然不受支持,则说明我们中的某个人犯了错误。请报告任何问题。
请注意,如果您不介意安装Rcpp,您可以使用它实现相同的测试:

library(Rcpp)
registerPlugin("flibs", Rcpp.plugin.maker(libs = "$(FLIBS)"))
sourceCpp(code = '
#ifdef _OPENMP
# include <omp.h>
#endif

#include <Rcpp.h>

// [[Rcpp::plugins(flibs)]]
// [[Rcpp::export]]
void omp_test()
{
#ifdef _OPENMP
    Rprintf("OpenMP threads available: %d\\n", omp_get_max_threads());
#else
    Rprintf("OpenMP not supported\\n");
#endif
    return;
}
')
omp_test()
OpenMP threads available: 8

参考文献

一切都有点零散:

  • R安装和管理手册link(https://cran.r-project.org/doc/manuals/r-release/R-admin.html)
  • 编写R扩展手册link(https://cran.r-project.org/doc/manuals/r-release/R-exts.html)
  • R for macOS开发者网页link(https://mac.r-project.org/)
lnxxn5zx

lnxxn5zx2#

我按照以下说明在~/.R/Makevars中添加了gfortran的自制安装路径,从而解决了这个问题:https://pat-s.me/transitioning-from-x86-to-arm64-on-macos-experiences-of-an-r-user/#gfortran

cuxqih21

cuxqih213#

测试了以下在M2 MacBook Pro(macOS Monterey)中运行多线程data.table的过程

用户推断的步骤与this answer基本相同。
1.从CRAN下载并安装R
1.下载并安装带有开发人员工具的RStudio
1.在终端运行以下命令安装OpenMP

curl -O https://mac.r-project.org/openmp/openmp-12.0.1-darwin20-Release.tar.gz
sudo tar fvxz openmp-12.0.1-darwin20-Release.tar.gz -C /

1.添加编译器标志以连接clan w/ OpenMP。在终端中,写入以下内容:

cd ~
mkdir .R
nano .R/Makevars
  • 在打开的Makevars文件中粘贴以下行。完成后,按command+O然后回车保存。按command+X关闭编辑器。
CPPFLAGS += -Xclang -fopenmp
LDFLAGS += -lomp

1.通过从相应的GitHub repo下载gfortran-ARM-12.1-Monterey.dmg,下载并运行gfortran的安装程序
以上是在M2芯片系统下启用OpenMP和(希望如此)Rcpp in R的步骤。

现在,为了测试data.table是否一切正常,我做了以下操作

打开RStudio并运行

install.packages("data.table", type = "source")

如果一切都正确,则软件包编译时应该没有任何错误,并在运行getDTthreads(verbose = TRUE)时返回以下内容:

OpenMP version (_OPENMP)       201811
  omp_get_num_procs()            8
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         2147483647
  omp_get_max_threads()          8
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                unset
  RestoreAfterFork               true
  data.table is using 4 threads with throttle==1024. See ?setDTthreads.
[1] 4

相关问题