Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Makevars file to overwrite R CMD's default g++ options?

Tags:

c++

r

makefile

g++

I have this standalone C++ code that I'm trying to wrap in an R package.

My problem is that I absolutely want it to be compiled with the -O3 flag on.

So in the src/Makevars file I put:

PKG_CPPFLAGS = -I../inst/include
PKG_CXXFLAGS = -O3  
CXX_STD = CXX11

and still when I install my package on my machine, I see:

g++ -std=c++0x -I/usr/share/R/include -DNDEBUG -I../inst/include -O3  -fpic  -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c mycppfunctions.cpp -o mycppfunctions.o
g++ -std=c++0x -shared -Wl,-Bsymbolic-functions -Wl,-z,relro -o mycppfunctions.so mycppfunctions.o -L/usr/lib/R/lib -lR

(the dreaded -O2 flag appears to the right)

so my question is: how can I overwrite the cpp flags used when g++ is invoked by R CMD?

Edit:

Recently, in another package, I found a way to do something similar for a F77 code (also in an R package). Basically, by adding this to the Makevars:

PKG_FFLAGS = $(FPICFLAGS) $(SHLIB_FFLAGS) 
all: $(SHLIB)
otherf77foo.o: otherf77foo.f
    $(F77) $(PGK_FFLAGS) -O3 -pipe -g -c -o otherf77foo.o otherf77foo.f

but I don't know how to do the same for a cpp code...

Edit2:

So, doing this is totally possible. Dirk Eddelbuettel question 'b)' from his answer below guided me to the solution. So, all I had to do was to place this in the src/Makevars file:

mycppfoo.o: mycppfoo.cpp
    g++ -std=c++0x -I/usr/share/R/include -DNDEBUG -I../inst/include -fpic  -g -O3 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c mycppfoo.cpp -o mycppfoo.o
    g++ -std=c++0x -shared -Wl,-Bsymbolic-functions -Wl,-z,relro -o mycppfoo.so mycppfoo.o -L/usr/lib/R/lib -lR

and my problem was solved!

like image 350
user189035 Avatar asked May 01 '14 18:05

user189035


Video Answer


2 Answers

You can't (as per a comment by Simon Urbanek on r-devel a while back).

But it should not matter as AFAIK the right-most value wins. And R puts its values to the left, and lets you add your values (eg via CXX_FLAGS from, say, ~/.R/Makevars or PKG_CXXFLAGS from the src/Makevars in your package) to the right.

So just override with -O3 and it should be -O3.

For what it is worth, my current values in ~/.R/Makevars are:

CFLAGS +=              -O3 -Wall -pipe -pedantic -std=gnu99
CXXFLAGS +=            -O3 -Wall -pipe -Wno-unused -pedantic

and you could of course throw in -mnative or your specific CPU identifier.

Lastly, if you really wanted you could edit /etc/R/Makeconf but you'd have to do that after each upgrade of the R package. And as I argue here you do not need to as the scheme suggested here should work.

Edit: In response to your edit:

a) The clear recommendation on r-devel (please check the archives) is that you should avoid Makefile logic if you can. IIRC this echoed in the Writing R Extension manual.

b) You declared a rule to build an .o (object) file from an .f (source) file. Did you try doing the same with cpp instead of f?

Lastly, you have not explained exactly why the world is coming to an end if your file is built with -O2 rather than -O3. You should understand that as an author of source, you can't fully control with which compiler options (let alone compiler versions) people will build your package.

like image 98
Dirk Eddelbuettel Avatar answered Sep 18 '22 15:09

Dirk Eddelbuettel


newedit: Okay I'm a fool. It solved the problem for Rcpp (which I don't care about), but it doesn't work for the github.com/ohdsi/cyclops.git package that I do care about. That one still gets -O2 stuck right-most. This is ridiculous. Control over command-line parameters might be the single most important piece of this entire operation. R needs a better build system.

edit: Of course after days of trouble, I figure it out right after posting. My problem was that I was using the CXX_STD = CXX11 flag. Apparently with this flag you need to use CXX11FLAGS += .... So if your Makevars file contains CXX11FLAGS += -O0 -Wall it will correctly put this to the right of the -O2 flag if you're using C++11.

No matter what I do I can't get -O0 to show up on the right. I have the following in my ~/.R/Makevars:

CFLAGS +=       -O0 -Wall
CXXFLAGS +=     -O0 -Wall
CPPFLAGS +=     -O0 -Wall

PKG_CFLAGS +=       -O0 -Wall
PKG_CXXFLAGS +=     -O0 -Wall
PKG_CPPFLAGS +=     -O0 -Wall

I have installed Rcpp from source (as a test...I'm not interested in it directly) using

install.packages(getwd(), repos = NULL, type = "source")

and that did correctly use -O0.

With my current configuration, I end up getting three different -O0's to the left and final -O2 on the right. Has anyone else run into this problem?

The software I'm installing is at github.com/ohdsi/cyclops.git, though I'm not sure what that would be important.

like image 30
Thomas Nyberg Avatar answered Sep 22 '22 15:09

Thomas Nyberg