eddelbuettel/rinside

problem undefined reference to `RInside::operator[]

Carole-ippon opened this issue · 8 comments

Hi,

I am trying to compile a C++ application using RCpp and RInside on a R3.1.2 (windows 7).

This application is building correctly on another computer (windows 10), but I need to transfer it on a more reliable one.

During linking, I encounter an undefined reference to 'RInside::operator[]'
It behaves like there is no reference to [] in the RInside dlls.

Here is the build command used linking :
g++ -LG:/Dev/DevEnvCarole/workspace/Exec/R-3.1.2/library/Rcpp/libs/x64 -LG:/Dev/DevEnvCarole/workspace/Exec/R-3.1.2/library/RInside/libs/x64 -LG:/Dev/DevEnvCarole/workspace/Exec/R-3.1.2/bin/x64 -m64 -o Gatw-Encryption.exe "src\Gat.o" -lRcpp -lpsapi -lRInside -lR

and one of the multiple undefined references :
src\Gat.o:Gat.cpp:(.text.startup+0x4af): undefined reference to `RInside::operator[](std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)'

I tried linking towards -lRInside, towards .../libs/x64/RInside.dll, any combinaison of the two, even using libRInside.a (which was a major setback), to no avail.
I spent too many hours on this problem to be able to list all the things I tried, but I am running low on hypothesis and possible corrections.

Do you have an idea that could help me to solve this problem, please?

Thank you very much.

Can you

Obviously, we have counter examples as the unit tests in R run on all platforms.

Ok thanks; Here I tied to answer your requests. Thanks to have a look.

• A minimally reproducible example :
My file Example.cpp contains:

#define WIN32
#include <iostream>
#include <string>

#include "Rcpp.h"
#include "RInside.h"

using namespace Rcpp;

int main ( int argc, char *argv [] )
{
    std::string RCommande;

    std::string input_filepath = argv [1];
    std::string nbfirstcolid = argv [2];
    std::string output_filepath = argv [3];

    RInside R (argc, argv);

    R ["input_filepath"] = input_filepath;
    R ["nbfirstcolid"] = nbfirstcolid;
    R ["output_filepath"] = output_filepath;

    RCommande = "print(paste(input_filepath, nbfirstcolid , output_filepath))";
    R.parseEval (RCommande);

    std::cout << "End " << std::endl;
    exit (0);
}

• How I should call it (ok on windows 10):
In cmd.exe I run:
Example.exe blabla.txt 2 blabla2.txt

• What R should run (ok on windows 10):
[1] blabla.txt 2 blabla2.txt

• Log Error during compiling Example.cpp (on windows 7 only):

19:31:25 **** Incremental Build of configuration Release for project mini_example ****
Info: Internal Builder is used for build
g++ "-IE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\include" "-IE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\library\\RInside\\include" "-IE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\library\\Rcpp\\include" -O3 -Wall -c -fmessage-length=0 -m64 -std=c++11 -o "src\\Example.o" "..\\src\\Example.cpp" 
In file included from E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/stats.h:38:0,
                 from E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp.h:69,
                 from ..\src\Example.cpp:8:
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/weibull.h: In function 'double Rcpp::stats::pweibull_1(double, double, int, int)':
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/weibull.h:57:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
     if (x <= 0)
     ^~
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/weibull.h:59:2: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'
  x = -::pow(x , shape);
  ^
In file included from E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/stats.h:41:0,
                 from E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp.h:69,
                 from ..\src\Example.cpp:8:
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/exp.h: In function 'double Rcpp::stats::d_exp_0(double, int)':
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/exp.h:37:6: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
      if (x < 0.)
      ^~
E:\IPPON\DEV\Eclipse\workspaceCDE\mini_example\Release\R-3.1.2\library\Rcpp\include/Rcpp/stats/exp.h:39:3: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'
   return give_log ? (-x) : ::exp(-x);
   ^~~~~~
g++ "-LE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\library\\Rcpp\\libs\\x64" "-LE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\library\\RInside\\libs\\x64" "-LE:\\IPPON\\DEV\\Eclipse\\workspaceCDE\\mini_example\\Release\\R-3.1.2\\bin\\x64" -m64 -o mini_example.exe "src\\Example.o" -lRcpp -lRInside -lR -lpsapi 
src\Example.o:Example.cpp:(.text.startup+0x132): undefined reference to `RInside::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
src\Example.o:Example.cpp:(.text.startup+0x196): undefined reference to `RInside::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
src\Example.o:Example.cpp:(.text.startup+0x1fa): undefined reference to `RInside::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
src\Example.o:Example.cpp:(.text.startup+0x250): undefined reference to `RInside::parseEval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2.exe: error: ld returned 1 exit status

19:31:30 Build Finished (took 4s.406ms)

Fixed half your formatting, can you work on the rest? Click on the 'pen' icon; bottom left has 'Styling with Markdown is supported'. There is help.

In short, you say you have code, you show a failed build and then say it didn't run. It needs to build first.

That is the problem.

This example build smoothly on a computer which will not be available anymore in the near future, but not on the three other I tried it on.

And despite all my effort and those from 2 other persons, we cannot find where the problem is coming.

This attempt is coming from the tranfered whole Eclipse environment, R folder with all its libraries, in which the paths and everything had been adapted.

In all the examples, the building is made using a Makefile, but I am not able to make them run either on Eclipse.

Every RInside library that I use, there is a missing reference to operator[], but on some, there are more missing references...

Now we are getting closer. You have a self-inflicted wound caused by Eclipse.

All examples works as is if you just use make, which may require pointing to the (GNU)makefile so either make of, more explicitly, make -f GNUmakefile (in, say, inst/examples/standard/) will work.

And we always recommended that you build your build setup of ours. As ours work.

Yeah, I understand that, but the project in which this is embeded is already built on Eclipse, and working fine on another computer that way.

The problem is to discover why these building steps are not transferable.

One of the aspect of this transfer is to have as much as possible a portable build environment, to prevent interferences from all the different versions of R installed on the different computer that can be meant to build that program.

In the end, I suspect the build commands should not be much different between a customized makefile and an Eclipse managed build...

I tried to adapt as possible the Makefile.win from the standard example, to use the paths of MinGW64, of R, of RTools, but even so, I get errors stating that cygwin can't use the paths provided, so it looks like a dead end...

I am sorry but I provide working Makefiles. You are free to use them, understand them and/or translate them to the (CMake ?) structure used by Eclipse. Also note the repository and package does contain older contributed CMake files in a subdirectory.

But Eclipse is outside of our spec.

On my Linux, make called in examples/standard builds all files with a command like

g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include \
        -I/usr/local/lib/R/site-library/RInside/include -g -O3 \
       -Wall -pipe -Wno-unused -march=native -Wall  \
       rinside_sample1.cpp  -Wl,--export-dynamic -fopenmp -Wl,-Bsymbolic-functions 
       -Wl,-z,relro -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 \
      -lz -lrt -ldl -lm -licuuc -licui18n -lblas -llapack \
      -L/usr/local/lib/R/site-library/RInside/lib -lRInside \
      -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib \
     -o rinside_sample1

where I indented by hand. Many of these values are computed with the Makefile, and to replicate this for Exclipse you need to understand how this work. But you could just this on your side and copy the resulting into your files used by Eclipse.