Я пытаюсь использовать Rcpp с C++ 11 на 64-битной Windows. Я следовал qaru.site/questions/1553635/... и использовал gcc 4.8.1 с R 3.1.1 и Rcpp 0.11.2.
С помощью файла C++ simpleProd.cpp
#include <vector>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int simpleProd(std::vector<int> vec) {
vec.push_back(5);
int prod = 1;
for (int &x : vec) { // loop over all values of vec
prod *= x; // access each elem., comp. product
}
return prod;
}
Я пробовал в R
library("Rcpp")
Sys.setenv("PKG_CXXFLAGS"="-std=c++11")
unlink("mypkg", recursive = TRUE)
Rcpp.package.skeleton("mypkg", cpp_files = "simpleProd.cpp",
example_code = FALSE)
install.packages("mypkg", repos = NULL, type = "source",
INSTALL_opts = "--no-multiarch")
library(mypkg)
Без проблем, но если я забегу
simpleProd(1:5)
результат
Error in .Call("mypkg_simpleProd", PACKAGE = "mypkg", vec) :
"mypkg_simpleProd" not available for .Call() for package "mypkg"
Если я просто использую
sourceCpp("simpleProd.cpp")
simpleProd(1:5)
нет проблем. Если vec.push_back(5);
удаляется или нет C++ 11, нет проблем. В Linux и Mac нет проблем, и, наконец, на 32-битной Windows (с соответствующей инструментальной цепочкой) проблем нет.
Есть идеи? Спасибо!
Изменение: уточнить: проблема возникает только в специальном случае с:
64-битная Windows + Rcpp + Package + C++ 11 + векторная операция.
Если я изменю одно из них, это сработает.
Я подозреваю, что вам нужно бежать
compileAttributes("mypkg") # or setwd() into the directory first
для создания Атрибутов.
Скелетные пакеты делают это. Если вы работаете в RStudio, он также полуавтоматичен.
Изменить. Или, чтобы быть более явным, если вы используете Rcpp.package.skeleton()
с предоставленным файлом, мы не можем запускать для вас compileAttributes()
. Какая ошибка - я посмотрю на это. Но вы можете исправить это, запустив функцию вручную.
Изменить 2: Возможно, я ошибался в отношении необходимости compileAttributes()
. Ваш пример работает для меня (используя текущие источники GitHub Rcpp). Тем не менее, мне пришлось включить компиляцию С++ 11 - что я сделал через пользовательский CXXFLAGS
в ~/.R/Makevars
. Скелетный код не указывает на необходимость использования этого плагина в поставляемом файле. Вы также можете отредактировать DESCRIPTION
или src/Makevars
вручную и добавить его вручную.
Редактировать 3: Нет проблем. В Windows вы i) должны отказаться от компилятора С++ 11, поскольку компилятор старше (что не является чем-то, над чем мы имеем контроль), и ii) я также удалил ваше ограничение на исключение нескольких арка. Затем все работает, см. Ниже. Это стандартное окно Windows 7 с текущими пакетами R и current.
R> setwd("C:/TEMP")
R> library(Rcpp)
R> Sys.setenv("PKG_CPPFLAGS"="-std=c++0x")
R> Rcpp.package.skeleton("mypkg", cpp_files = "simpleProd.cpp", example_code = FALSE)
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './mypkg/Read-and-delete-me'.
Adding Rcpp settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp
>> added useDynLib directive to NAMESPACE
>> added importFrom(Rcpp, evalCpp) directive to NAMESPACE
>> copied simpleProd.cpp to src directory
R> install.packages("mypkg", repos = NULL, type = "source")
Installing package into ‘c:/opt/R-library
(as ‘lib is unspecified)
* installing *source* package 'mypkg' ...
** libs
*** arch - i386
g++ -m32 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c RcppExports.cpp -o RcppExports.o
g++ -m32 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c simpleProd.cpp -o simpleProd.o
g++ -m32 -shared -s -static-libgcc -o mypkg.dll tmp.def RcppExports.o simpleProd.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/i386 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/opt/R-CURR~1/bin/i386 -lR
installing to c:/opt/R-library/mypkg/libs/i386
*** arch - x64
g++ -m64 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c RcppExports.cpp -o RcppExports.o
g++ -m64 -I"C:/opt/R-CURR~1/include" -DNDEBUG -std=c++0x -I"c:/opt/R-library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c simpleProd.cpp -o simpleProd.o
g++ -m64 -shared -s -static-libgcc -o mypkg.dll tmp.def RcppExports.o simpleProd.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/opt/R-CURR~1/bin/x64 -lR
installing to c:/opt/R-library/mypkg/libs/x64
** R
** preparing package for lazy loading
** help
Warning: C:/TEMP/mypkg/man/mypkg-package.Rd:30: All text must be in a section
Warning: C:/TEMP/mypkg/man/mypkg-package.Rd:31: All text must be in a section
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (mypkg)
R> library(mypkg)
R> simpleProd(1:5)
[1] 600
R>
Makevars
иMakevars.win
и просто заменил их наSys.setenv("PKG_CXXFLAGS"="-std=c++11")
чтобы упростить пример. Обратите внимание, что единственный случай, когда возникает проблема:64bit Windows + Rcpp + Package + C++11 + vector operation
.Rcpp.package.skeleton()
- не больше, не меньше. Если есть еще одна проблема, которую мне не хватает, пожалуйста, сообщите об этом в списке с воспроизводимым примером.