Table of Contents
TL;DR: include OBJCXX=clang++ -std=gnu++17
in .R/Makevars
to help install.pacakges
to help Object-C code compilation.
Error messages
I wanted to install tidyverse
on a new Mac. Almost everything worked out of the box, except for one thing: R
's systemfonts
triggered an hour of pain. clang++
stopped parsing when it encountered mac/FontManagerMac.mm
while complaining that it was unable to understand c++11
features, e.g., constexpr
.
clang++ -I"/opt/homebrew/Cellar/r/4.4.2_2/lib/R/include" -DNDEBUG -I/opt/homebrew/opt/freetype/include/freetype2 -I/opt/homebrew/opt/libpng/include/libpng16 -I'/opt/homebrew/lib/R/4.4/site-library/cpp11/include' -I/opt/homebrew/opt/gettext/include -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/xz/include -I/opt/homebrew/include -fobjc-arc -fPIC -c mac/FontManagerMac.mm -o mac/FontManagerMac.o
In file included from mac/FontManagerMac.mm:5:
In file included from mac/../FontDescriptor.h:11:
In file included from mac/../utils.h:9:
In file included from /opt/homebrew/lib/R/4.4/site-library/cpp11/include/cpp11/protect.hpp:10:
/opt/homebrew/lib/R/4.4/site-library/cpp11/include/cpp11/R.hpp:52:1: error: unknown type name 'constexpr'
52 | constexpr R_xlen_t operator"" _xl(unsigned long long int value) { return value; }
| ^
/opt/homebrew/lib/R/4.4/site-library/cpp11/include/cpp11/R.hpp:52:19: error: expected ';' after top level declarator
52 | constexpr R_xlen_t operator"" _xl(unsigned long long int value) { return value; }
| ^
| ;
Solution: make your Clang++
understand new features
I believe CRAN packages are generally well prepared to handle C/C++ compiling, except for Object-C! We need to include the following line to .R/Makevars
for a silicon Mac:
OBJCXX=clang++ -std=gnu++17
We could additionally tweak so that compilation processes can take place on many files with an additional flag:
MAKEFLAGS = -j10
Here, we run 10 jobs simultaneously.
Another issue on openmp
In order to compile Rcpp
codes with <omp.h>
, we also need libomp
for multi-threading. We can add more lines to .R/Makevars
and here is an example:
LDFLAGS += -L/opt/homebrew/opt/llvm/lib
LDFLAGS += -L/opt/homebrew/opt/libomp/lib -lomp
CXXFLAGS += -I/opt/homebrew/opt/llvm/include
CXXFLAGS += -I/opt/homebrew/opt/libomp/include -Xclang -fopenmp
CPPFLAGS += -I/opt/homebrew/opt/llvm/include
CPPFLAGS += -I/opt/homebrew/opt/libomp/include -Xclang -fopenmp
PKG_LDFLAGS += $(LDFLAGS)
PKG_CXXFLAGS += $(CXXFLAGS)
PKG_CPPFLAGS += $(CPPFLAGS)
OBJCXX = clang++ -std=gnu++17
MAKEFLAGS = -j10