R Compiler Tools for Rcpp on macOS

Editor’s Note: This is an updated post that covers how to install the macOS toolchain for versions of R starting at 3.6.z.

For R versions between R:

Intro

The objective behind this post is to provide users with information on how to setup the macOS toolchain for compiling used in the 3.5.* series of R. This has been a bit problematic for many R users since OS X Mavericks, which resulted in gfortran binaries being dropped from the R installer. More curiously, the additional demand to have access to a compiler vs. downloading a binary from CRAN became apparent slightly after Rcpp’s 0.10.0 version, when attributes where added that removed the necessity to use R’s SEXP objects.

Removing Old Installation Files

If you previously used either the clang4, clang6, or the macos-rtools installer, please consider deleting the old components that were installed.

To do so, open the Terminal from /Applications/Utilities/ and type:

# Delete the clang4 binary
sudo rm -rf /usr/local/clang4
# Delete the clang6 binary
sudo rm -rf /usr/local/clang6

# Delete the prior version of gfortran installed
sudo rm -rf /usr/local/gfortran
sudo rm -rf /usr/local/bin/gfortran

# Remove the install receipts that indicate a package is present

# Remove the gfortran install receipts (run after the above commands)
sudo rm -rf /private/var/db/receipts/com.gnu.gfortran.bom
sudo rm -rf /private/var/db/receipts/com.gnu.gfortran.plist

# Remove the clang4 installer receipt
sudo rm -rf /private/var/db/receipts/com.rbinaries.clang4.bom
sudo rm -rf /private/var/db/receipts/com.rbinaries.clang4.plist

# Remove the Makevars file
sudo rm -rf ~/.R/Makevars

In the prior configuration for R 3.4.x, we did a lot of configuration in ~/.R/Makevars. From R 3.5.x and up, the configuration method changes to modify the PATH variable using ~/.Renviron file and adding compilation flags to ~/.R/Makevars. Therefore, removing the old files installed to obtain a “fresh” slate is useful for working on installing the toolchain for R 3.6.x.

Note: If you are upgrading from R 3.0.0 - R 3.3.3 to R 3.6.x, you may have the old CRAN compiled gfortran4.8.2 binary. Please see the instructions at Removing the old R gfortran binary for assistance in removing the binary.

Installation Instructions

One of the primary ways to setup the R toolchain for compiled code on macOS is to individually installing each element yourself.

There are three components to the R 3.6.x toolchain based on Section: C.3 macOS of R Installation and Administration. These components are:

  1. Xcode Command Line Tools (“Xcode CLI”)
  2. clang7
  3. gfortran6.1

For historical information about the toolchain, please see: R macOS toolchain evolution

Manual Install Guide

This guide provides a step-by-step breakdown of the actions required to setup the toolchain. As a result, this guide will use both installers and script commands ia Terminal.app found in /Applications/Utilities/. Terminal is macOS’s equivalent to Linux’s shell and Window’s command line. From Terminal, we will install only the XCode Command Line Tools (“Xcode CLI”). These provide the system headers used to build the official CRAN binary for R.

XCode Command Line Tools

  1. Open the Terminal from /Applications/Utilities/
  2. Type the following into Terminal

    • Note: Anytime the Xcode CLI toolchain updates, you must re-run this command.

      xcode-select --install
      
  3. Press “Install”

  4. Verify installation by typing into terminal:

    gcc --version
    

Note: If you are on macOS Mojave (10.14) or higher, you will need to add into ~/.R/Makevars a set of compilation flags.

mkdir -p ~/.R

# Fill with appropriate flag statements
cat <<- EOF > ~/.R/Makevars
# clang: start
CFLAGS=-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
CCFLAGS=-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
CXXFLAGS=-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
# clang: end
EOF

Installing the clang7 R binary

The clang7 binary can be obtained at:

https://cran.r-project.org/bin/macosx/tools/clang-7.0.0.pkg

from the macOS Tools Page

  1. Download and run the installer.

  2. Open the Terminal from /Applications/Utilities/

  3. Type:

    touch ~/.Renviron
    echo 'PATH="/usr/local/clang7/bin:${PATH}"' >> ~/.Renviron
    

Install gfortran6.1 binary

The gfortran6.1 binary can be obtained at:

https://cran.r-project.org/bin/macosx/tools/gfortran-6.1.pkg

from the macOS Tools Page

Download and run the installer.

Quick check

To verify that everything is working appropriately, let’s do a quick C++ program using Rcpp and Armadillo.

First, let’s install Rcpp and RcppArmadillo within R.

install.packages(c('Rcpp', 'RcppArmadillo'))

Create a new file, name the follow: helloworld.cpp

By adding the .cpp extension, the file is viewed as being C++ code.

Within the file write:

#include <RcppArmadillo.h>   

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
void hello_world() {
  Rcpp::Rcout << "Hello World!" << std::endl;  
}

// After compile, this function will be immediately called using
// the below snippet and results will be sent to the R console.

/*** R
hello_world() 
*/

Compile the function using:

Rcpp::sourceCpp('path/to/file/helloworld.cpp')

where 'path/to/file/' is the location containing helloworld.cpp

If everything is installed appropriately, then you should see the following in the console:

> hello_world()

Hello World!

In addition, you should have a new function within the global environment scope called “hello_world”. You can call this function like a normal R function via:

hello_world()

Common Errors

The following are debugged errors that you may run into.

Why can’t R find the clang7 compiler even though I installed it and setup the ~/.Renviron?

There are three ways to encounter this issue:

First, the issue will appear as a warning when you first install RcppArmadillo from source. e.g.

install.packages("RcppArmadillo", type = "source")

The configure script will say:

checking for macOS... found
checking for macOS Apple compiler... found
configure: WARNING: OpenMP unavailable and turned off.

Secondly, if you try to compile a script locally using the pre-built CRAN binary for RcppArmadillo, then you will run into:

clang: warning: argument unused during compilation: '-fopenmp'
fatal error: 'omp.h' file not found

Third way – and the least common – is to have missing build commands. This error is likely due to an improperly specified PATH variable.

sh: make: command not found
sh: rm: command not found
Warning message:
In system(cmd) : error in running command

The fixes for each of these problems can be broken down related to:

  1. Launching R from terminal
    • Do you have any custom bindings, e.g. alias R ="R --flag1 --flag2"?
    • Are there any flags with the R call like --vanilla or --no-environ?
      • For --vanilla, please switch to --no-save --no-restore --no-site-file --no-init-file.
      • Otherwise, please remove --no-environ from the list.
  2. Poorly formatted ~/.Renviron
    • Are there multiple PATH variables or just one?
      • If so, delete and/or merge together the multiple copies of PATH.
    • Did you type the path correctly in ~/.Renviron?
      • Verify PATH="/usr/local/clang6/bin:${PATH}"
  3. Location of Installation
    • Did you install the clang-7.0.0.pkg?
      • Check if a folder is present: ls /usr/local/clang6