简体   繁体   中英

Rcpp Library Won't Build (Can't find Compiler) on Ubuntu

I have a package that depends on Rcpp and uses two other libraries compiled from sub-directories in src/ . The package builds fine on Mac OSX using a clang compiler. However, on an RStudio Ubuntu server, it fails to build. The build's first two steps (creating the static libraries in the sub directories to link in) work fine and I can see sensible build commands like the following taking place:

g++ -Wall -I../../inst/include/ --std=c++11 -lhts -L../htslib/ -lz -lm -c -o someLibFile.o someLibFile.cpp

However, in the very last step of the build process where it tries to build the Rcpp code and bind to the library, for some reason it appears to compleletey fail to put the compiler command in front ( g++ ) and only outputs the second half of the command.

 -o mypackage.so RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -L/htslib/ -Lpbbam/ -L/mnt/software/r/R/3.1.1/usr/lib/R/lib -lR

In contrast, on the Mac it builds just fine, appending clang++ and other flags in front of this final command:

 clang++ -std=c++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o pbbamr.so LoadData.o RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -Lhtslib/ -Lpbbam/ -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation

How do I make it use the g++ compiler on Ubuntu at this step? I have a custom Makevars file, but it is there just to build the dependencies in the sub-directory, so I don't know why that would cause any problems (since it works on Mac OSX).

More Information

The compiler seems to be found if I delete my Makevars file. However, the Makevars file I am using is essentially a direct copy of the example given in the R extensions guide with one addition to enable C++11:

 CXX_STD = CXX11
.PHONY: all mylibs

all: $(SHLIB)
    $(SHLIB): mylibs

mylibs:
    (cd subdir; make)

With the line CXX_STD removed, it does stick a compiler in front of the command.

Briefly:

  • What is your R installation? You should probably run the binaries provided by Michael via CRAN; they are based on my Debian upload; I run these too on a bunch of machines
  • The reason is that R 'remembers' its compile-time settings via $RHOME/etc/Makefconf . This should just be CXX=g+= .
  • When you install r-base-dev (from Ubuntu or the newer version from CRAN) you also get the build-essential package as well as all common dependencies. With that things just work.

If however you are doing something special or local, well then you have to deal with your local changes. The basic Ubuntu setup is used by thousands of people and daily jobs--including eg Travis builds for countless GitHub repos.

This is caused by using an outdated/unusual R installation which has poor support for C++11. The best way to resolve his is to upgrade to a more recent version of R, or use a standard R install ( sudo apt-get install r-base-dev ). A poor work around is described below.

Problems Cause and Bad Work Around

When writing R extension that use C++11, one often sets CXX_STD = CXX11 in the Makevars file or list SystemRequirements: C++11 in the DESCRIPTION file. These will trigger R to use the compiler set by the following flags in the Makeconf file (located at file.path(R.home(), "etc/Makeconf") ).

CXX1X
CXX1XFLAGS
CXX1XPICFLAGS
CXX1XSTD

Note that some of these may be set in this file, but not all of them might be there indicating a problem. In the event there is a problem with these settings or they are not set, R appears to use the empty string "" as the compiler/linker for the C++ code, leading to the problem shown above where no compiler argument is given.

If upgrading is not an option and you need to deploy on a known machine, one work around is to manually setup for C++11 by making a more idiosyncratic Makevars file. For example, you could:

  • Remove the CXX_STD=CXX11 line from the Makevars file.
  • Remove SystemRequirements: C++11 from the DESCRIPTION file.
  • Add --std=c++11 and any other requirements needed to PKG_CPPFLAGS , PKG_CFLAGS , PKG_CXXFLAGS or whatever variable is being used to compile your code, to manually set the needed flags (assuming the machine's compiler actually does support C++11).

The above solution is not particularly robust, but can be used as a work around in case the machine cannot be upgraded.

Thanks to @DirkEddelbuettel for not only writing Rcpp but being willing to support it on StackOverflow and help with issues like this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM