Mon, 27 Jul 2026

#057: Condionally Quieten Compilers

Welcome to post 57 in the R4 series.

R packages with compiled codes can use the file src/Makevars to set compilation flags. We often rely on this to set libraries, include directories or compilation options. When using external libraries, be it header-only or via headers and linking, we are often experiencing ‘compilation noise’ when these libraries tickle warnings under generally-recommended flags such as -Wall -pedantic. Two packages I maintain are clearly repeat offenders here: Eigen, and BH. Both cam generate pages and pages of compiler output. This is generally not great as it may hide genuine warnings from our own code.

What makes matters worse is that some of the available and specific options for the compilers are treated by R CMD check as ‘non-portable’ leading to a nag on package checking. Examples are -Wno-parentheses, -Wno-maybe-uninitialize or -Wno-nunnull.

I have long resorted to adding these to my per-user ~/.R/Makevars. When added there, compilation is quieter, but R CMD check still nags here where the option is set but not at CRAN or r-universe. A situation that is not ideal but what somewhat ‘stable’.

More recently, I realized there was an available check we can use to conditionally add extra compilation flags but leave them off by default. That makes local development quiet allowing us to focus on the quality of our additions here without noise from third-party libraries we may use. At the same time we do not need to do anything else to let CRAN do its work.

The check we now use is whether there is a .git/ directory present. If so, we are indeed building from local sources and can add extra flags. If not, we are likely building from a tar.gz source archive—which is the case for CRAN—and hence do not set these.

An example use is this recent additional to package qlcal where this bit of R code is invoked from a minimal shell script configure and replaces the stub @XTRAFLAGS@ in src/Makevars.in (or src/Makevars.win.in)

if (dir.exists(".git")) {
    ## development from a .git directory can use these flags
    xtraflags <- "-Wno-nonnull -Wno-deprecated-declarations"
} else {
    ## else build from tarball so stick with existing flags
    xtraflags <- ""
}
win <- if (Sys.info()[["sysname"]] == "Windows") ".win" else ""
infile <- file.path("src", paste0("Makevars", win, ".in"))
outfile <- file.path("src", paste0("Makevars", win))
lines <- readLines(infile)
lines <- gsub("@XTRAFLAGS@", xtraflags, lines)
writeLines(lines, outfile)

With this change, local compilation is quiet, yet CRAN has nothing to nag about (as seen at the qlcal results page).

Similarly, one can also check from an actual configure file written in autoconf. Here is a similar example from RcppEigen (showing some relevants parts of the whole file)

# PKG_CXXFLAGS initialized earlier ...

## Check if building locally
AC_MSG_CHECKING([whether .git/ exists])
if test -d "$srcdir/.git"; then
    AC_MSG_RESULT([yes, adding extra flags])
    AC_SUBST([PKG_CXXFLAGS],["${PKG_CXXFLAGS} -Wno-ignored-attributes -Wno-maybe-uninitialized"])
else
    AC_MSG_RESULT([no, consider adding '-Wno-ignored-attributes -Wno-maybe-uninitialized' to ~/.R/Makevars])
fi

AC_SUBST([PKG_CXXFLAGS], ["${PKG_CXXFLAGS}"])
AC_CONFIG_FILES([src/Makevars])
AC_OUTPUT

Once again, with this change compilation is quiet locally, yet unaffected at CRAN. Just what we want. Give it a try in your packages.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.

/code/r4 | permanent link