1

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
user8561039
  • 115
  • 10
  • 1
    My recommendation is to start trying to build (some of) the supplied examples to validate your local toolchain. If that works, try 'porting' to Eclipse, CMake, ... At some point in the past the contributed CMakefiles worked but I don;t if a) they every worked on Windows or b) if they are current. I use the standard R tools... – Dirk Eddelbuettel Mar 07 '19 at 22:44
  • 1
    OMNeT++ simulations are traditionally built via opp_makemake, which creates GNU Makefiles. An easy way to tweak these Makefiles to use custom include paths and libraries is the use of a makefrag file, which contains a fragment of code that will be inserted into the created Makefile. Try building Veins, check the created Makefile in src/, compare this with the makefrag file in src/ and try to take code from RInside's sample Makefiles, e.g., https://github.com/eddelbuettel/rinside/blob/6699d52/inst/examples/standard/GNUmakefile – Christoph Sommer Mar 08 '19 at 00:12
  • Thanks Dirk and Christoph! Really appreciate your suggestions. I will post my findings around these. – user8561039 Mar 08 '19 at 06:20

1 Answers1

1

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.

Christoph Sommer
  • 6,893
  • 1
  • 17
  • 35
  • Thanks a lot! I edited makefrag file and built the project, but ended up having "make[1]: /bin/R: Command not found". I ran 'R RHOME' command on the command line and got the path correctly as 'C:\R-3.5.2\'. Still could not figure out why.. – user8561039 Mar 11 '19 at 05:18
  • My bad - I forgot to mention that I did this by copying from the RInside examples GNUMakefile (the file used for building the examples on macOS, Linux, etc) - not from its Makefile.win (the file used for building on Windows) – Christoph Sommer Mar 11 '19 at 06:30
  • All good! I built RInside examples as Dirk has mentioned and it worked fine. Then as you did I copied the relevant content from Makefile.win to makefrag file in Veins and built. I am still getting "/bin/sh: R: command not found" and "make[1]: /bin/R: Command not found". I think the line "R_HOME := $(shell R RHOME | sed -e "s|\\\\|\/|g")" doesn't pick up the path correctly. Any thoughts on this and how to correct it? – user8561039 Mar 12 '19 at 23:04
  • Are you able to edit your question to amend it with what you have in your makefrag so far? – Christoph Sommer Mar 12 '19 at 23:54