在 Mac M1(Big Sur,Monterey)上为 Rcpp 和其他工具配置编译器
Configuring compilers on Mac M1 (Big Sur, Monterey) for Rcpp and other tools
我正在尝试在我的 M1 Mac 上使用 R 中需要 Rcpp
的软件包,我在购买这台计算机后一直无法起床和 运行ning。我将其更新为 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 安装了 this release of gfortran
。当我在终端中输入 which gfortran
时,它会显示 returns /opt/homebrew/bin/gfortran
。 (也许这个版本的 gfortran
需要 Xcode 太新的工具——它说的是 13.2,而当我 运行 clang --version
它说的是 13.0——但我没有看到gfortran
蒙特雷的另一个版本?)
我还在 R 中将 /opt/homebrew/bin:
附加到 PATH
,所以现在看起来像这样:
> Sys.getenv("PATH")
[1] "/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Library/TeX/texbin:/Applications/RStudio.app/Contents/MacOS/postback"
我检查的其他内容:
- Xcode 命令行工具已安装 (
which clang
returns /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
背景
目前 (2022-04-24),CRAN 使用 Apple clang
来自 Xcode 13.1 的命令行工具并使用 GNU Fortran 12 的实验分支为 Apple silicon 构建 R 4.2 二进制文件。
如果您从 CRAN 获得 R(即 here),那么您需要在构建包含 C/C++/Fortran 代码的 R 包之前在您的系统上复制 CRAN 的编译器设置来源(以及在使用 Rcpp
之前,等等)。此要求可确保您的包构建与 R 本身兼容。
更复杂的是 Apple clang
不支持 OpenMP,因此您需要做更多的工作来编译使用多线程的程序。您可以通过使用 LLVM clang
构建 R 本身和来自源的所有 R 包来规避这个问题,确实 支持 OpenMP,但这种方法很繁琐并且“对于仅限专家。
有一些 another 方法已经过一些人的测试,包括 R for macOS 的维护者 Simon Urbanek。它是实验性的并且“仅供专家使用”,但它可以在我的机器上运行并且比学习自己构建 R 简单得多。
获取工作工具链的说明
警告:这些产品不提供保修,随时可能损坏。假设您对 C/C++/Fortran 程序编译、Makefile 语法和 Unix shell 有一定程度的熟悉。鼓励每个人查阅 official 文档,这些文档比 SO 上的答案更有可能得到维护。与往常一样,sudo
风险自负。
我将尝试同时解决编译器和 OpenMP 支持问题。我假设你是从零开始的。随意跳过您已经执行的步骤,但您可能会发现重新开始会有所帮助。
我已经在机器 运行 Big Sur 上测试了这些指令,at least one person 已经在机器 运行 Monterey 上测试了它们。我很高兴收到其他人的来信。
从 CRAN here 下载 R 4.2 二进制文件并安装。请务必 select 为 Apple 芯片构建的二进制文件。
运行
$ sudo xcode-select --install
在终端中安装适用于 Xcode 的 Apple 命令行工具的最新版本,其中包括 Apple clang
。您可以从浏览器 here 获取早期版本。但是,您安装的版本不应早于 CRAN 用于构建 R 二进制文件的版本。
下载 gfortran
推荐的二进制文件 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
最后一个命令更新 gfortran
安装内的符号链接,使其指向命令行工具安装内的 SDK。
下载适合您的 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
将以下行添加到 $(HOME)/.R/Makevars
,必要时创建文件。
CPPFLAGS+=-I/usr/local/include -Xclang -fopenmp
LDFLAGS+=-L/usr/local/lib -lomp
FC=/opt/R/arm64/gfortran/bin/gfortran -mtune=native
FLIBS=-L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.6.0/12.0.1 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm
运行 R 并测试您是否可以编译支持 OpenMP 的程序。例如:
if (!requireNamespace("RcppArmadillo", quietly = TRUE)) {
install.packages("RcppArmadillo")
}
Rcpp::sourceCpp(code = '
#include <RcppArmadillo.h>
#ifdef _OPENMP
# include <omp.h>
#endif
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
void omp_test()
{
#ifdef _OPENMP
Rprintf("OpenMP threads available: %d\n", omp_get_max_threads());
#else
Rprintf("OpenMP not supported\n");
#endif
}
')
omp_test()
OpenMP threads available: 8
如果 C++ 代码编译失败,或者如果编译没有错误但您收到链接器警告或者您发现 OpenMP 不受支持,那么我们中的一个人可能犯了一个错误。请报告任何问题。
参考资料
一切都有点散乱:
我按照以下说明将 gfortran 的自制程序安装路径添加到我的 ~/.R/Makevars
中,从而解决了这个问题:https://pat-s.me/transitioning-from-x86-to-arm64-on-macos-experiences-of-an-r-user/#gfortran
我正在尝试在我的 M1 Mac 上使用 R 中需要 Rcpp
的软件包,我在购买这台计算机后一直无法起床和 运行ning。我将其更新为 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 安装了 this release of gfortran
。当我在终端中输入 which gfortran
时,它会显示 returns /opt/homebrew/bin/gfortran
。 (也许这个版本的 gfortran
需要 Xcode 太新的工具——它说的是 13.2,而当我 运行 clang --version
它说的是 13.0——但我没有看到gfortran
蒙特雷的另一个版本?)
我还在 R 中将 /opt/homebrew/bin:
附加到 PATH
,所以现在看起来像这样:
> Sys.getenv("PATH")
[1] "/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Library/TeX/texbin:/Applications/RStudio.app/Contents/MacOS/postback"
我检查的其他内容:
- Xcode 命令行工具已安装 (
which clang
returns/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
背景
目前 (2022-04-24),CRAN 使用 Apple clang
来自 Xcode 13.1 的命令行工具并使用 GNU Fortran 12 的实验分支为 Apple silicon 构建 R 4.2 二进制文件。
如果您从 CRAN 获得 R(即 here),那么您需要在构建包含 C/C++/Fortran 代码的 R 包之前在您的系统上复制 CRAN 的编译器设置来源(以及在使用 Rcpp
之前,等等)。此要求可确保您的包构建与 R 本身兼容。
更复杂的是 Apple clang
不支持 OpenMP,因此您需要做更多的工作来编译使用多线程的程序。您可以通过使用 LLVM clang
构建 R 本身和来自源的所有 R 包来规避这个问题,确实 支持 OpenMP,但这种方法很繁琐并且“对于仅限专家。
有一些 another 方法已经过一些人的测试,包括 R for macOS 的维护者 Simon Urbanek。它是实验性的并且“仅供专家使用”,但它可以在我的机器上运行并且比学习自己构建 R 简单得多。
获取工作工具链的说明
警告:这些产品不提供保修,随时可能损坏。假设您对 C/C++/Fortran 程序编译、Makefile 语法和 Unix shell 有一定程度的熟悉。鼓励每个人查阅 official 文档,这些文档比 SO 上的答案更有可能得到维护。与往常一样,sudo
风险自负。
我将尝试同时解决编译器和 OpenMP 支持问题。我假设你是从零开始的。随意跳过您已经执行的步骤,但您可能会发现重新开始会有所帮助。
我已经在机器 运行 Big Sur 上测试了这些指令,at least one person 已经在机器 运行 Monterey 上测试了它们。我很高兴收到其他人的来信。
从 CRAN here 下载 R 4.2 二进制文件并安装。请务必 select 为 Apple 芯片构建的二进制文件。
运行
$ sudo xcode-select --install
在终端中安装适用于 Xcode 的 Apple 命令行工具的最新版本,其中包括 Apple
clang
。您可以从浏览器 here 获取早期版本。但是,您安装的版本不应早于 CRAN 用于构建 R 二进制文件的版本。下载
gfortran
推荐的二进制文件 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
最后一个命令更新
gfortran
安装内的符号链接,使其指向命令行工具安装内的 SDK。下载适合您的 Apple
clang
版本 here 的 OpenMP 运行时并通过解压到 root 进行安装。您可以使用clang --version
查询您的 Appleclang
版本。比如我有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
将以下行添加到
$(HOME)/.R/Makevars
,必要时创建文件。CPPFLAGS+=-I/usr/local/include -Xclang -fopenmp LDFLAGS+=-L/usr/local/lib -lomp FC=/opt/R/arm64/gfortran/bin/gfortran -mtune=native FLIBS=-L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.6.0/12.0.1 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm
运行 R 并测试您是否可以编译支持 OpenMP 的程序。例如:
if (!requireNamespace("RcppArmadillo", quietly = TRUE)) { install.packages("RcppArmadillo") } Rcpp::sourceCpp(code = ' #include <RcppArmadillo.h> #ifdef _OPENMP # include <omp.h> #endif // [[Rcpp::depends(RcppArmadillo)]] // [[Rcpp::export]] void omp_test() { #ifdef _OPENMP Rprintf("OpenMP threads available: %d\n", omp_get_max_threads()); #else Rprintf("OpenMP not supported\n"); #endif } ') omp_test()
OpenMP threads available: 8
如果 C++ 代码编译失败,或者如果编译没有错误但您收到链接器警告或者您发现 OpenMP 不受支持,那么我们中的一个人可能犯了一个错误。请报告任何问题。
参考资料
一切都有点散乱:
我按照以下说明将 gfortran 的自制程序安装路径添加到我的 ~/.R/Makevars
中,从而解决了这个问题:https://pat-s.me/transitioning-from-x86-to-arm64-on-macos-experiences-of-an-r-user/#gfortran