使用Rtools和外部库/ DLL构建64位R包

时间:2017-01-03 22:09:28

标签: r rcpp

我在使用Rcpp骨架创建的Windows上构建/安装R软件包。有一段时间我只是构建了一个32位版本,它连接了一个32位的dll。我的Makevars文件看起来像这样:

PKG_CPPFLAGS = -I"D:/projects/source/my_project"
PKG_LIBS = -L"D:/projects/source/my_project/Release" -lproject

我会跑

R CMD build Package
R CMD INSTALL --no-multiarch --no-test-load --build Package_1.0.tar.gz

在cmd提示符下,一切都会好的。现在我也需要64位版本。我让我的Makevars看起来像这样:

PKG_CPPFLAGS = -I"D:/projects/source/my_project"
PKG_LIBS = -L"D:/projects/source/my_project/Release" -lproject -lprojectx64

我的64位dll被命名为projectx64.dll。问题是当我运行命令时:

R CMD INSTALL --build Package_1.0.tar.gz

构建失败是因为在32位构建过程中,因为编译器尝试链接64位dll。有什么方法可以让它按顺序链接dll以获得适当的架构?

作为P.S.我已经阅读了大红色文字,上面写着“没有窗户!”#34;在Rcpp手册中,这只是不准确,我不知道我的问题在Linux上会有什么不同。

修改

这是INSTALL命令的输出。当32位gcc启动并尝试链接到Makevars中规定的64位dll时,它可以预测会失败。

*** arch - i386
c:/Rtools/mingw_32/bin/g++  -I"C:/R/R-3.3.1/include" -DNDEBUG -    I"D:/projects/source/my_project"   -I"C:/Users/rk/Documents/R/win-library/3.3/Rcpp/include" -I"d:/Compiler/gcc-4.9.3/local330/include"     -O2 -Wall  -mtune=core2 -c RcppExports.cpp -o RcppExports.o
c:/Rtools/mingw_32/bin/g++  -I"C:/R/R-3.3.1/include" -DNDEBUG -I"D:/projects/source/my_project"   -I"C:/Users/rk/Documents/R/win-library/3.3/Rcpp/include" -I"d:/Compiler/gcc-4.9.3/local330/include"     -O2 -Wall  -mtune=core2 -c cstyle.cpp -o cstyle.o
c:/Rtools/mingw_32/bin/g++ -shared -s -static-libgcc -o Package.dll tmp.def RcppExports.o cstyle.o -LD:/projects/source/my_project/Release -lproject -lprojectx64 -Ld:/Compiler/gcc-4.9.3/local330/lib/i386 -Ld:/Compiler/gcc-4.9.3/local330/lib -LC:/R/R-3.3.1/bin/i386 -lR
D:/projects/source/my_project/Release/projectx64.dll: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
no DLL was created
ERROR: compilation failed for package 'Package'
* removing 'C:/Users/rk/Documents/R/win-library/3.3/Package'
* restoring previous 'C:/Users/rk/Documents/R/win-library/3.3/Package'

1 个答案:

答案 0 :(得分:0)

我接受了Dirk的建议,并为每个架构构建了两个独立的包。 Makevars当然只在每个构建的相应库中链接。运行--no_multiarch标志时使用的体系结构选择取决于PATH中首先设置的R版本。通过在命令提示符下运行R --version可以看到该版本。为每个版本更改PATH

我要补充一点,您必须在Windows上添加清单才能使其正常运行。将其添加到Visual Studio项目中的stdafx.h文件中:

#if defined _M_IX86
  #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
  #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
  #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
  #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

这是因为在Window的LoadLibrary函数中存在超级酷的错误(已经存在多年而没有修复),R用于加载DLL,这些DLL将尝试在调用时调用32位Common Controls DLL您的64位DLL导致整个加载失败。