[R] Compiling C++ package source: linking problem?

Prof Brian Ripley ripley at stats.ox.ac.uk
Thu Jun 17 01:29:36 CEST 2004

On Thu, 17 Jun 2004, Alet Roux wrote:

> Dear Prof Ripley
> libR.a seems to be created fine, as far as this layman can tell. Executing 
> make libR.a
> in C:\R\rw1090\src\gnuwin32 produces the single line
> dlltools -k --as as  --dllname R.dll --def R.exp --output-lib libR.a
> and the resulting file libR.a is 1583 Kb big. I just tried copying my
> c++ file into C:\R\rw1090\src\gnuwin32, and executing R CMD SHLIB as
> below. It seems to work (so libR.a must be fine), but is not an ideal
> solution, for obvious reasons.

You should not be working in C:\R\rw1090\src\gnuwin32, at least not in a 
system compiled there.

You can find out via nm -pg libR.a | grep Rf_allocVector

> Now, compiling my second example below (it does in fact have an extern
> "C"-wrapper), I typed
> R CMD SHLIB montecarlo.cpp
> in the appropriate directory, and obtained (slight alterations in order to make
> the text fit).
> making montecarlo.d from montecarlo.cpp
> g++ --shared -s -o montecarlo.dll montecarlo.def montecarlo.a
>     -LC:/R/rw1090/src/gnuwin32 -lg2c -lR
> montecarlo.a(montecarlo.o.b)(.text+0x28):montecarlo.cpp: undefined reference 
>     to 'Rf_allocVector(unsigned, int)'
> montecarlo.a(montecarlo.o.b)(.text+0x33):montecarlo.cpp: undefined reference 
>     to 'Rf_protect(SEXPREC*)'
> montecarlo.a(montecarlo.o.b)(.text+0x3f):montecarlo.cpp: undefined reference 
>     to 'Rf_unprotect(int)'
> make: ** [montecarlo.dll] Error 1
> To me, it seems that libR.a is simply ignored (I had the same impression with
> Rdll.lib under MSVC++ 6.0; the linker found and read the file, but gave similar
> errors as above).

You appear to have C++ entry points, not C ones (note that arg sequences).
Again, look at the actual compiled code with nm to see what the symbol 
names are.  Using your code below

[c:/R/rw1091/src/gnuwin32/tmp]% nm -g montecarlo.o
         U __Z10Rf_protectP7SEXPREC
         U __Z12Rf_unprotecti
         U __Z14Rf_allocVectorji
00000000 T __Z8whateverP7SEXPREC

but if I use the correct inclusion of C headers

extern "C" {
#include <R.h>
#include <Rdefines.h>

SEXP whatever (SEXP model)
   SEXP anotherModel;
   PROTECT(anotherModel = NEW_NUMERIC(4));
   return anotherModel;

it works.  So the problem seems to be your using C headers as if they 
were C++ headers, and nothing to do with libR.a.

Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

More information about the R-help mailing list