Getting RInside example to work with extra linker

2019-08-09 04:53发布

问题:

I got the RInside example to run and work but I had to manually add the linker option: "-F/Library/Frameworks/R.framework/.. -framework R" at the end for g++ (on Mac Snow Leopard 10.6.8 with Xcode 3.x). It works, but I don't know why. Can anyone say what these options actually do ? I could not find it on this list: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

Here is the original code:

#include <RInside.h>                    // for the embedded R via RInside

int main(int argc, char *argv[]) 
{
 RInside R(argc, argv);              // create an embedded R instance 
 R["txt"] = "Hello, world!\n";  // assign a char* (string) to 'txt'
 R.parseEvalQ("cat(txt)");           // eval the init string, ignoring any returns
 exit(0);
}

Here is the linker call as I saw it in NetBeans:

g++ -o dist/Debug/GNU-MacOSX/callingrproject build/Debug/GNU-MacOSX/main.o - L/Library/Frameworks/R.framework/Resources/lib -L/Library/Frameworks/R.framework/Resources/library/Rcpp/lib -L/Library/Frameworks/R.framework/Resources/library/RInside/lib -L/Library/Frameworks/R.framework/Libraries -L/Library/Frameworks/R.framework/Resources/lib -L/Library/Frameworks/R.framework/Resources/library -L/Library/Frameworks/R.framework/Resources/modules -lRcpp -lRInside -lRlapack -lRblas -F/Library/Frameworks/R.framework/.. -framework R

The last part is what I had to add manually. Without that I got these two linkage errors:

Undefined symbols:
 "_Rf_mkString", referenced from:
   Rcpp::wrap(char const*)in main.o
 "_R_NilValue", referenced from:
   Rcpp::wrap(char const*)in main.o

回答1:

Frameworks are, more or less, a Mac way of packaging applications. These applications might contain code + headers + libraries we want to use. The line

-F/Library/Frameworks/R.framework/..

says, "look in the folder /Library/Frameworks for any frameworks that get specified", and

-framework R

says, "look for the folder R.framework in the set of 'frameworks' directories".

Note that the -framework R argument is actually handled by ld, not gcc/clang, so you would find more information in man ld. The -F argument, on the other hand, is handled by gcc/clang. Together, they allow your compiler and linker to find headers and libraries needed.

In particular, on Mac, they are located (by default) as /Library/Frameworks/R.framework/Headers and /Library/Frameworks/R.framework/Libraries -- these are the directories scoured by setting the appropriate framework flags.

More information is available here for the -F argument and for the -framework argument.



回答2:

RInside requires R as it embeds R.

This is why you get linker errors about basic R identifiers missing when it is not present.

Now I do not know why these link instructions where not present. Our Makefile in the directory examples/standard (from which this first example comes) uses

LDLIBS :=   $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

and all those variables are set in the Makefile itself. This one is

RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags)

and that should have included R and its library.