为加快开发速度,我一直在尝试在编译一些cython扩展时尝试使用“黄金”链接器或多线程“ 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:.....对.....的未定义引用”错误。 (无需添加此LDSHARED envvar即可正常运行)。无论使用此内部os.environ还是在调用setup.py之前导出envvar,故障行为都是相同的。我有一种预感,也许Cython的用于分配编译作业的多处理方法不会在所有地方都保持环境变量,从而导致链接器的这种混合?
如何正确指定链接器,以便设置和构建与GNU ld链接器相同?
这里有一个相关的问题: How do I specify the linker when building python extensions?;但是,如前所述,它并不能解决我的问题。
答案 0 :(得分:1)
通常,distutils
/ setuptools
不直接使用链接器,而是调用gcc
之类的前端作为c扩展,或调用g++
之类作为c ++扩展。
这些前端收集所有必要的信息-例如应将哪些库传递给链接器,例如libstdc++
(用于c ++扩展名),然后使用正确的命令行选项调用链接器。例如,通过-v
中的gcc
将g++
-选项传递给extra_link_args
前端的setup.py
-时,人们可以看到它。
因此,如果您强制distutuls
/ setuptools.py
直接使用ld
,则还应该在extra_link_args
中提供前端收集的所有选项,否则某些库将丢失如您所见,并且编译将失败。
让setup.py
选择另一个链接器是很困难的,但是有一些便宜的选择可以在本地进行:
/usr/bin/ld
)只是一个符号链接,请使其指向您选择的链接器。extra_link_args
,即-B/path/to/folder/with/my/linker
传递-B
-option。这些细微的细节是:1)应该将链接器称为ld
(如果需要,创建一个符号链接)2)一些发行版(例如Anaconda)已经提供了-B
-选项,该选项优先于通过的路径通过extra_link_args
。在这种情况下,一种可能的解决方案是像本SO-post中所述,修改发出的命令行。LDSHARED
环境变量设置链接器,并在extra_link_args
中提供所有需要的选项。选项2可能最容易调整以在任何系统上工作:
ld.lld
,如果存在:ld
)-B
选项添加到extra_link_args
-B
选项,操作命令行(例如,here所述)以确保临时文件夹的优先级。