Disable link step of distutils Extension

142 Views Asked by At

Is it possible to disable the creation of shared objects with distutils.core.Extension? I want to stop the compiler before linking (i.e. g++ -c ...).

I am swigging a native file, which creates an object file and a python file. I have other code to compile that I'll later link with this object file, so I don't want this to proceed after the .o compilation.

$ python setup.py build
running build
....
building 'foo' extension
swigging src/foobar.i to src/foobar.cpp
swig -python -c++ -o src/foobar.cpp src/foobar.i

I want to stop here, but it continues.

creating build/temp.linux-x86_64-2.7
creating build/temp.linux-x86_64-2.7/src
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -Isrc -I/usr/include/python2.7 -c src/foobar.cpp -o build/temp.linux-x86_64-2.7/src/foobar.o
g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-x86_64-2.7/src/foobar.o -o build/lib.linux-x86_64-2.7/foobar.so

Do I need to use the CCompiler class directly? Or is there a way to wrangle the Extension class?

23     ext_modules=[
24         # Swig
25         Extension(
26             name='foobar',
27             sources=['src/foobar.i'],
28             include_dirs=['src'],
29             swig_opts=['-c++'],
30         ),
31     ]
2

There are 2 best solutions below

0
On BEST ANSWER

It is not possible to stop the linking step without modifying the underlying ccompiler object. One could theoretically override the link_shared_object function of the underlying ccompiler to do nothing (See the build_ext source).

However, to answer the original intent behind this question, the C/C++ files can be passed to the Extension with the Swig interface file without needing to compile them independently and link later. It is not necessary to separate the swig file generation and the library compilation.

0
On

You could do something like this:

from distutils.command import build_ext

def cmd_ex(command_subclass):
    orig_ext = command_subclass.build_extension

    def build_ext(self, ext):
        sources = self.swig_sources(list(ext.sources), ext)

    command_subclass.build_extension = build_ext
    return command_subclass

@cmd_ex
class build_ext_ex(build_ext):
    pass

setup(
    name = ...,
    cmdclass = {'build_ext': build_ext_ex},
    ext_modules = ...
)

to override the default behavior of distutils command.

Setuptools – run custom code in setup.py