Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
568 views
in Technique[技术] by (71.8m points)

python - How to remove -pthread compiler flag from cython setup file

In linux environment, when I run the setup script for cython, I get

gcc -pthread -B /apps/.../compiler_compat -Wl,-sysroot=/ -Wsign-compare 
-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/ap......  

for my case, I want to remove the pthread option. How do I do that thru the cython setup file? I see there are options to add compiler flags but none to remove. My setup file:

from distutils.core import setup
from Cython.Build import cythonize

from distutils.extension import Extension

extensions = [Extension("foo",sources = ["foo.pyx"])]                                 

setup(ext_modules = cythonize(extensions))
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @DavidW has pointed out, for many options there is also an option which negates/overrides it and the last option on the command line "wins". So for example adding extra compile option -Os would overrule the default setting -O2 or -O3, because -Os would come after -O2 on the command line (-fwrapv/-fno-wrapv another example for such pairs).

However, -pthread has no such "partner" and the only chance to disable it, is to prevent its appearance on the command line altogether. The ways to do it are somewhat hacky, but is this hackiness not the reason we all use python?

distutils uses distutils.sysconfig to find the right compile/link flags. One possibility would be modify its functionality, so that -pthread is filtered out.

I choose get_config_vars, but there are also other options of course. The plan is simple:

  1. wrap distutils.sysconfig.get_config_vars, so that -pthread is filtered out
  2. replace distutils.sysconfig.get_config_vars with the wrapper
  3. otherwise, setup.py is unchanged

Which leads to the following setup.py:

# manipulate get_config_vars:
# 1. step: wrap functionality and filter
from distutils.sysconfig import get_config_vars as default_get_config_vars

def 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 x

def 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 dsc
dsc.get_config_vars = my_get_config_vars


# 3.step: normal setup.py

from distutils.core import setup
from Cython.Build import cythonize

from distutils.extension import Extension

extensions = [Extension("foo",sources = ["foo.pyx"])]                                 

setup(ext_modules = cythonize(extensions))

I'm not entirely sure, it is a great idea to build without -pthread and to load the resulting module in a python-interpreter which is built with -pthread - not sure it will not break in some subtle ways and work as intended.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...