创建独立的轮子

Creating self contained wheel

我尝试为 pyRFC 创建一个独立的轮子:http://sap.github.io/PyRFC/install.html

我有所需的(闭源)库和 header 文件。

如果我将库和 headers 复制到 $VIRTUAL_ENV/lib 和 $VIRTUAL_ENV/include.

,则安装 pyRFC 有效

现在我尝试创建一个包含闭源库文件的轮子。

但是我失败了。

如果我解压缩轮子,它只包含这个:

(pypi)pypi@pypiserver:~> unzip -l packages/pyrfc-1.9.91-cp27-cp27mu-linux_x86_64.whl
Archive:  packages/pyrfc-1.9.91-cp27-cp27mu-linux_x86_64.whl
  Length      Date    Time    Name
---------  ---------- -----   ----
     5366  2018-07-23 13:38   pyrfc/_exception.py
     1045  2018-07-23 13:38   pyrfc/__init__.py
  1610216  2018-07-23 14:10   pyrfc/_pyrfc.so
     3835  2018-07-23 14:10   pyrfc-1.9.91.dist-info/DESCRIPTION.rst
      990  2018-07-23 14:10   pyrfc-1.9.91.dist-info/metadata.json
        6  2018-07-23 14:10   pyrfc-1.9.91.dist-info/top_level.txt
      105  2018-07-23 14:10   pyrfc-1.9.91.dist-info/WHEEL
     4666  2018-07-23 14:10   pyrfc-1.9.91.dist-info/METADATA
      715  2018-07-23 14:10   pyrfc-1.9.91.dist-info/RECORD
---------                     -------
  1626944                     9 files

缺少 extra_objects(见下文)。

我如何修改 pyRFC 的 setup.py 以使轮子包含来自 $VIRTUAL_ENV/lib 的库?

这是 setup.py:https://github.com/SAP/PyRFC/blob/master/setup.py

我为 setup.py

尝试了这个补丁
@@ -48,7 +49,9 @@ PYRFC_EXT = Extension(
     , libraries=LIBS
     , define_macros=MACROS
     , extra_compile_args=COMPILE_ARGS
-    , extra_link_args=LINK_ARGS
+    , extra_link_args=LINK_ARGS,
+      library_dirs=['lib'],
+      extra_objects = ['lib/libicudata.so.50', 'lib/libsapnwrfc.so', 'lib/libicui18n.so.50', 'lib/libicuuc.so.50', 'lib/libicudecnumber.so', 'lib/libsapucum.so'],
 )

如果我安装 运行 没有 libsapnwrfc.so 的库,我会收到此错误:

Traceback (most recent call last):
  File "test-pyrfc.py", line 1, in <module>
    from pyrfc import Connection
  File "/home/other/lib/python2.7/site-packages/pyrfc/__init__.py", line 22, in <module>
    from pyrfc._pyrfc import get_nwrfclib_version, Connection, TypeDescription, FunctionDescription, Server
ImportError: libsapnwrfc.so: cannot open shared object file: No such file or directory

如果我跟踪打开的调用,我发现它只查看 root-level 库。该库未在 virtualenv 中搜索(/home/other):

strace python test-pyrfc.py 2>&1 | grep libsapnwrfc.so
open("/lib64/tls/x86_64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/tls/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/x86_64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/tls/x86_64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/tls/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/x86_64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/libsapnwrfc.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(2, "libsapnwrfc.so: cannot open shar"..., 73libsapnwrfc.so: cannot open shared object file: No such file or directory) = 73

我想通过 wheel 安装 "libsapnwrfc.so" 到 virtualenv 中,因为这使我能够拥有多个独立的环境。我可以通过 RPM 或 config-management 安装它,但我想避免它。

extra_objects 仅在链接扩展库时使用,未捆绑在轮子中。 From the docs:

extra_objects: list of extra files to link with (eg. object files not implied by ‘sources’, static library that must be explicitly specified, binary resource files, etc.)

要将库捆绑到 wheel 中,请将 auditwheel 用于 Linux wheel,或将 delocate 用于 MacOS wheel。 SO 已经有一个很好的问题:,它涵盖了使用 auditwheeldelocate 的整个车轮修复过程。在这里,我只总结必要的命令。这两种工具的过程非常相似:

$ pip install auditwheel  # you may also need to install patchelf
$ python setup.py bdist_wheel
$ auditwheel show dist/*_linux_x86_64.whl  # will show the libs to be bundled
$ auditwheel repair dist/*_linux_x86_64.whl

这将创建一个新目录 dist/wheelhouse,其中包含带有捆绑库的新轮子。