我在使用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'
答案 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导致整个加载失败。