Selecting an alternative compiler for R package testing on Travis-CI

Editor’s Note: This post is based off of work by both Bob Rudis and Kevin Ushey on StackOverflow under the question Using an alternate compiler for Travis-CI R project builds. Thanks also to readers Bhaskar Karambelkar and Dirk Eddelbuettel for making suggestions on how to improve the post.

Introduction

Recently, the Armadillo project – led by the wonderful, rugged, australian Conrad Sanderson – has increased the gcc compiler requirement from 4.6 to 4.7.2. In turn, this rippled downstream to affect any package that has a dependency on RcppArmadillo. For users that do not use Travis-CI to continously check their package prior to submitting to CRAN, there is no change. However, for those that do use Travis-CI and its the default VM/container image – still serving Ubuntu Precise 12.04 despite the promised transition to Ubuntu Trusty 14.04 – their package will error on a package dependency instead of erroring on the material being tested. Specifically, the error will be:

checking whether g++ version is sufficient... no
configure: WARNING: Only g++ version 4.7.2 or greater can be used with RcppArmadillo.
configure: error: Please use a different compiler.

The error can be found in the logs associated with the build.

Using functions found in the tools package released with R 3.4.0, we can compute the amount of CRAN packages that depend on RcppArmadillo and, thus, may end up failing on a Travis-CI build due to the upstream change.

# CRAN Package Information
db = tools::CRAN_package_db()

# Number of total packages on CRAN
num_pkgs_db = nrow(db)

# Calculate number of dependencies
num_deb_arma = length(tools::dependsOnPkgs("RcppArmadillo",
                                           recursive = FALSE, installed = db))

Thus, there are 480 out of 12602 packages on CRAN whose testing procedure may be affected depending on their Travis-CI configuration. For an extended look at these functions in tools, take a look at Dirk Eddelbuettel’s R^4: Easy package information post.

Simple configuration fix

The easiest change is to pre-emptively set the distro variable in to trusty.

# Trusty was released later than precise
dist: trusty

This changes the VM image from Ubuntu Precise 12.04 with gcc 4.6.3 to Ubuntu Trusty 14.04 with gcc 4.8.2.

Advanced configuration of .travis.yml

Within this section, I’ll work through the different configuration options I’ve recently used to re-enable testing on the iccbeta package. The majority of configuration options is a mixture between responses by both Bob Rudis and Kevin Ushey on StackOverflow under the question Using an alternate compiler for Travis-CI R project builds.

We’ll begin with the standard devtools::use_travis() function call. From here, change sudo: false to sudo: required.

# Semi-standard devtools wrapper travis declaration
language: r
cache: packages
sudo: required

We’ll also request the VM to be on a newer operating system, e.g. Trusty 14.04 vs Precise 12.04. For further details, please see Travis-CI’s default VM Environment.

# Trusty was released later than precise
dist: trusty

Now, we’ll request a more up-to-date compiler from the ubuntu-r-toolchain test PPA (i.e Personal Package Archives).

# Install new packages via ubuntu's apt-get manager
# View available compilers in the ubuntu-toolchain-r ppa at:
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test
addons:
  apt:
    sources:
      - ubuntu-toolchain-r-test
    packages:
      - gcc-5
      - g++-5
      - gfortran-5

With the packages installed, we can create symbolic links to different programs using update-alternatives. Issuing update-alternatives leads to the link in /etc/alternatives being changed to reflect the correct binary. This setup maintains the current configuration across the system. If you need to manually set the variables, please see the end of this post for advice on manipulating ~/.R/Makevars.

before_install:
  - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 60 --slave /usr/bin/g++ g++ /usr/bin/g++-5
  - sudo update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran-5 60

Last, but not least, I’ve added the option to build the package on all versions of R that the DESCRIPTION file indicates is supported.

r:
  - 3.2
  - oldrel
  - release
  - devel

If all goes well, then you should end up with a nice green test matrix.

Fin

Over the course of the post, we had a situation where the default compiler on Travis-CI had to be changed due to new requirements in a package dependency. The details of the .travis.yml file for the compiler changed were addressed separately and are available for a single script download here:

https://github.com/tmsalab/iccbeta/blob/master/.travis.yml

Misc Note

If there is a preference to avoid overriding the binaries gcc and g++ in /bin or not using sudo: required, then a similar effect is possible by explicitly telling R about the new compiler versions. Achieving this is possible by specifying implicit variables found in R’s ~/.R/Makevars file. One important note to raise is the CC declaration also include a fixed compilation standard of 1999. This is due to the openssl package failing without it being set, which in turns causes failure to occur in installing devtools on Travis-CI.

# Specify local Makevars configuration
before_install:
  - mkdir -p ~/.R
  - VER=-5
  - echo "CC=gcc$(VER) -std=gnu99" >> ~/.R/Makevars
  - echo "CXX=g++$(VER)"           >> ~/.R/Makevars
  - echo 'CXX1X=$(CXX)'            >> ~/.R/Makevars
  - echo 'CXX11=$(CXX)'            >> ~/.R/Makevars
  - echo 'CXX14=$(CXX)'            >> ~/.R/Makevars
  - echo 'CXX14=$(CXX)'            >> ~/.R/Makevars
  - echo "SHLIB_CXXLD=g++$(VER)"   >> ~/.R/Makevars
  - echo "FC=gfortran$(VER)"       >> ~/.R/Makevars
  - echo "F77=gfortran$(VER)"      >> ~/.R/Makevars
comments powered by Disqus