【问题标题】:Specify alternative linker when building python / cython extensions?在构建 python / cython 扩展时指定替代链接器?
【发布时间】:2020-03-03 17:25:15
【问题描述】:

为了加快开发过程,我一直在尝试在编译一些 cython 扩展时尝试使用“gold”链接器或多线程“lld”链接器来代替 GNU 链接器。在我的 setup.py 中,我尝试了以下内容:

lld_linker = shutil.which('ld.lld')
if lld_linker:
    print("Using LLD Linker in place of GNU LD")
    os.environ['LDSHARED'] = lld_linker    

但是,这会导致链接过程失败,并出现大量“/usr/bin/ld: ..... undefined reference to .....”错误。 (构建工作正常,无需添加此 LDSHARED envvar)。无论是使用这个内部 os.environ,还是在调用 setup.py 之前导出 envvar,失败行为都是相同的。我有一种预感,也许 Cython 分配编译作业的多处理方法并没有将环境变量保留在任何地方,从而导致了这种链接器的混合?

如何正确指定链接器,以便设置与 GNU ld 链接器相同?

这里有一个相关的问题: How do I specify the linker when building python extensions? ;但是,如前所述,它并没有解决我的问题。

【问题讨论】:

    标签: python c++ linker cython


    【解决方案1】:

    通常distutils/setuptools 不直接使用链接器,而是调用像gcc 用于c 扩展或g++ 用于c++ 扩展的前端。

    这些前端收集所有必要的信息——比如应该将哪些库传递给链接器,例如。 libstdc++ 用于 c++ 扩展, - 并使用正确的命令行选项调用链接器。在将-v-option 传递给g++-frontend 的gcc- 时可以看到它,例如通过setup.py 中的extra_link_args

    所以如果你强制distutuls/setuptools.py直接使用ld,你还应该在extra_link_args中提供前端收集的所有选项,否则一些库会丢失,编译会失败,因为你见。

    setup.py 选择另一个链接器非常困难,但是有一些便宜的选择可以在本地进行:

    1. 默认链接器(例如/usr/bin/ld)只是一个符号链接,让它指向您选择的链接器。
    2. 通过extra_link_args 传递-B-option,即-B/path/to/folder/with/my/linker。微妙的细节是:1)链接器应该被称为ld(如果需要,创建一个符号链接)2)一些发行版(例如Anaconda)已经提供了一个-B-option,它优先于通过extra_link_args传递的路径.在这种情况下,一种可能的解决方案是修改发出的命令行,类似于SO-post 中所述。
    3. 直接通过LDSHARED 环境变量设置链接器,并在extra_link_args 中提供所有需要的选项。

    选项 2 可能最容易调整以适用于任何系统:

    1. 检测ld.lld是否存在,如果存在:
    2. 创建一个带有符号链接的临时文件夹(称为ld
    3. 将此临时文件夹作为-B-options 添加到extra_link_args
    4. 检测分发是否已经使用-B 选项,操作命令行(如here 所述)以确保临时文件夹的优先级。

    【讨论】:

      猜你喜欢
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 2016-04-11
      • 1970-01-01
      • 2016-11-04
      • 1970-01-01
      相关资源
      最近更新 更多