Я работаю над проектом Python с файлом setup.py, который имеет что-то вроде этого1:
setup(
cmdclass = {"build_ext": my_build_ext},
ext_modules=[
Extension("A", ["a.c", "common.c"]),
Extension("B", ["b.c", "common.c"])
]
)
У меня возникла проблема при параллельной сборке модулей: кажется, что один модуль пытается прочитать common.o
/common.obj
, а другой его компилирует, и это терпит неудачу. Есть ли какой-нибудь способ заставить setuptools компилировать файлы C для каждого модуля в свои собственные каталоги сборки, чтобы они не перезаписывали друг друга?
Я нашел потенциальное решение, переопределив build_extension()
в пользовательском классе build_ext
:
import copy, os
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
class my_build_ext(build_ext):
def build_extension(self, ext):
# Append the extension name to the temp build directory
# so that each module builds to its own directory.
# We need to make a (shallow) copy of 'self' here
# so that we don't overwrite this value when running in parallel.
self_copy = copy.copy(self)
self_copy.build_temp = os.path.join(self.build_temp, ext.name)
build_ext.build_extension(self_copy, ext)
setup(
cmdclass = {"build_ext": my_build_ext},
ext_modules=[
Extension("A", ["a.c", "common.c"]),
Extension("B", ["b.c", "common.c"])
]
)
Мне также рассказали о (в настоящее время недокументированном) параметре libraries
для setup()
:
from setuptools import Extension, setup
setup(
libraries=[
("common", {"sources": ["common.c"]}),
],
ext_modules=[
Extension("A", sources=["a.c"], libraries=["common"]),
Extension("B", sources=["b.c"], libraries=["common"]),
],
)
Оба решения сработали для меня, но немного по-разному. Первое решение перекомпилирует код для каждого модуля, что позволяет вам указать разные параметры для каждого модуля (например, разные defs
). Второе решение нужно скомпилировать в код только один раз, и оно будет повторно использовать его для каждого модуля.
Я думаю, что это совершенно правильный способ справиться с этим, поскольку корень сборки не отображается.
extra_compile_args
. Или перестать строить параллельно.