R Compiler Tools for Rcpp on macOS before R 4.0.0

programming
cpp
Author

TheCoatlessProfessor

Published

May 14, 2019

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 other R versions, please see:

At one point during the 3.6.3 release window, Rcpp v1.0.4 would fail to compile on various builds. Instructions and details behind why this happened can be found here.

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.6.* series of R. The post is structured primarily for macOS Catalina (10.15.2) users.

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.

Instructions for uninstallation can be found here:

Uninstalling the R development toolchain on macOS

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

Automatic Installation

The instructions in the next section breakdown how to install the different components for a toolchain on macOS. If you are unfamiliar with Terminal, please consider using the unofficial macOS Rtools installer package.

https://github.com/rmacoslib/r-macos-rtools/releases

Note: This installer package is community maintained and is not affiliated with either R Core or CRAN. Hence, this installer package is unofficial.

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
  1. Press “Install”
  2. 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
CPPFLAGS=-isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include

SHLIB_CXXLDFLAGS+=-Wl,-rpath,\${R_HOME}/lib \${R_HOME}/lib/libc++abi.1.dylib
SHLIB_CXX14LDFLAGS+=-Wl,-rpath,\${R_HOME}/lib \${R_HOME}/lib/libc++abi.1.dylib
# clang: end
EOF

Special thanks to go out to: Kevin Ushey of RStudio as well as Sebastian Weber (wds15) and Ben Goodrich (@bgoodri) of the Stan project for their work in helping identify an ABI break in macOS Catalina (10.15.z) that resulted in needing both SHLIB_CXXLDFLAGS and SHLIB_CXX14LDFLAGS.

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/clang7/bin:${PATH}"
  3. Location of Installation
    • Did you install the clang-7.0.0.pkg?
      • Check if a folder is present: ls /usr/local/clang7