python - 在构建 python/cython 扩展时指定替代链接器?

标签 python c++ linker cython

为了加快开发过程,我一直在尝试在编译一些 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? ;但是,如前所述,它并没有解决我的问题。

最佳答案

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

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

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

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

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

  • 选项 2 可能最容易调整以适用于任何系统:
  • 检测是否 ld.lld是出席,如果是:
  • 创建一个带有符号链接(symbolic link)的临时文件夹(称为 ld )
  • 将此临时文件夹添加为 -B -extra_link_args 的选项
  • 检测分发是否已经使用-B选项,操作命令行(如 here 所述)以确保临时文件夹的优先级。
  • 关于python - 在构建 python/cython 扩展时指定替代链接器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60512552/

    相关文章:

    c++ - libuvc 和 opencv2 的 G++ undefined reference

    c++ - MSVC 名称修改

    visual-c++ - 为什么在 Visual Studio 中编译 C++ 项目时出现 fatal error "LNK1104: cannot open file ' C :\Program. obj'"?

    python - 在运行多面测试之前,如何使用 python 正确执行全局固定装置?

    python - 皮蒙戈 : Convert MongoDB query (cursor) to class instance with defined variable name

    c++ - 非菱形继承(钻石问题)树中的虚拟继承 - 内存和行为副作用

    c++ - 返回真还是返回假?魔法

    python - 为什么带有屏蔽数组的 pcolor 仍然填充连接到屏蔽点的四边形,以及如何阻止这种情况?

    python - django自动创建的sqlite数据库在哪里?

    c++ - UINT_MAX 宏的定义