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

使用Rtools和外部库/DLL构建64位R包,r,rcpp,R,Rcpp,我正在用Rcpp框架创建的Windows上构建/安装一个R包。有一段时间,我只是在构建一个链接32位dll的32位版本。我的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-t

我正在用Rcpp框架创建的Windows上构建/安装一个R包。有一段时间,我只是在构建一个链接32位dll的32位版本。我的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位版本。我让我的Makevar看起来像这样:

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以获得合适的体系结构

作为一名副总裁,我读过Rcpp手册中的红色大文本,上面写着“没有WINDOWS!”,但这完全是不准确的,我看不出我的问题在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'

我采纳了德克的建议,为每个架构构建了两个独立的包。当然,Makevars只针对每个构建在适当的库中提供链接。运行
--no_multiarch
标志时使用的架构选择由
路径中首先设置的R版本决定。可以通过在命令提示符下运行
R--version
来查看版本。更改每个生成的
路径

我要补充的是,你必须在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

这是因为Windows的LoadLibrary函数中有一个超级酷的错误(多年来一直没有修复),R用来加载DLL,在调用64位DLL时试图调用32位通用控件DLL,导致整个加载失败。

我想你误解了。默认情况下,Windows上的每个版本都是32位和64位。请试穿一下。另外,此:
“D:/projects/source/my_project”
并不理想,因为包随后会绑定到您的计算机,因为它是绝对路径而不是相对路径。R CMD检查失败,并显示相同的消息。我知道它默认使用两种体系结构,但是如何链接适当体系结构的库文件呢?运行R CMD INSTALL会为32位构建启动32位gcc,并且在尝试链接64位库时(显然)失败。包含外部库很难。我对lproject
一无所知,但是FWIW有一次我还尝试用Rcpp包含一个C库,并且只能在32位的Windows上编译。为了获得指导,您应该查看其他一些包含外部库的Rcpp包的Makevars。和/或将您的包构建在一个子体系结构上。这与Rcpp本身无关,而是关于在Windows上构建(更高级的)包。这也是有文件记录的。说“我接受了Dirk的建议,为每个架构构建了两个独立的包。”误解了,甚至歪曲了我所说的。下面是一个(来自我是合著者的一个项目)在处理外部库时适当地检测32位和64位。