1

I have created a docker image based on Centos7 and installed R with the Dockerfile below:

FROM centos:7

ENV TZ=Etc/UTC

# OS Dependencies
RUN yum install -y \
    epel-release \
    centos-release-scl-rh \
    openblas-Rblas \
    devtoolset-8-toolchain \
    tre-devel \
    wget \
    libcurl-devel \
    && yum group install -y "Development Tools"

# Install R
RUN yum install -y \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/libRmath-devel-4.0.2-1.sdl7.x86_64.rpm \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/libRmath-4.0.2-1.sdl7.x86_64.rpm \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/R-java-devel-4.0.2-1.sdl7.x86_64.rpm \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/R-devel-4.0.2-1.sdl7.x86_64.rpm \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/R-core-devel-4.0.2-1.sdl7.x86_64.rpm \
    http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/R-core-4.0.2-1.sdl7.x86_64.rpm

I am trying to install the R package rlang but am getting an error related to "C99" mode that I cannot resolve.

> install.packages("rlang", repos = "https://cran.rstudio.org")
Installing package into '/usr/lib64/R/library'
(as 'lib' is unspecified)
trying URL 'https://cran.rstudio.org/src/contrib/rlang_0.4.10.tar.gz'
Content type 'application/x-gzip' length 915685 bytes (894 KB)
==================================================
downloaded 894 KB

* installing *source* package 'rlang' ...
** package 'rlang' successfully unpacked and MD5 sums checked
** using staged installation
** libs
gcc -m64 -I"/usr/include/R" -DNDEBUG -I./lib/  -I/usr/local/include  -fvisibility=hidden -fpic  -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic  -c capture.c -o capture.o
gcc -m64 -I"/usr/include/R" -DNDEBUG -I./lib/  -I/usr/local/include  -fvisibility=hidden -fpic  -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic  -c export.c -o export.o
In file included from export.c:1:0:
export/exported.c: In function 'rlang_env_bind_list':
export/exported.c:93:3: error: 'for' loop initial declarations are only allowed in C99 mode
   for (r_ssize i = 0; i < n; ++i) {
   ^
export/exported.c:93:3: note: use option -std=c99 or -std=gnu99 to compile your code
In file included from export.c:1:0:
export/exported.c: In function 'rlang_is_string':
export/exported.c:572:3: error: 'for' loop initial declarations are only allowed in C99 mode
   for (r_ssize i = 0; i < n; ++i) {
   ^
make: *** [export.o] Error 1
ERROR: compilation failed for package 'rlang'
* removing '/usr/lib64/R/library/rlang'

The downloaded source packages are in
        '/tmp/RtmpEmr8lk/downloaded_packages'
Updating HTML index of packages in '.Library'
Warning messages:
1: In install.packages("rlang", repos = "https://cran.rstudio.org") :
  installation of package 'rlang' had non-zero exit status
2: In file.create(f.tg) :
  cannot create file '/usr/share/doc/R-4.0.2/html/packages.html', reason 'No such file or directory'
3: In make.packages.html(.Library) : cannot update HTML package index

The error is the same one as discussed here, but I was looking for a solution that I could implement during image build (i.e. an environment var or change to an R config file) that would be persistent for those using the image and installing R packages in the future, allowing them to install with a simple call to install.packages() rather than having to use withr::with_makevars() for every package install.

Wil
  • 3,076
  • 2
  • 12
  • 31

1 Answers1

0

You can set R's config file under $R_HOME/etc/Makeconf (or add a Makevars in the same directory). By default, R_HOME should be in /usr/lib64/R, although you can get it in R by running > R.home().

Set CC = gcc -std=c11 (or whatever standard you like), you may also want to set CXX standard similarly.


Technically, you can also change what the gcc binary points to. I tried this after setting the CFLAGS environment variable failed. For example, you can rename the gcc binary (usually under /usr/bin) to something like gcc-v4.8.5. Then create a file called gcc (with proper exec permissions) in the same folder with the following shell script

#!/usr/bin/env bash
gcc-v4.8.5 -std=c99 "$@"

This will work by invoking gcc with that extra parameter but it's not recommended since it will probably break after updates to gcc. That said, I am not sure what happens to Makevars/Makeconf when R will be updated.

This shouldn't be a problem if the user runs gcc separately, it just sets the default standard that will be ignored if the user specifies the flag as well (since it will appear later in the command).