I often install R packages from source, and need a properly configured ~/.R/Makevars
to do this. I want to be able to use OpenMP, so I copied a Makevars
I found online. My Makevars
ended up being this:
OPT_LOC = $(HOME)/homebrew/opt
LLVM_LOC = $(OPT_LOC)/llvm
CC=$(LLVM_LOC)/bin/clang
CXX=$(LLVM_LOC)/bin/clang++
# CFLAGS and CXXFLAGS *with* -fopenmp
CFLAGS=-fopenmp -g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
CXXFLAGS=-fopenmp -g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
# CFLAGS and CXXFLAGS *without* -fopenmp
# (sometimes the package install process fails if -fopenmp is present)
# CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
# CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
LDFLAGS=-L$(OPT_LOC)/gettext/lib -L$(LLVM_LOC)/lib -Wl,-rpath,$(LLVM_LOC)/lib
CPPFLAGS=-I$(OPT_LOC)/gettext/include -I$(LLVM_LOC)/include
I can no longer find the original source of my version, but it's similar to this one.
My Makevars
works great, except for a few packages, like stringi. These packages complain that "C compiler cannot create executables". I discovered that this error generally goes away if I remove -fopenmp
from CFLAGS
and CXXFLAGS
. As you can see, I've set up Makevars
so I can easily switch back and forth between the configuration with -fopenmp
and without it.
My workaround works fine, as does the workaround of "delete Makevars
entirely" in the Stack Overflow post linked above. But isn't there a better way? It's annoying that I can't expect package installs to succeed because of these dependencies that hate the -fopenmp
flag, while removing the flag means I might miss out on OpenMP on some package installs.
If you use GCC instead of Clang you should be able to install stringi with OpenMP enabled. I've tested a number of different solutions and ultimately came up with these steps to successfully install stringi from source with the -fopenmp
flag (Intel macOS v11 (Big Sur)):
Reinstall the Xcode command line tools (don't believe Software Update if it says 'up to date' - it lies - brew doctor
said my version was actually old)
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
Install GCC and LLVM via Homebrew (instructions for installing Homebrew) or, if you already have GCC/LLVM installed, skip to the next step.
# WARNING: This can take several hours
brew install gcc
brew install llvm
If you already have GCC and LLVM installed via Homebrew:
brew cleanup
brew update
brew upgrade
brew reinstall gcc
brew reinstall llvm
Link some headers into /usr/local/include
sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/* /usr/local/include/
# I believe you can safely ignore warnings like this:
#ln: /usr/local/include//tcl.h: File exists
#ln: /usr/local/include//tclDecls.h: File exists
#ln: /usr/local/include//tclPlatDecls.h: File exists
#ln: /usr/local/include//tclTomMath.h: File exists
#ln: /usr/local/include//tclTomMathDecls.h: File exists
#ln: /usr/local/include//tk.h: File exists
#ln: /usr/local/include//tkDecls.h: File exists
#ln: /usr/local/include//tkPlatDecls.h: File exists
Edit your ~/.R/Makevars
file (if you don't have a file called Makevars
in your ~/.R/
directory, create it) and include only these lines:
LOC = /usr/local/gfortran
CC=$(LOC)/bin/gcc -fopenmp
CXX=$(LOC)/bin/g++ -fopenmp
CXX11 = $(LOC)/bin/g++ -fopenmp
CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
LDFLAGS=-L$(LOC)/lib -Wl,-rpath,$(LOC)/lib
CPPFLAGS=-I$(LOC)/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
FLIBS=-L/usr/local/gfortran/lib/gcc/x86_64-apple-darwin19/10.2.0 -L/usr/local/gfortran/lib -lgfortran -lquadmath -lm
CXX1X=/usr/local/gfortran/bin/g++
CXX98=/usr/local/gfortran/bin/g++
CXX11=/usr/local/gfortran/bin/g++
CXX14=/usr/local/gfortran/bin/g++
CXX17=/usr/local/gfortran/bin/g++
Compile a package from source in R/RStudio
# Test if OpenMP is actually enabled
install.packages("data.table", type = "source")
# (loading data.table will tell you if it was successful)
# Compile the stringi package from source
install.packages("stringi", type = "source")
NB: Some users have commented that they had to install a 'fresh' GFortran (e.g., GFortran 10.2 for Big Sur (macOS 11), for Intel processors) to compile packages successfully, and others have commented that they didn't need LLVM, but these steps seem to work in most cases.
I recently had an error when updating "RcppAlgos" using this ~/.R/Makevars (couldn't find gmp.h or libgmp). I checked gmp was installed (brew install gmp
), then added /usr/local/include to CPPFLAGS and /usr/local/lib to LDFLAGS in the ~/.R/Makevars file to solve the problem, and hopefully prevent similar issues in the future, i.e. edit your Makevars to contain these lines only:
LOC=/usr/local/gfortran
CC=$(LOC)/bin/gcc -fopenmp
CXX=$(LOC)/bin/g++ -fopenmp
CXX11 = $(LOC)/bin/g++ -fopenmp
CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
LDFLAGS=-L$(LOC)/lib -Wl,-rpath,$(LOC)/lib,-L/usr/local/lib
CPPFLAGS=-I$(LOC)/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/usr/local/include
FLIBS=-L/usr/local/gfortran/lib/gcc/x86_64-apple-darwin19/10.2.0 -L/usr/local/gfortran/lib -lgfortran -lquadmath -lm
CXX1X=/usr/local/gfortran/bin/g++
CXX98=/usr/local/gfortran/bin/g++
CXX11=/usr/local/gfortran/bin/g++
CXX14=/usr/local/gfortran/bin/g++
CXX17=/usr/local/gfortran/bin/g++