Earlier this week, I received a note from CRAN about how my RcppTOML package was no longer building with the (as of right now of course unreleased) version 11 of the GNU C++ compiler, i.e.
g++-11. And very kindly even included a hint about the likely fix (which was of course correct). CRAN, and one of its maintainers in particular, is extremely forward-looking in terms of toolchain changes. A year ago we were asked to updated possible use of global variables in C code as
gcc-10 tightened the rules. This changes is a C++ one, and a fairly simple one of simply being more explicit with include headers. Previous
g++ release had done the same.
The question now was about the least painful way to get
g++-11 onto my machine, with the least amount of side-effects. Regular readers of this blog will know where this is headed, but even use of Docker requires binaries. A look at g++-11 within packages.debian.org comes up empty. No Debian means no Ubuntu. But … there is a PPA for Ubuntu with toolchain builds we have used before. And voilà there we have it: within the PPA for Ubuntu Toolchain repository is the volatile packages PPA with both
g++-11. Here Ubuntu 20.10 works with
g++-11 requires Ubuntu 21.04. Docker containers are there for either. So with the preliminaries sorted out, the key steps are fairly straightforward:
ubuntu:21.04to be able to install
software-properties-commonpackage to be able to add a PPA
sudo add-apt-repository ppa:ubuntu-toolchain-r/volatilecommand to add the volatile packages PPA
g++-11(along with, for good measure)
update-alternative(a clever Debian/Ubuntu command) to make version ‘11’ the default
r-base-core) which we simply take from the distro as 21.04 is by construction very recent
r-cran-rcppbinary which covers all dependencies for the package in question
And that is it! RcppTOML is fairly minimal and could be a member of the tinyverse so no other dependencies are needed—if your package has any you could just use the standard steps to install from source, or binary (including using RSPM or bspm). You can see the resulting Dockerfile which contains a minimal amount of extra stuff to deal with some environment variables and related settings. Nothing critical, but it smoothes the experience somewhat.
This container is now built (under label
rocker/r-edge with tags
gcc-11), and you can download it from Docker Hub. With that the ‘proof’ of the (now fixed and uploaded) package building becomes as easy as
edd@rob:~/git/rcpptoml(master)$ docker run --rm -ti -v $PWD:/mnt -w /mnt rocker/r-edge:gcc-11 g++ --version g++ (Ubuntu 11-20201128-0ubuntu2) 11.0.0 20201128 (experimental) [master revision fb6b29c85c4:a331ca6194a:e87559d202d90e614315203f38f9aa2f5881d36e] Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. edd@rob:~/git/rcpptoml(master)$ edd@rob:~/git/rcpptoml(master)$ docker run --rm -ti -v $PWD:/mnt -w /mnt rocker/r-edge:gcc-11 R CMD INSTALL RcppTOML_0.1.7.tar.gz * installing to library ‘/usr/local/lib/R/site-library’ * installing *source* package ‘RcppTOML’ ... ** using staged installation ** libs g++ -std=gnu++11 -I"/usr/share/R/include" -DNDEBUG -I../inst/include/ -DCPPTOML_USE_MAP -I'/usr/lib/R/site-library/Rcpp/include' -fpic -g -O2 -fdebug-prefix-map=/build/r-base-Fuvi9C/r-base-4.0.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c RcppExports.cpp -o RcppExports.o g++ -std=gnu++11 -I"/usr/share/R/include" -DNDEBUG -I../inst/include/ -DCPPTOML_USE_MAP -I'/usr/lib/R/site-library/Rcpp/include' -fpic -g -O2 -fdebug-prefix-map=/build/r-base-Fuvi9C/r-base-4.0.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c parse.cpp -o parse.o g++ -std=gnu++11 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o RcppTOML.so RcppExports.o parse.o -L/usr/lib/R/lib -lR installing to /usr/local/lib/R/site-library/00LOCK-RcppTOML/00new/RcppTOML/libs ** R ** inst ** byte-compile and prepare package for lazy loading ** help *** installing help indices ** building package indices ** testing if installed package can be loaded from temporary location ** checking absolute paths in shared objects and dynamic libraries ** testing if installed package can be loaded from final location ** testing if installed package keeps a record of temporary installation path * DONE (RcppTOML) edd@rob:~/git/rcpptoml(master)$
I hope both the availability of such a base container with
gfortran-11) as well as a “recipe” for building similar containers with newer clang version will help other developers.
If you like this or other open-source work I do, you can sponsor me at GitHub.