[Phylobase-devl] Rcpp and OS X compiliation

Dirk Eddelbuettel edd at debian.org
Fri Jan 15 18:56:26 CET 2010


Hello,

Ben kindly CC'ed me as I am not on phylobase-dev.

On 15 January 2010 at 12:16, Ben Bolker wrote:
| Mark Holder wrote:
| > $ R
| >  > install.packages(c("ape", "Rcpp"))
| > Warning in install.packages(c("ape", "Rcpp")) :
| >     argument 'lib' is missing: using '/Users/mholder/Library/R/2.10/ 
| > library'
| > ....
| > #############################
| > despite the warning it ran (I'm not R-savvy enough to know if this  
| > indicates a problem).
| 
|   No.  It's putting the package in a default location (why it issues a
| warning in this case is another conversation).

(AFAICT because install.packages() assumes you give it a lib= argument as
well, I never do either and find the warning equally silly.)

| > I was able to call library(Rcpp) and library(ape) from within R with  
| > no errors.

library(Rcpp) is not a great test, that just uses the package's own code that
also uses Rcpp. What we want is a test of compiling and linking against Rcpp
and I have long thought that a 'hello, World'-style package that did just
that would help.  Romain just started to add Rcpp.package.skeleton() to the
SVN which may help.

| > $ cd phylobase
| > $ R CMD INSTALL pkg
| > * installing to library ‘/Users/mholder/Library/R/2.10/library’
| > * installing *source* package ‘phylobase’ ...
| > ...
| > ########################
| > There was lots of configure and make output, of course.
| > Of note to me were the
| > 
| > 	-L/Users/mholder/Library/R/2.10/library/Rcpp/lib/i386 -lRcpp flags in  
| > the linking step command.
| > 
| > 
| > I did get a ld warning: duplicate dylib /usr/local/lib/libgcc_s.1.dylib
| > 
| > but the build exited without error.
| > 
| > When I try to import phylobase I get an error similar to the one seen  
| > on https://r-forge.r-project.org/R/?group_id=111&log=check_x86_64_mac&pkg=phylobase&flavor=patched
| > 
| > Specifically I see:
| > 
| > 
| [snip]
| 
| 
| > library(phylobase)
| > Loading required package: grid
| > Loading required package: ape
| > Loading required package: Rcpp
| > Error in dyn.load(file, DLLpath = DLLpath, ...) :
| >    unable to load shared library '/Users/mholder/Library/R/2.10/ 
| > library/phylobase/libs/i386/phylobase.so':
| >    dlopen(/Users/mholder/Library/R/2.10/library/phylobase/libs/i386/ 
| > phylobase.so, 6): Library not loaded: /Builds/Rdev-web/QA/Simon/ 
| > packages/tiger-universal/Rlib/2.10/Rcpp/lib/i386/libRcpp.dylib
| >    Referenced from: /Users/mholder/Library/R/2.10/library/phylobase/ 
| > libs/i386/phylobase.so
| >    Reason: image not found
| > Error: package/namespace load failed for 'phylobase'
| > 
| > #################################################################################
| > 
| > 
| > But if I alter my shell's env to contain the path to libRcpp.dylib  
| > then it works:
| > 
| > #################################################################################
| > $ ls /Users/mholder/Library/R/2.10/library/Rcpp/lib/i386/
| > Rcpp                   RcppCommon.h           RcppDateVector.h        
| > RcppDatetimeVector.h   RcppFunction.h         RcppMatrix.h            
| > RcppNumList.h          RcppResultSet.h        RcppStringVector.h      
| > RcppVector.h           libRcpp.a
| > Rcpp.h                 RcppDate.h             RcppDatetime.h          
| > RcppFrame.h            RcppList.h             RcppMatrixView.h        
| > RcppParams.h           RcppSexp.h             RcppStringVectorView.h  
| > RcppVectorView.h       libRcpp.dylib
| > $ export DYLD_LIBRARY_PATH=/Users/mholder/Library/R/2.10/library/Rcpp/ 
| > lib/i386
| > $ r
| > 
| [snip successful attempt]
| > 
| > So it appears to be an issue of the dynamic linker not finding the  
| > right version of libRcpp.dylib
| > 
| > 
| > I'm not sure how to fix it other than altering the user's env (which  
| > is obviously not ideal).  

The idea (originally suggested by Simon Urbanek who also supplied quite some
help in getting the dylib business right) was that from an R prompt (or shell
prompt via Rscript / littler) you could call Rcpp itself by using the
functions 

	  Rcpp:::CxxFlags()
	  Rcpp:::LdFlags()

to leanrn about the precise -I and -L invocations to g++ et al.

Just yesterday I was helping another package by putting this into their
src/Makevars -- they had only the GSL bits

   PKG_CPPFLAGS=-I$(LIB_GSL)/include  $(shell Rscript -e 'Rcpp:::CxxFlags()')
   PKG_LIBS=-L$(LIB_GSL)/lib -lgsl -lgslcblas  $(shell Rscript -e 'Rcpp:::LdFlags()')

This way R finds out at compile and link time where to get Rcpp headers and
the library from, including all correct Platform / Arch features.

That package was mistakenly including Rcpp instead of depending on it, once
we get this sorted out it may make another example to you to look at.

| > Are there other Rcpp libraries that I could  
| > try out to see if they have similar problems on my machine?
| 
| http://cran.r-project.org/web/packages/Rcpp/index.html  says
| 
| 	Reverse depends: 	RInside, RQuantLib

Yes, that's me eating my own dog food.  RInside only needs it for the
examples/ dir, so you only get to see the Makefile there.  RQuantLib is
similar to phylobase in that it uses an external C++ library via Rcpp.  I
think I leaned on its configure when I made my changes in phylobase svn.  Ie
configure.in has


-----------------------------------------------------------------------------
AC_DEFUN(AC_PROG_R, [AC_CHECK_PROG(R,R,yes)])
AC_PROG_R

# Next segment by Kurt
: ${R_HOME=`R RHOME`}
if test -z "${R_HOME}"; then
    AC_MSG_ERROR([Could not determine R_HOME.])   
fi
CXX=`${R_HOME}/bin/R CMD config CXX`
CXXFLAGS=`"${R_HOME}/bin/R" CMD config CXXFLAGS`

## look for Rscript, but use the one found via R_HOME to allow for multiple installations
AC_DEFUN(AC_PROG_RSCRIPT, [AC_CHECK_PROG(RSCRIPT,Rscript,yes)])
AC_PROG_RSCRIPT
#AC_MSG_CHECKING([for Rscript])
if test x"${RSCRIPT}" == x"yes" ; then
#     AC_MSG_RESULT([yes])    
     ## Rcpp compile flag providing header directory containing Rcpp.h
     rcpp_cxxflags=`${R_HOME}/bin/Rscript -e 'Rcpp:::CxxFlags()'`
     ## link flag providing libary as well as path to library, and optionally rpath
     rcpp_ldflags=`${R_HOME}/bin/Rscript -e 'Rcpp:::LdFlags()'`
     ## now use all these
     AC_SUBST([CXXFLAGS],["${CXXFLAGS} $rcpp_cxxflags"])
     AC_SUBST([LDFLAGS],["${LDFLAGS} $rcpp_ldflags"])
else
#    AC_MSG_RESULT([no])    
    echo "
  Your installation does not appear to have Rscript installed.

  Please make sure that you have a working and complete R installation.
"
    exit 1
fi
-----------------------------------------------------------------------------

and then uses 

AC_SUBST(CXXFLAGS)
AC_SUBST(LDFLAGS)
AC_OUTPUT(src/Makevars)

( Building RQuantLib munges a lot CPU because QuantLib so huge.  And you'd
need Quantlib (Debian/ Ubuntu do. So this may be easier to look at than to
try to run at your end. )


A simpler example of using Rcpp is 'earthmovdist' on R-Forge, see 
https://r-forge.r-project.org/projects/earthmovdist/

It essentially wraps just one C++ class (that computes this EMD metric).

Let me know how I can help. I always had projects like phylobase in mind when
I thought that Rcpp should be of help to people besides myself.  If I am
standing mostly in your way feel free to let me know.  Shortcomings of the
documentations would also be a good thing to know about -- I have a bit of
tunnel vision having coded with Rcpp since 2004/2005.  The rejigging of the
build and use process (ie not like RcppTemplate) was meant to make things
easier not harder.

Hope this helps,  Dirk

-- 
Three out of two people have difficulties with fractions.


More information about the Phylobase-devl mailing list