R Compiler Tools for Rcpp on macOS before R 4.5.0

programming
cpp
Author

James Balamuta

Published

April 21, 2023

This is a historical post that covers how to install the macOS toolchain for versions of R starting at 4.3.0 - 4.4.3.

For the current version of R (4.5.0 - 4.5.z), please see the post: R Compiler Tools for Rcpp on macOS.

Intro

The objective behind this post is to provide users with information on how to setup the macOS toolchain for compiling used in the R 4.3.0 - 4.4.3 series. The post is structured primarily for macOS Big Sur 11 and higher users.

Installation Instructions

One of the primary ways to setup the R toolchain for compiled code on macOS is to use either the automated R package installer or to individually install each element yourself.

There are two components to the R 4.3.0 - 4.4.3 toolchain based on Section: C.3 macOS of R Installation and Administration. These components are:

  1. Xcode Command Line Tools (“Xcode CLI”): 14.2 (Intel) or 14.3 (Apple Silicon M-series)
  2. GNU Fortran: gfortran 12.2 (Universal)

The gfortran component is dependent on the version of R being used.

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 R package.

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

You can see a video of the installation process here:

Run the following command in your R console to install the package:

# install.packages("remotes")
remotes::install_github("coatless-mac/macrtools")

With the package, you can run inside of R:

macrtools::install_macos_rtools()

Once done, please restart R to ensure that the changes take effect.

You can find source of the package at:

https://github.com/coatless-mac/macrtools

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’ 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

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

sudo xcode-select --install
  1. Press “Install”
  2. Verify installation by typing into terminal:
gcc --version

Install gfortran binary

The next step is to install the appropriate gfortran binary for your version of R.

For R 4.3.0 - 4.4.3, you will need to install gfortran 12.2. The R project makes available a universal installer package that works on both Intel and Apple Silicon (M-series) Macs.

https://mac.r-project.org/tools/gfortran-12.2-universal.pkg

Both of the installers will place the gfortran binary into /opt/gfortran/bin. This will be picked up by the default implicit variable set by R during compilation.

The version of gfortran changes based on the version of R being used. Please ensure that you are using the correct version of gfortran for your version of R.

Since the 4.3.0 and above series of R, the CRAN distributed version of R for macOS automatically assumes that the gfortran binary is located in /opt/gfortran/bin. If you have a custom version of gfortran installed, please ensure that you create a symbolic link to the binary in /opt/gfortran/bin or modify your ~/.Renviron file to point to the correct location.

If you have previously installed a version of gfortran and modified your ~/.Renviron file, please ensure that you update or remove your ~/.Renviron file to ensure that the correct version of gfortran is being used.

You can remove your custom ~/.Renviron file by running the following command:

file.remove("~/.Renviron")

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.

fatal error: ‘cmath’ file not found

If you’ve previously installed the Xcode CLI tools and upgraded to Xcode 16.0 or higher, you may see the following error when trying to compile code:

/Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library/Rcpp/include/Rcpp/platform/compiler.h:100:10: fatal error: 'cmath' file not found
  100 | #include <cmath>
      |          ^~~~~~~
1 error generated.

This is because Command Line Tools for Xcode 16 does not delete a directory that prior versions of Xcode did causing issues with the clang finding C++ headers. You can read more about this issue on the MacPorts’ macOS Sequoia Problems FAQ or the Issue #1333 in the Rcpp GitHub Issue Tracker.

The solution is to fully delete the library directory for Xcode CLI and, then, reinstall the Xcode CLI tools.

To do this, please open Terminal and run:

sudo rm -rf /Library/Developer/CommandLineTools

Please copy and paste the command directly into Terminal to avoid any typos. This is a destructive operation that will delete the Xcode CLI tools directory and all of its contents. However, with the rm -rf command, you can delete other files and directories if you mistype the target path.

Thus, please be careful when using this command.

You may be prompted for your password. This is the same password that you use to login to your Mac.

Then, reinstall the Xcode CLI tools via:

sudo xcode-select --install

make: gfortran: No such file or directory

If you try to compile code that uses Fortran without a correct version of gfortran for the R version being used, you may see the following error:

make: gfortran: No such file or directory
make: *** [/Library/Frameworks/R.framework/Resources/etc/Makeconf:196: object.o] Error 127
ERROR: compilation failed for package ‘package’

Please ensure that you have installed the correct version of gfortran for your version of R installed.

fatal error: ‘omp.h’ file not found

If you try to compile code that uses OpenMP, you may see the following error:

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

Beginning with R 4.0.0 the CRAN distributed version of R loses the ability to use OpenMP without a custom setup. This custom setup is reserved for advanced users. You can read more about this in the OpenMP support on macOS post.

OpenMP is not part of the default toolchain on macOS as Apple does not ship a version of clang with OpenMP support. However, it is possible to use the OpenMP headers and link against the OpenMP runtime library if you extract and install the appropriate files. This is considered an “advanced” setup and is not recommended for most users. Please see the OpenMP support on macOS post for details.

Acknowledgements

Thanks to dr.ing. MPH Verouden for catching a couple of errors in the post and letting me know!