Configure RInside with Veins and OMNET++ on Windows

218 views Asked by At

I have been trying to configure RInside with Veins and OMNET++, but finding some issues.

After going through the discussion in Is it possible to use RInside in omnet++/Veins project to benefit from rich R features and How to set up Eclipse + StatET + Rcpp on Windows, I created a new project (shared type) in omnet++ and tried to configure RInside it. I am experiencing some errors ("undefined reference to RInside::operator[]", "undefined reference to RInside::parseEvalQ").

I know that this is a linking error. I am fairly new to C++ configurations and eclipse based IDEs so struggling to figure out what's wrong. I am attaching the screenshots of the configurations as well. I would really appreciate if someone can help.

Errors Configurations enter image description here enter image description here

Update (after successfully building RInside and making sure that the tool chain is right)

Here is the makefrag file

#
# on windows we have to link with the ws2_32 (winsock2) library as it is no longer added to the omnetpp system libraries by default (as of OMNeT++ 5.1)
# copied from INET Framework (inet-3.6.0) makefrag
#
ifeq ($(PLATFORM),win32.x86_64)
  LIBS += -lws2_32
  DEFINES += -DINET_EXPORT
  ENABLE_AUTO_IMPORT=-Wl,--enable-auto-import
  LDFLAGS := $(filter-out $(ENABLE_AUTO_IMPORT), $(LDFLAGS))

  R_HOME := $(shell R RHOME | sed -e "s|\\\\|\/|g")
  R_ARCH := --arch $(shell echo 'cat(.Platform$$r_arch)' | R --vanilla --slave)
  sources := $(wildcard *.cpp)
  programs := $(sources:.cpp=)

  ## include headers and libraries for R
  RCPPFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --cppflags)
  RLDFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --ldflags)
  RBLAS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config BLAS_LIBS)
  RLAPACK := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config LAPACK_LIBS)


  ## include headers and libraries for Rcpp interface classes
  RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave)
  RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()'  | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave)


  ## include headers and libraries for RInside embedding classes
  RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave)
  RINSIDELIBS := $(shell echo 'RInside:::LdFlags()'  | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave)

  #DEFINES += $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
  #LIBS += $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

endif
1

There are 1 answers

4
Christoph Sommer On

I gave integrating RInside and Veins (version 5 alpha 1) a quick try and can report success.

I installed RInside by running R and executing install.packages('RInside').

I then amended the following lines (mostly copied from the RInside examples GNUMakefile) to the Veins src/makefrag file:

# determine flags for RInside
R_HOME := $(shell R RHOME)
RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)
RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)
RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS := $(shell echo 'RInside:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)

# feed to opp_makemake
DEFINES += $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
LIBS += $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

After that, I could use R inside Veins. I tried this by copying code from RInside rinside_sample0.cpp to Veins BaseConnectionManager.cc as follows:

diff --git a/src/veins/base/connectionManager/BaseConnectionManager.cc b/src/veins/base/connectionManager/BaseConnectionManager.cc
index 879e90d244..8e9eba10e8 100644
--- a/src/veins/base/connectionManager/BaseConnectionManager.cc
+++ b/src/veins/base/connectionManager/BaseConnectionManager.cc
@@ -1,3 +1,5 @@
+#include <RInside.h>
+
 #include "veins/base/connectionManager/BaseConnectionManager.h"

 #include "veins/base/connectionManager/NicEntryDebug.h"
@@ -42,6 +44,12 @@ void BaseConnectionManager::initialize(int stage)
     // BaseModule::initialize(stage);

     if (stage == 0) {
+
+        // Hello R!
+        RInside R;
+        R["txt"] = "Hello, world!\n";
+        R.parseEvalQ("cat(txt)");
+
         drawMIR = hasPar("drawMaxIntfDist") ? par("drawMaxIntfDist").boolValue() : false;

         EV_TRACE << "initializing BaseConnectionManager\n";

Compiling Veins (./configure followed by make) and running the tutorial example (cd examples/veins followed by ./run -u Cmdenv) produced the desired output:

OMNeT++ Discrete Event Simulation  (C) 1992-2018 Andras Varga, OpenSim Ltd.
Version: 5.4.1, build: 180629-5e28390, edition: Academic Public License -- NOT FOR COMMERCIAL USE
See the license for distribution terms and warranty disclaimer

Setting up Cmdenv...

Loading NED files from ../../src/veins:  41
Loading NED files from .:  1
Loading NED files from /Users/sommer/src/veins/examples/veins:  1

Preparing for running configuration General, run #0...
Assigned runID=General-0-20190308-18:16:24-23603
Setting up network "RSUExampleScenario"...
Initializing...
Hello, world!

Running simulation...

(Note the Hello, world! output during initialization of the simulation.)

Building on Windows will likely mean copying lines from the RInside examples Makefile.win file instead.