Andrew Redd
Andrew Redd

Reputation: 4692

Changing CXXFLAGS in R CMD INSTALL for developing R packages

I'm trying to debug a package that I'm developing. I use a makefile for building, checking and installing the packages. The packages is an Rcpp package and so already has a makevars and makevars.win file in it. What I am looking for is a was to have CXXFLAGS changed just for a specific make rule. Then make debug will run R CMD INSTALL with CXXFLAGS= -Wall -pedantic -g -O0" but regular make install will run with CXXFLAGS=-O3 without any debugging info. is there a good way to dynamically change this without having to modify my package, personal or system makevars files?

Upvotes: 3

Views: 2110

Answers (2)

user2961927
user2961927

Reputation: 1728

Because GCC will only respect the last -O flag in the compilation command, any -O flag in the package's Makevars file will be overridden by -O2 in R's Makeconf file. Dirk's answer of setting a ~/.R/Makevars file will not work if the package is distributed to other platforms, unless you can tell everyone who uses the package to create or modify their ~/.R/Makevars.

Because -O3 is -O2 + some other flags, you can write your package's Makevars as follows:

PKG_CXXFLAGS += -fgcse-after-reload \
-fipa-cp-clone \
-floop-interchange \
-floop-unroll-and-jam \
-fpeel-loops \
-fpredictive-commoning \
-fsplit-loops \
-fsplit-paths \
-ftree-loop-distribution \
-ftree-partial-pre \
-funswitch-loops \
-fvect-cost-model=dynamic \
-fversion-loops-for-strides

These flags (see GCC manual https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) will be respected even with -O2 on the back.

In my years of experience with playing optimization flags in scientific computing on different platforms, -O3 almost never outperforms -O2 due to aggressive optimizations yielding larger binaries. The following however almost always generates the fastest code:

PKG_CXXFLAGS += -march=native -ftree-vectorize -ffast-math

Since GCC-12, -ftree-vectorize is switched on by default in -O2 and thus can be omitted.

Note that -ffast-math (https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-ffast-math) should be used with great care.

Upvotes: 0

Dirk is no longer here
Dirk is no longer here

Reputation: 368399

I don't think so as there is only one CXXFLAGS to go around. But you could reassign again in differnt 'make' vs `make debug' target portions.

You could just keep two versions ~/.R/Makevars.normal amd ~/R/Makevars.debug and use a script to flip a link between them...

For what it is worth. I just edit ~/.R/Makevars and comment/uncomment different lines.

Edit: What about something like this, based on the Makefile you posted:

install: $(PKG_NAME)_$(PKG_VERSION).tar.gz
    CXXFLAGS+="-O3" R CMD INSTALL $(PKG_NAME)_$(PKG_VERSION).tar.gz

debuginstall: $(PKG_NAME)_$(PKG_VERSION).tar.gz
    CXXFLAGS+="-Wall -g -O0" R CMD INSTALL $(PKG_NAME)_$(PKG_VERSION).tar.gz

Edit 2: I just played with this, and it works:

PKG_NAME=digest
PKG_VERSION=0.5.1

install: $(PKG_NAME)_$(PKG_VERSION).tar.gz
    PKG_CFLAGS="-O6" R CMD INSTALL $(PKG_NAME)_$(PKG_VERSION).tar.gz

debuginstall: $(PKG_NAME)_$(PKG_VERSION).tar.gz
    PKG_CFLAGS="-Wall -g -O0" R CMD INSTALL $(PKG_NAME)_$(PKG_VERSION).tar.gz

It still reads my ~/.R/Makevars afterwards so certain vars cannot be set here. But you could just set MYDEBUG=... in your Makefile and then use that inside a definition in ~/.R/Makevars.

Upvotes: 4

Related Questions