Настройка RInside с помощью Veins и OMNET++ в Windows

Я пытался настроить RInside с помощью Veins и OMNET++, но обнаружил некоторые проблемы.

После обсуждения в Можно ли использовать RInside в проекте omnet++/Veins, чтобы воспользоваться богатыми функциями R и Как настроить Eclipse + StatET + Rcpp в Windows, я создал новый проект (общий тип) в omnet++ и попытался настроить RInside. У меня возникают некоторые ошибки ("undefined reference to RInside::operator[]", "undefined reference to RInside::parseEvalQ").

Я знаю, что это ошибка ссылки. Я новичок в конфигурациях С++ и IDE на основе eclipse, поэтому изо всех сил пытаюсь понять, что не так. Прикрепляю скриншоты настроек. Я был бы очень признателен, если кто-то может помочь.

Ошибки Конфигурации введите здесь описание изображения введите здесь описание изображения

Обновление (после успешной сборки RInside и проверки правильности набора инструментов)

Вот файл makefrag

#
# 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

person user8561039    schedule 07.03.2019    source источник
comment
Я рекомендую начать пытаться собрать (некоторые из) предоставленных примеров для проверки вашей локальной цепочки инструментов. Если это сработает, попробуйте «портировать» на Eclipse, CMake, ... В какой-то момент в прошлом добавленные файлы CMake работали, но я не знаю, если а) все они работали в Windows или б) если они актуальны. Я использую стандартные инструменты R...   -  person Dirk Eddelbuettel    schedule 08.03.2019
comment
Моделирование OMNeT++ традиционно создается с помощью opp_makemake, который создает файлы GNU Makefile. Простой способ настроить эти файлы Makefile для использования настраиваемых путей включения и библиотек — использовать файл makefrag, содержащий фрагмент кода, который будет вставлен в созданный файл Makefile. Попробуйте собрать Veins, проверьте созданный Makefile в src/, сравните его с файлом makefrag в src/ и попробуйте взять код из образцов Makefile RInside, например, github.com/eddelbuettel/rinside/blob/6699d52/inst/examples/   -  person Christoph Sommer    schedule 08.03.2019
comment
Спасибо Дирк и Кристоф! Очень ценю ваши предложения. Я опубликую свои выводы вокруг них.   -  person user8561039    schedule 08.03.2019


Ответы (1)


Я попробовал интегрировать RInside и Veins (версия 5 альфа 1) и могу сообщить об успехе.

Я установил RInside, запустив R и выполнив install.packages('RInside').

Затем я изменил следующие строки (в основном скопированные из GNUMakefile примеров RInside) в файл Veins src/makefrag:

# 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)

После этого я мог использовать R внутри Veins. Я попробовал это, скопировав код из RInside rinside_sample0.cpp в Veins BaseConnectionManager.cc следующим образом:

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";

Компиляция Veins (./configure, затем make) и запуск обучающего примера (cd examples/veins, затем ./run -u Cmdenv) дали желаемый результат:

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...

(Обратите внимание на вывод Hello, world! во время инициализации моделирования.)

Сборка на базе Windows, скорее всего, будет означать копирование строк из файла Makefile.win примеров RInside.

person Christoph Sommer    schedule 08.03.2019
comment
Большое спасибо! Я отредактировал файл makefrag и собрал проект, но в итоге получил make[1]: /bin/R: Команда не найдена. Я запустил команду «R RHOME» в командной строке и правильно указал путь как «C:\R-3.5.2\». До сих пор не мог понять, почему.. - person user8561039; 11.03.2019
comment
Мое плохое — я забыл упомянуть, что сделал это, скопировав из примеров RInside GNUMakefile (файл, используемый для сборки примеров в macOS, Linux и т. д.), а не из его Makefile.win (файл, используемый для сборки в Windows) - person Christoph Sommer; 11.03.2019
comment
Все хорошо! Я создал примеры RInside, как упоминал Дирк, и все работало нормально. Затем, как и вы, я скопировал соответствующий контент из Makefile.win в файл makefrag в Veins и построил. Я все еще получаю /bin/sh: R: команда не найдена и make[1]: /bin/R: команда не найдена. Я думаю, что строка R_HOME := $(shell R RHOME | sed -e s|\\\\|\/|g) неправильно определяет путь. Есть мысли по этому поводу и как исправить? - person user8561039; 13.03.2019
comment
Можете ли вы отредактировать свой вопрос, чтобы дополнить его тем, что у вас уже есть в makefrag? - person Christoph Sommer; 13.03.2019