У меня есть проект, состоящий из нескольких модулей Cython в разных папках:
clibs
File.cpp
File.hpp
module
module/folder
__init__.py
file1.pyx
file1.pxd
__init__.py
file2.pyx
В module/folder/file1.pxd
У меня есть что-то вроде этого:
cdef extern from "../../clibs/File.hpp":
cdef cppclass MyCppClass:
int _data
MyCppClass(int arg)
cdef class MyPyClass:
cdef MyCppClass* cpp_obj
а затем в module/file2.pyx
я cimport
декларации от module/folder/file1.pxd
:
from module.folder.file1 cimport MyCppClass, MyPyClass
Теперь, когда я пытаюсь построить это, Cython генерирует строку
#include "../../clibs/File.hpp"
при чтении module/folder/file1.pxd
и бросает его во вновь сгенерированный module/file2.cpp
, что, очевидно, неверный путь!
Как мне решить это? Могу ли я указать путь относительно корня проекта в моем extern
пункты?
Мое (временное) решение — создать символическую ссылку на clibs
каталог в каждой папке Python.
Чтобы это не было проблемой с контролем версий, я добавил следующее в верхнюю и нижнюю часть моего setup.py
:
# at the top:
import os
pwd = os.getcwd()
folders = [
"module",
"module/folder"]
for f in folders:
os.system("ln -s " + pwd + "/clibs " + f + "/clibs")
try:
# setup commands...
finally:
# used here so that if setup raises a compilation exception, we
# still tidy up:
for f in folders:
os.system("rm " + f + "/clibs")
заметки: вам нужно полное pwd
— если вы просто укажите имя локальной папки, это все, что хранится в символической ссылке, и вы получите ошибку ELOOP слишком много символических ссылок.
Я все еще хочу лучшее решение для этого, это просто грязный хак, и действует только тогда, когда ln -s
а также rm
здесь! Если больше ничего не будет опубликовано, я в конечном итоге отметлю это как «принятый», но это вообще не нужно.
Обновление: Другая ошибка заключается в том, что когда код находится в сетевой файловой системе (например, в общей папке в VirtualBox), вам не разрешено создавать символические ссылки на гостевой системе — очень неприятно!
Других решений пока нет …