Инструменты настройки Python с несколькими модулями расширения и параллельным созданием общего исходного кода на языке C

Я работаю над проектом 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 для каждого модуля в свои собственные каталоги сборки, чтобы они не перезаписывали друг друга?

 

  1. Реальный проект более сложен и содержит больше модулей и исходных файлов.
setuptools.pypa.io/en/latest/userguide/… Нет. Вы можете попробовать что-нибудь сделать с extra_compile_args. Или перестать строить параллельно.
phd 24.04.2024 23:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
112
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел потенциальное решение, переопределив 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). Второе решение нужно скомпилировать в код только один раз, и оно будет повторно использовать его для каждого модуля.

Я думаю, что это совершенно правильный способ справиться с этим, поскольку корень сборки не отображается.

rasjani 25.04.2024 08:43

Другие вопросы по теме