Rcpp sourceCpp compiler settings - r

I am using Rcpp to speed up a function that gets called repeatedly in R (3.4, Windows7) and I was hoping to change the compiler settings.
When I call:
sourceCpp("scoreseq1.1.cc", verbose=TRUE)
Part of the output reads:
C:/RBuildTools/3.4/mingw_64/bin/g++ -I"C:/PROGRA~1/R/R-34~1.1/include" -O2 -Wall -mtune=core2 -c scoreseq1.1.cc -o scoreseq1.1.o
I would like to change -mtune to haswell, and -O2 to -O3 in search of some performance improvements.
Is there a way to do that through the sourceCpp or cppFunction, do I need a special header in my.cc file, or do I need to I need to modify some file on my system (and if so, what file?!)
Thanks!

No, you can't (easily), and in general not from a function.
These settings are "fixed" from when R itself is built. You can edit the file -- but you will have to so each time R is rebuilt / reinstalled.
On my box the file is $(R RHOME)/etc/Makeconf.

Just in case someone has a similar problem. You can do this in your C++ source. The following overrides command-line compiler settings:
void
__attribute__((optimize("-O3"),target("tune=haswell")))
foo()
{
// your code goes here
}
For reference take a look at: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html.

Related

Suppress warnings when building with GNU make in command line [duplicate]

This question already has an answer here:
Add compiler option without editing Makefile
(1 answer)
Closed 6 months ago.
Is there a way to suppress compiler warnings for GNU make and only show higher-order logs, i.e. errors?
Apparently, this should be possible using make -w as described here. However, for my version of GNU make (4.1), the man file specifies this as printing the current directory:
-w, --print-directory Print the current directory.
-W FILE
Consider FILE to be infinitely new.
If possible, this should be disabled both for make-internal warnings ($(warning ...)) and compiler-level warnings by gcc.
As pointed out in this post, it is not possible to directly add flags for the compiler. Furthermore, adding to existing CFLAGS variables (make CFLAGS+=-w) does not work either in most cases, as it ignores the append part and simply redefines the variable in the command line.
A very easy solution to fix this is by creating an empty dummy variable (once) inside your makefile and then defining it in case you need it:
# Add empty variable to add flags over command line
CDBG +=
CFLAGS += $(CDBG)
Which you then simply use as follows:
make CDBG=-w
as in https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
just add -w in your building command to suppress warnings, for example
gcc -Wall -w -o program pgmEcho.c pgm.c pgm.h

What is setting my environment variables wrong?

When I try to install.packages('readr'), I get errors deriving from
clang++ -I/usr/local/lib/R/include -DNDEBUG -I/usr/local/lib/R/include
-I/usr/local/include -I"/usr/local/lib/R/site-library/Rcpp/include"
-I"/usr/local/lib/R/site-library/BH/include"
-fpic -g -O2 -O3 -fstack-protector --param=ssp-buffer-size=4
-Wformat -Wformat-security -Werror=format-security
-D_FORTIFY_SOURCE=2 -g -std=c++11
-c Collector.cpp -o Collector.o
I'm checking ~/.R/Makevars and /etc/R/Makeconf for where this clang++ -I.... command might be set but neither contains that language.
echo $CXX
echo $CC
are both empty, and setting them to something else before starting R hasn't helped. Starting R --no-environ doesn't change the error message either.
So where might these environment variables be set, how can I change or disable them, and how do I figure out for next time where this "global variable from somewhere" error is coming from?
Thanks in advance.
I may have neededto addexport LIBRARY_PATH=/opt/boost_1_61_0/boost/to my~/.bashrc`.
This doesn't answer my question (of how to clean the clang call), but changing the CXX value in ~/.R/Makevars from clang++ to g++ did fix my immediate problem of not being able to install readr.
Here are the build errors under clang:
In file included from Collector.cpp:4:
In file included from ./Collector.h:8:
In file included from ./Token.h:6:
In file included from ./Source.h:5:
In file included from ./boost.h:13:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/include/qi.hpp:16:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi.hpp:14:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/action.hpp:14:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/action/action.hpp:14:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/meta_compiler.hpp:14:
In file included from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/support/meta_compiler.hpp:19:
In file included from /usr/local/lib/R/site-library/BH/include/boost/proto/proto.hpp:12:
In file included from /usr/local/lib/R/site-library/BH/include/boost/proto/core.hpp:21:
In file included from /usr/local/lib/R/site-library/BH/include/boost/proto/fusion.hpp:22:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/include/intrinsic.hpp:11:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/sequence/intrinsic.hpp:23:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/sequence/intrinsic/swap.hpp:15:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/view/zip_view.hpp:12:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/view/zip_view/zip_view.hpp:16:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/view/zip_view/detail/begin_impl.hpp:14:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/algorithm/transformation/transform.hpp:11:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/view/transform_view/transform_view.hpp:22:
In file included from /usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector10.hpp:25:
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:261:61: error:
invalid use of 'this' outside of a nonstatic member function
auto at_impl(J) -> decltype(at_detail<J::value>(this))
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:262:13: error:
type name requires a specifier or qualifier
{
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:262:13: error:
C++ requires a type specifier for all declarations
{
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:261:13: error:
'auto' return without trailing return type
auto at_impl(J) -> decltype(at_detail<J::value>(this))
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:268:67: error:
invalid use of 'this' outside of a nonstatic member function
auto at_impl(J) const -> decltype(at_detail<J::value>(this))
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:269:13: error:
type name requires a specifier or qualifier
{
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:269:13: error:
C++ requires a type specifier for all declarations
{
^
/usr/local/lib/R/site-library/BH/include/boost/fusion/container/vector/vector.hpp:268:13: error:
'auto' return without trailing return type
auto at_impl(J) const -> decltype(at_detail<J::value>(this))
^
8 errors generated.
make: *** [Collector.o] Error 1
ERROR: compilation failed for package ‘readr’
If I compile with g++ instead of clang++, the errors become warnings:
In file included from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/is_dereferenceable.hpp:12:0,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/resolve.hpp:26,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/push.hpp:24,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:31,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream_buffer.hpp:22,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream.hpp:21,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/detail/iterator_source.hpp:14,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/stream.hpp:16,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream.hpp:15,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi.hpp:30,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/include/qi.hpp:16,
from boost.h:14,
from Source.h:5,
from Token.h:6,
from Collector.h:8,
from Collector.cpp:4:
/usr/local/lib/R/site-library/BH/include/boost/type_traits/detail/bool_trait_def.hpp:18:79: note: #pragma message: NOTE: Use of this header (bool_trait_def.hpp) is deprecated
# pragma message("NOTE: Use of this header (bool_trait_def.hpp) is deprecated")
^
In file included from /usr/local/lib/R/site-library/BH/include/boost/type_traits/detail/bool_trait_def.hpp:21:0,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/is_dereferenceable.hpp:12,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/resolve.hpp:26,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/push.hpp:24,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:31,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream_buffer.hpp:22,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream.hpp:21,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/detail/iterator_source.hpp:14,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/stream.hpp:16,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream.hpp:15,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi.hpp:30,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/include/qi.hpp:16,
from boost.h:14,
from Source.h:5,
from Token.h:6,
from Collector.h:8,
from Collector.cpp:4:
/usr/local/lib/R/site-library/BH/include/boost/type_traits/detail/template_arity_spec.hpp:13:84: note: #pragma message: NOTE: Use of this header (template_arity_spec.hpp) is deprecated
gma message("NOTE: Use of this header (template_arity_spec.hpp) is deprecated")
^
In file included from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/is_dereferenceable.hpp:13:0,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/resolve.hpp:26,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/push.hpp:24,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/detail/streambuf/indirect_streambuf.hpp:31,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream_buffer.hpp:22,
from /usr/local/lib/R/site-library/BH/include/boost/iostreams/stream.hpp:21,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/detail/iterator_source.hpp:14,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream/stream.hpp:16,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi/stream.hpp:15,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/home/qi.hpp:30,
from /usr/local/lib/R/site-library/BH/include/boost/spirit/include/qi.hpp:16,
from boost.h:14,
from Source.h:5,
from Token.h:6,
from Collector.h:8,
from Collector.cpp:4:
(error is too long, pasted at http://ix.io/11F0)
So spirit and fusion are disliked by both compilers (with my chosen flags, which I still can't figure out how to clean).

Automake: AM_CFLAGS has no effect

I am trying to add some compilation options in Automake, but none of the approaches work.
Here is my configure.ac:
AC_INIT(...)
AC_PREREQ([2.59])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.10 foreign -Wall no-define])
AC_PROG_CXX
AC_PROG_LIBTOOL
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile test/Makefile])
AC_LANG(C++)
AC_OUTPUT
And I have the parent Makefile.am (in top-level dir):
#AM_CFLAGS = ... # doesn't work
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
SUBDIRS = src test
dist_noinst_SCRIPTS = autogen.sh
and a Makefile.am for each source dir; src/Makefile:
include_HEADERS = ...
lib_LIBRARIES = ...
and test/Makefile:
#AM_CFLAGS = ... # doesn't work
bin_PROGRAMS = myprog #test
myprog_SOURCES = ...
myprog_LDADD = ../src/libmylib.a
#myprog_CFLAGS = ... # Doesn't work either
I tried uncommenting all combinations of commented lines, i.e.:
add AM_CFLAGS = ... to the parent Makefile.am - this should set the CFLAGS for all affected sources
add AM_CFLAGS = ... to other two Makefile.ams
add myprog_CFLAGS = ... to Makefile.am (this should set CFLAGS when compiling myprog)
but none of these has any effects. Both my program (myprog) and its library (mylib) are kept being compiled / linked with some default flags which are something like -DHAVE_CONFIG -g -O2.
I also tried using INCLUDES instead of AM_CFLAGS, but didn't help.
Anybody has some idea what is going on here and how to fix it?
It looks like you're compiling C++, in which case the variable to use is AM_CXXFLAGS.
Setting AM_CXXFLAGS should be in the Makefile.am that declares things you're actually compiling (i.e., bin_PROGRAMS, lib_LTLIBRARIES, ...).
If you're repeating yourself, don't forget automake supports an include statement.
Recursive make considered harmful. Modern automake supports subdir-objects. If one Makefile.am gets out of hand, use include statements.
The modern way to turn on libtool is LT_INIT, not AC_PROG_LIBTOOL.
AC_LANG(C++) doesn't do anything at point of configure.ac. It sets the language to use when running configure tests. Besides, AC_LANG_PUSH and AC_LANG_POP are smarter ways of doing that.
Why are you assigning to ACLOCAL_AMFLAGS like that?
I tried adding AM_CFLAGS to the parent Makefile.am as suggested, which didn't work. When I added it to the relevant Makefile.am, it ended introducing two conflicting -g options as shown below:
libtool: link: gcc -std=gnu99 -g -O0 -g -O2 -Wl -pthread ...
The correct way to disable optimization is to add CFLAGS = -g -O0 to the Makefile.am where it's needed. Try deleting Makefile.in and Makefile (no extension) if the change doesn't take effect for some reason.
Here's the correct linker directive:
libtool: link: gcc -std=gnu99 -g -O0 -Wl -pthread ...

Running make from Outside the Tree

Let's say I have a makefile like the following:
CXXFLAGS := -I./Include
Foo:
$(CXX) $(CXXFLAGS) -o Foo
If the user cds into the source tree and runs make, everything is fine and dandy. However, if make is invoked from somewhere outside the source tree, the include directory will be incorrect.
Using full paths instead of relative paths works, but that destroys the portability of the makefile.
Should I just rely on users invoking make "properly?" Or is there an easy way to get around this?
If you want to have CXXFLAGS be -Isome_dir/Include
when the make is invoked asmake -f some_dir/Makefile,
MAKEFILE_LIST
might meet the purpose.
For example:
MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
CXXFLAGS := -I$(MAKEFILE_DIR)Include
If your make's version is 3.80 or lower, lastword might not work.
In that case,
$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) will work instead.
EDIT: This answer is for GNU-make.
Use the -C flag.
make -C my_dir
You could present your users a compile command that looks like (cd /to/proper/directory && make -k)

set LD_LIBRARY_PATH from Makefile

How do I set the LD_LIBRARY_PATH env variable from a Makefile?
I have some source code that links to a shared library that in turn links to a different shared library (more than 1). The Makefile for building the application only knows about the first shared library.
If I want to build this, I have to specify:
#export LD_LIBRARY_PATH=/path/to/the/shared/libs (for bash)
and that works fine.
However, I would like to do this from the Makefile itself.
Yes, "export" is the correct directive to use. It is documented in detail here. This is the same mechanism as make itself uses to propagate variables to sub-makes. The drawback is that you cannot selectively pass down the variable to some commands and not to others.
There are two other options I can think of:
Using .EXPORT_ALL_VARIABLES (specify as a target somewhere), causes all variables to be exported to the environment of sub-commands.
Specify on the command line:
foo:
EXPORTEDVAR=somevalue gcc $< -o $#
If you don't want to export the LD_LIBRARY_PATH variable within the makefile (e.g. because you have recursive Makefiles which all add to the variable), you can keep it bound to all calls to your compiler and linker.
Either you add it directly to all gcc and ld calls within your target rules, e.g.
my_target: my_target.o
LD_LIBRARY_PATH=/my/library/path gcc -o my_target my_target.o
or you set the global make variables that define the compilers include the path, e.g.:
CC=LD_LIBRARY_PATH=/my/library/path gcc
CPP=LD_LIBRARY_PATH=/my/library/path gcc
CXX=LD_LIBRARY_PATH=/my/library/path gcc
I chose gcc as compiler but of course you can use any compiler you like.
I had the same problem, I had to export LD_LIBRARY_PATH as you did:
export LD_LIBRARY_PATH=/path/to/the/shared/libs ; my_command
My friend showed me an alternative when LD_LIBRARY_PATH only applies to one command, notice no semicolon below.
LD_LIBRARY_PATH=/path/to/the/shared/libs my_command
This article explains more.
I had tried adding:
export LD_LIBRARY_PATH=/path/to/the/shared/libs
which apparently works fine.
I was getting errors because my /path/to/the/shared/libs was incorrect.
Would still be good to know what others do for this and/if there is a better way.
If you want to set LD_LIBRARY_PATH for a particular make , try this LD_LIBRARY_PATH=/path/to/the/shared/libs make.
Adding this to the top of the Makefile worked for me:
export LD_LIBRARY_PATH := $(HOME)/lib
Pay attention not to add any extra spaces to the end of the line. I wasted some time until I realized that was the problem.

Resources