如何将Python运行时嵌入运行在Windows上的R包中

2024-06-20 15:19:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我们希望创建一个R包,它包装Python运行时,并且是“无依赖关系的”(例如,R包不需要安装Python)。已经有一个包允许R调用Python(CRAN包rPython),但它要求在目标机器上安装Python。我们希望通过标准的R软件包安装机制来安装预想的软件包时,所有的依赖项都会被安装。我分叉rPython并创建了这个变体:https://github.com/brucehoff/rWithPython。这个软件包可以在Unix和Mac上运行。它下载并构建Python源代码,然后从R访问Python运行时。通过使用libpython的静态版本,它可以构建一个共享对象,该对象可以安装在另一台机器上,而不会留下任何依赖项。问题是如何让它在Windows上运行。在windows上,R包是使用“R工具”(https://cran.r-project.org/bin/windows/Rtools/)构建的,它使用cygwin/mingw堆栈。尝试在Unix上进行配置,但失败。然后我尝试使用visualstudio链接我在Windows框上构建的静态libpython。Python非常有用,它提供了更改MVS构建以创建静态库的说明: PCB生成\自述文件.txt在某种程度上说:

The solution has no configuration for static libraries. However it is easy to build a static library instead of a DLL. You simply have to set the "Configuration Type" to "Static Library (.lib)" and alter the preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may also have to change the "Runtime Library" from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)".

这很好,我得到了一个python的静态库。但是,当我试图在cygwin/rtools下链接库时,链接器会给出一个错误:

gcc -m32 -I"C:/bin/R/include" -DNDEBUG -I"d:/RCompile/CRANpkg/extralibs64/local/include" -I"C:/Python35/Include" -I"C:/Python35/PC" -O3 -Wall -std=gnu99 -mtune=core2 -c pycall.c -o pycall.o gcc -m32 -shared -s -static-libgcc -o rWithPython.dll tmp.def pycall.o -LC:/Python35/PCbuild/win32 -lpython35 -Ld:/RCompile/CRANpkg/extralibs64/local/lib/i386 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/bin/R/bin/i386 -lR c:/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: C:/Python35/PCbuild/win32/libpython35.a(C:/hgpy/cpython/PCbuild/obj//win32_Release/pythoncore/getbuildinfo.obj): Recognised but unhandled machine type (0x14c) in Import Library Format archive pycall.o:pycall.c:(.text+0x5): undefined reference to '_imp__Py_Initialize' pycall.o:pycall.c:(.text+0x1a): undefined reference to '_imp__PyRun_SimpleStringFlags' pycall.o:pycall.c:(.text+0x31): undefined reference to '_imp__Py_Finalize' pycall.o:pycall.c:(.text+0x56): undefined reference to '_imp__PyRun_SimpleStringFlags' pycall.o:pycall.c:(.text+0x8c): undefined reference to '_imp__PyImport_AddModule' pycall.o:pycall.c:(.text+0x95): undefined reference to '_imp__PyModule_GetDict' pycall.o:pycall.c:(.text+0xa8): undefined reference to '_imp__PyDict_GetItemString' pycall.o:pycall.c:(.text+0xb5): undefined reference to '_imp__PyUnicode_AsUTF8String' collect2: ld returned 1 exit status no DLL was created ERROR: compilation failed for package 'rWithPython'

从我所读到的“机器类型”0x14c是“Intel 386或更高版本,以及兼容的处理器”,即最常见/预期的机器类型。所以我猜这个错误是一个红鲱鱼,问题是编译器之间的不兼容,而不是机器之间的不兼容。在

如有任何关于如何进行的建议,我们将不胜感激!!在

----更新---
我验证了I可以构建/链接(1)在作为标准Windows Python安装的一部分的库中链接时;(2)使用msvisualstudio从源代码构建时,不以任何方式修改构建。当我按照PCbuild中的指导原则修改visualstudio构建设置以生成一个静态库(python35.lib)时,问题就被复制了\自述文件.txt. 那些指导方针有点模棱两可。我将进一步探讨,但如果有人成功地在msvs中生成了静态Python库,请让我知道!在

----另一个更新---- 我们有办法解决这个问题: https://github.com/Sage-Bionetworks/PythonEmbedInR (代码是开源的,在GPL-3许可下。)

您可以看到我们如何解决在Windows上运行的问题: https://github.com/Sage-Bionetworks/PythonEmbedInR/blob/master/configure.win

简而言之,我们不尝试从源代码编译或创建静态库,而是使用Python的“embedded zip”,并确保其库位于应用程序的搜索路径上。看起来太好了!在


Tags: totextpyhttps机器bin链接windows
1条回答
网友
1楼 · 发布于 2024-06-20 15:19:19

您还需要在应用程序代码中放入Py_NO_ENABLE_SHARED define。基本上,只要包含Python.h文件。如果不存在,则include文件假定您已链接到.dll,并相应地(错误地)执行操作

相关问题 更多 >