'Configuring compilers on Mac M1 (Big Sur, Monterey) for Rcpp and other tools
I'm trying to use packages that require Rcpp
in R on my M1 Mac, which I was never able to get up and running after purchasing this computer. I updated it to Monterey in the hope that this would fix some installation issues but it hasn't. I tried running the Rcpp
check from this page but I get the following error:
> 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.
I get that it can't "find" gfortran
. I installed this release of gfortran
for Monterey. When I type which gfortran
into Terminal, it returns /opt/homebrew/bin/gfortran
. (Maybe this version of gfortran
requires Xcode tools that are too new—it says something about 13.2 and when I run clang --version
it says 13.0—but I don't see another release of gfortran
for Monterey?)
I also appended /opt/homebrew/bin:
to PATH
in R so it looks like this now:
> 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"
Other things I checked:
- Xcode command line tools is installed (
which clang
returns/usr/bin/clang
). - Files
~/.R/Makevars
and~/.Renviron
don't exist.
Here's my session info:
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
Solution 1:[1]
Background
Currently (2022-04-24), CRAN builds R 4.2 binaries for Apple silicon using Apple clang
from Command Line Tools for Xcode 13.1 and using an experimental fork of GNU Fortran 12.
If you obtain R from CRAN (i.e., here), then you need to replicate CRAN's compiler setup on your system before building R packages that contain C/C++/Fortran code from their sources (and before using Rcpp
, etc.). This requirement ensures that your package builds are compatible with R itself.
A further complication is the fact that Apple clang
doesn't support OpenMP, so you need to do even more work to compile programs that make use of multithreading. You could circumvent the issue by building R itself and all R packages from sources with LLVM clang
, which does support OpenMP, but that approach is onerous and "for experts only".
There is another approach that has been tested by a few people, including Simon Urbanek, the maintainer of R for macOS. It is experimental and also "for experts only", but it works on my machine and is much simpler than learning to build R yourself.
Instructions for obtaining a working toolchain
Warning: These come with no warranty and could break at any time. Some level of familiarity with C/C++/Fortran program compilation, Makefile syntax, and Unix shells is assumed. Everyone is encouraged to consult official documentation, which is more likely to be maintained than answers on SO. As usual, sudo
at your own risk.
I will try to address compilers and OpenMP support at the same time. I am going to assume that you are starting from nothing. Feel free to skip steps you've already taken, though you might find a fresh start helpful.
I've tested these instructions on a machine running Big Sur, and at least one person has tested them on a machine running Monterey. I would be glad to hear from others.
Download an R 4.2 binary from CRAN here and install. Be sure to select the binary built for Apple silicon.
Run
$ sudo xcode-select --install
in Terminal to install the latest release version of Apple's Command Line Tools for Xcode, which includes Apple
clang
. You can obtain earlier versions from your browser here. However, the version that you install should not be older than the one that CRAN used to build your R binary.Download the
gfortran
binary recommended here and install by unpacking to 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
The last command updates a symlink inside of the
gfortran
installation so that it points to the SDK inside of your Command Line Tools installation.Download an OpenMP runtime suitable for your Apple
clang
version here and install by unpacking to root. You can query your Appleclang
version withclang --version
. For example, I have version 1300.0.29.3, so I did:$ 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 /
After unpacking, you should find these files on your system:
/usr/local/lib/libomp.dylib /usr/local/include/ompt.h /usr/local/include/omp.h /usr/local/include/omp-tools.h
Add the following lines to
$(HOME)/.R/Makevars
, creating the file if necessary.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
Run R and test that you can compile a program with OpenMP support. For example:
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
If the C++ code fails to compile, or if it compiles without error but you get linker warnings or you find that OpenMP is not supported, then one of us has probably made a mistake. Please report any issues.
References
Everything is a bit scattered:
Solution 2:[2]
I resolved this issue by adding a path to the homebrew installation of gfortran to my ~/.R/Makevars
following these instructions: https://pat-s.me/transitioning-from-x86-to-arm64-on-macos-experiences-of-an-r-user/#gfortran
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | AFH |