正如@DavidW指出的那样,对于许多选项,还有一个选项可以对其进行否定/覆盖,而命令行上的最后一个选项“
wins”。因此,例如添加额外的编译选项
-Os将否决默认设置
-O2或
-O3,因为
-Os它将
-O2在命令行之后出现(
-fwrapv/
-fno-wrapv这样的对的另一个示例)。
但是,
-pthread没有这样的“伙伴”,并且禁用它的唯一机会是完全防止其出现在命令行中。做到这一点的方法有些怪异,但这不是我们所有人都使用python的原因吗?
distutils用于
distutils.sysconfig查找正确的编译/链接标志。一种可能性是修改其功能,以便将
-pthread其过滤掉。
我选择
get_config_vars,但是当然还有其他选择。该计划很简单:
- wrap
distutils.sysconfig.get_config_vars
,以便将-pthread
其过滤掉 distutils.sysconfig.get_config_vars
用包装纸代替- 否则,
setup.py
保持不变
这导致以下结果
setup.py:
# manipulate get_config_vars:# 1. step: wrap functionality and filterfrom distutils.sysconfig import get_config_vars as default_get_config_varsdef remove_pthread(x): if type(x) is str: # x.replace(" -pthread ") would be probably enough... # but we want to make sure we make it right for every input if x=="-pthread": return "" if x.startswith("-pthread "): return remove_pthread(x[len("-pthread "):]) if x.endswith(" -pthread"): return remove_pthread(x[:-len(" -pthread")]) return x.replace(" -pthread ", " ") return xdef my_get_config_vars(*args): result = default_get_config_vars(*args) # sometimes result is a list and sometimes a dict: if type(result) is list: return [remove_pthread(x) for x in result] elif type(result) is dict: return {k : remove_pthread(x) for k,x in result.items()} else: raise Exception("cannot handle type"+type(result))# 2.step: replace import distutils.sysconfig as dscdsc.get_config_vars = my_get_config_vars# 3.step: normal setup.pyfrom distutils.core import setupfrom Cython.Build import cythonizefrom distutils.extension import Extensionextensions = [Extension("foo",sources = ["foo.pyx"])]setup(ext_modules = cythonize(extensions))我不确定,
-pthread在不使用python解释器构建并加载结果模块的情况下,这是一个好主意
-pthread-不确定它不会以某些细微的方式破坏并按预期工作。



