我正在尝试按照以下结构与 Cython 绑定一起构建 C++ 库https://bloerg.net/2012/11/10/cmake-and-distutils.html https://bloerg.net/2012/11/10/cmake-and-distutils.html.
问题是,期间make install
,扩展将被编译两次。当只有一个 main 时,不会发生这种双重编译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
is
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
is:
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.cpp
and A.cpp
并链接库。
在安装步骤中,再次运行编译只有当CMakeFile.txt
在里面python
子文件夹.
这是安装过程中发生的情况:
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 https://github.com/zeeMonkeez/cmakeCythonTest