繁体   English   中英

Cython,CMake和setup.py,子目录中的python编译两次

[英]Cython, CMake and setup.py, python in a subdirectory compiles twice

我正在尝试按照https://bloerg.net/2012/11/10/cmake-and-distutils.html的结构与Cython绑定一起构建C ++库。

问题是在make install期间,扩展名将被编译两次。 当主文件夹中只有一个主CMakeLists.txt (调整了路径)时,不会发生这种双重编译。 详细信息如下:

我的项目结构是

.
├── CMakeLists.txt
├── python
│   ├── CMakeLists.txt
│   ├── a_py.pxd
│   ├── a_py.pyx
│   └── setup.py.in
└── src
    ├── A.cpp
    └── A.h

顶级CMakeLists.txt仅包含add_subdirectory(python)

python/CMakeLists.txt

IF(NOT ${PYTHON})
    find_program(PYTHON "python")
ENDIF()

set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
set(SETUP_PY    "${CMAKE_CURRENT_BINARY_DIR}/setup.py")

set(PY_OUTPUT      "${CMAKE_CURRENT_BINARY_DIR}/build/pytimestamp")

configure_file(
    ${SETUP_PY_IN}
    ${SETUP_PY}
)

add_custom_command(OUTPUT "${PY_OUTPUT}"
                   COMMAND ${PYTHON} ${SETUP_PY} build_ext
                   COMMAND ${CMAKE_COMMAND} -E touch ${PY_OUTPUT}
               )

add_custom_target(a_py ALL DEPENDS ${PY_OUTPUT})

install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)")

setup.py是:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
    Extension(
    name="a",
    sources=["${CMAKE_CURRENT_SOURCE_DIR}/a_py.pyx", "${CMAKE_CURRENT_SOURCE_DIR}/../src/A.cpp"],
    include_dirs = ['${CMAKE_CURRENT_SOURCE_DIR}/../src'],
    language="c++",
    ),
]
setup(
    name = 'a',
    version='${PROJECT_VERSION}',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules,
    package_dir={ 'a': '${CMAKE_CURRENT_SOURCE_DIR}' },
)

在两种情况下( CMakeFile.txt在根或python子文件夹),首先, build_ext步骤运行:

 Scanning dependencies of target a_py [100%] Generating build/pytimestamp running build_ext 

并编译生成的a_py.cppA.cpp并链接库。 在安装步骤中, 仅当CMakeFile.txt位于python子文件夹中时, CMakeFile.txt再次运行编译。

这是在安装过程中发生的情况:

 running build_ext skipping '/Users/xxx/tmp/ctest/t08/python/a_py.cpp' Cython extension (up-to-date) building 'a' extension creating build 

请注意,不会再次对a_py.pyx cythonized,但是会重新创建构建目录(在构建和安装步骤之间是相同的),并且将编译文件(使用完全相同的编译器和链接器调用)。

完整的示例可以在这里找到: https : //github.com/zeeMonkeez/cmakeCythonTest

我有同样的问题。 显然,就我而言,在安装阶段, setup.py在查找将编译后的扩展放入构建阶段的目录时遇到了麻烦,因此即使使用--skip-build开关,它也可以重新编译它们。

通过在构建和安装阶段分别使用--build-lib--build-dir开关指定相同的目录路径来解决:

    add_custom_command(OUTPUT ${PY_OUTPUT}
            COMMAND ${PYTHON} ${SETUP_PY} build_ext --build-lib ${CMAKE_CURRENT_BINARY_DIR}/mysoext
            COMMAND ${CMAKE_COMMAND} -E touch ${PY_OUTPUT}
            DEPENDS ${DEPS}
            )
...
        set(MYINSTCMD "\
            EXECUTE_PROCESS(COMMAND ${PYTHON} ${SETUP_PY} install_lib \
            --skip-build \
            --install-dir /my/install/dir \
            --build-dir ${CMAKE_CURRENT_BINARY_DIR}/mysoext)")
        install(CODE "${MYINSTCMD}")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM