From bbf51e15621ab1261f22e5ec8e53df10a0018566 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 1 Jun 2016 13:38:05 +0800 Subject: [PATCH] cmake: install cython modules * fix CYTHON_ADD_MODULE() macro. because python_add_module() offered by FindPythonLibs.cmake creates a target with name of ${name}, which conflicts with existing targets like "rbd" or "rados". so we can not reuse the name in ${name}.pyx. and instead, we should specify the target name explicitly. * add distutils_install_cython_module() function to build and install cython modules. * we can split build and install of cython module, but the install phase always tries to build the module. so keep it this way. will look at it later on. * move the variables initializations into the Distutils.cmake module. Signed-off-by: Kefu Chai --- cmake/modules/Distutils.cmake | 49 ++++++++++++++++++++++++++++++++ cmake/modules/FindCython.cmake | 49 +++++++++++++++++--------------- src/CMakeLists.txt | 1 + src/pybind/CMakeLists.txt | 8 ++---- src/pybind/cephfs/CMakeLists.txt | 17 ++--------- src/pybind/rados/CMakeLists.txt | 17 ++--------- src/pybind/rbd/CMakeLists.txt | 17 ++--------- 7 files changed, 88 insertions(+), 70 deletions(-) diff --git a/cmake/modules/Distutils.cmake b/cmake/modules/Distutils.cmake index 4697c87852b0..b4c678b208c1 100644 --- a/cmake/modules/Distutils.cmake +++ b/cmake/modules/Distutils.cmake @@ -22,3 +22,52 @@ function(distutils_install_module name) "execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py install ${options} --root=$DESTDIR WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") endfunction(distutils_install_module) + +function(distutils_add_cython_module name src) + get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE) + get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK) + set(PY_CC \"${compiler_launcher} ${CMAKE_C_COMPILER}\") + set(PY_CXX \"${compiler_launcher} ${CMAKE_CXX_COMPILER}\") + set(PY_LDSHARED \"${link_launcher} ${CMAKE_C_COMPILER} -shared\") + add_custom_target(${name} ALL + COMMAND + env + CC=${PY_CC} + CXX=${PY_CXX} + LDSHARED=${PY_LDSHARED} + OPT=\"-DNDEBUG -g -fwrapv -O2 -Wall\" + LDFLAGS=-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + CYTHON_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR} + CFLAGS=\"-iquote ${CMAKE_SOURCE_DIR}/src/include\" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py build --build-base ${CYTHON_MODULE_DIR} --verbose + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${src}) +endfunction(distutils_add_cython_module) + +function(distutils_install_cython_module name) + install(CODE " + set(options --prefix=/usr) + if(DEFINED ENV{DESTDIR}) + if(EXISTS /etc/debian_version) + set(options --install-layout=deb) + endif() + set(root --root=\$ENV{DESTDIR}) + else() + set(options \"--prefix=${CMAKE_INSTALL_PREFIX}\") + set(root --root=/) + endif() + execute_process( + COMMAND env + CYTHON_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR} + CFLAGS=\"-iquote ${CMAKE_SOURCE_DIR}/src/include\" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py + build --build-base ${CYTHON_MODULE_DIR} --verbose + install \${options} \${root} --verbose + --single-version-externally-managed --record /dev/null + WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\" + RESULT_VARIABLE install_res) + if(NOT \"\${install_res}\" STREQUAL 0) + message(FATAL_ERROR \"Failed to build and install ${name} python module\") + endif() + ") +endfunction(distutils_install_cython_module) diff --git a/cmake/modules/FindCython.cmake b/cmake/modules/FindCython.cmake index e9487065ae4c..05b10fb2db9e 100644 --- a/cmake/modules/FindCython.cmake +++ b/cmake/modules/FindCython.cmake @@ -48,32 +48,35 @@ ENDIF (Cython_FOUND) # 2) to compile assembly.pyx and something.cpp to assembly.so: # CYTHON_ADD_MODULE(assembly something.cpp) -if(NOT CYTHON_INCLUDE_DIRECTORIES) - set(CYTHON_INCLUDE_DIRECTORIES .) -endif(NOT CYTHON_INCLUDE_DIRECTORIES) - # Cythonizes the .pyx files into .cpp file (but doesn't compile it) macro(CYTHON_ADD_MODULE_PYX name) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) - set(DEPENDS ${name}.pyx ${name}.pxd) - else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) - set(DEPENDS ${name}.pyx) - endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) - # Allow the user to specify dependencies as optional arguments - set(DEPENDS ${DEPENDS} ${ARGN}) - add_custom_command( - OUTPUT ${name}.cpp - COMMAND ${CYTHON_BIN} - ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${name}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pyx - DEPENDS ${DEPENDS} - COMMENT "Cythonizing ${name}.pyx") + set(depends ${name}.pyx) + if(CYTHON_INCLUDE_DIRECTORIES) + foreach(dir ${CYTHON_INCLUDE_DIRECTORIES}) + file(GLOB pxd_srcs ${CYTHON_INCLUDE_DIRECTORIES}/*.pxd) + list(APPEND depends ${pxd_srcs}) + endforeach() + elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) + list(APPEND depends ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) + set(CYTHON_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + # Allow the user to specify dependencies as optional arguments + list(APPEND depends ${ARGN}) + add_custom_command( + OUTPUT ${name}.cpp + COMMAND ${CYTHON_BIN} + ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${name}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pyx + DEPENDS ${depends} + COMMENT "Cythonizing ${name}.pyx") endmacro(CYTHON_ADD_MODULE_PYX) # Cythonizes and compiles a .pyx file -macro(CYTHON_ADD_MODULE name) - CYTHON_ADD_MODULE_PYX(${name}) - # We need Python for this: - find_package(Python REQUIRED) - add_python_library(${name} ${name}.cpp ${ARGN}) +macro(CYTHON_ADD_MODULE name pyx) + CYTHON_ADD_MODULE_PYX(${pyx}) + add_library(${name} MODULE ${pyx}.cpp) + target_include_directories(${name} PRIVATE ${PYTHON_INCLUDE_PATH}) + target_link_libraries(${name} ${PYTHON_LIBRARIES}) + set_target_properties(${name} PROPERTIES + PREFIX "${PYTHON_MODULE_PREFIX}" + OUTPUT_NAME ${pyx}) endmacro(CYTHON_ADD_MODULE) - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b07ebaeebebe..d5e31bce170e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,6 +212,7 @@ find_package(PythonInterp 2 QUIET) if(NOT PYTHONINTERP_FOUND) message(FATAL_ERROR "Python 2 interpreter not found.") endif(NOT PYTHONINTERP_FOUND) +find_package(PythonLibs REQUIRED) # if CMAKE_INSTALL_PREFIX is an empty string, must replace # it with "/" to make PYTHON_INSTALL_TEMPLATE an absolute path to be diff --git a/src/pybind/CMakeLists.txt b/src/pybind/CMakeLists.txt index 6a4ba94ebd05..9acea1db9214 100644 --- a/src/pybind/CMakeLists.txt +++ b/src/pybind/CMakeLists.txt @@ -1,9 +1,7 @@ +find_package(Cython REQUIRED) +include(Distutils) + set(CYTHON_MODULE_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/cython_modules) -get_property(compiler_launcher GLOBAL PROPERTY RULE_LAUNCH_COMPILE) -get_property(link_launcher GLOBAL PROPERTY RULE_LAUNCH_LINK) -set(PY_CC \"${compiler_launcher} ${CMAKE_C_COMPILER}\") -set(PY_CXX \"${compiler_launcher} ${CMAKE_CXX_COMPILER}\") -set(PY_LDSHARED \"${link_launcher} ${CMAKE_C_COMPILER} -shared\") add_subdirectory(rados) add_subdirectory(rbd) diff --git a/src/pybind/cephfs/CMakeLists.txt b/src/pybind/cephfs/CMakeLists.txt index 2981a920b272..c3aa6c3d0ff9 100644 --- a/src/pybind/cephfs/CMakeLists.txt +++ b/src/pybind/cephfs/CMakeLists.txt @@ -1,14 +1,3 @@ -add_custom_target(cython_cephfs - COMMAND - env - CC=${PY_CC} - CXX=${PY_CXX} - LDSHARED=${PY_LDSHARED} - OPT=\"-DNDEBUG -g -fwrapv -O2 -Wall\" - LDFLAGS=-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - CYTHON_BUILD_DIR=${CMAKE_BINARY_DIR}/src/pybind/cephfs - CFLAGS=\"-iquote ${CMAKE_SOURCE_DIR}/src/include\" - python ${CMAKE_SOURCE_DIR}/src/pybind/cephfs/setup.py build --build-base ${CYTHON_MODULE_DIR} --verbose - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/cephfs - DEPENDS rados cephfs) - +distutils_add_cython_module(cython_cephfs ${CMAKE_CURRENT_SOURCE_DIR}/cephfs.pyx) +add_dependencies(cython_cephfs cephfs) +distutils_install_cython_module(cython_cephfs) diff --git a/src/pybind/rados/CMakeLists.txt b/src/pybind/rados/CMakeLists.txt index 8bbe9cef968f..5b36e5cc31dd 100644 --- a/src/pybind/rados/CMakeLists.txt +++ b/src/pybind/rados/CMakeLists.txt @@ -1,14 +1,3 @@ -add_custom_target(cython_rados - COMMAND - env - CC=${PY_CC} - CXX=${PY_CXX} - LDSHARED=${PY_LDSHARED} - OPT=\"-DNDEBUG -g -fwrapv -O2 -Wall\" - LDFLAGS=-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - CYTHON_BUILD_DIR=${CMAKE_BINARY_DIR}/src/pybind/rados - CFLAGS=\"-iquote ${CMAKE_SOURCE_DIR}/src/include\" - python ${CMAKE_SOURCE_DIR}/src/pybind/rados/setup.py build --build-base ${CYTHON_MODULE_DIR} --verbose - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/rados - DEPENDS rados) - +distutils_add_cython_module(cython_rados ${CMAKE_CURRENT_SOURCE_DIR}/rados.pyx) +add_dependencies(cython_rados rados) +distutils_install_cython_module(cython_rados) diff --git a/src/pybind/rbd/CMakeLists.txt b/src/pybind/rbd/CMakeLists.txt index 52400c45004d..50a37a0940a4 100644 --- a/src/pybind/rbd/CMakeLists.txt +++ b/src/pybind/rbd/CMakeLists.txt @@ -1,14 +1,3 @@ -add_custom_target(cython_rbd - COMMAND - env - CC=${PY_CC} - CXX=${PY_CXX} - LDSHARED=${PY_LDSHARED} - OPT=\"-DNDEBUG -g -fwrapv -O2 -Wall\" - LDFLAGS=-L${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - CYTHON_BUILD_DIR=${CMAKE_BINARY_DIR}/src/pybind/rbd - CFLAGS=\"-iquote ${CMAKE_SOURCE_DIR}/src/include\" - python ${CMAKE_SOURCE_DIR}/src/pybind/rbd/setup.py build --build-base ${CYTHON_MODULE_DIR} --verbose - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/pybind/rbd - DEPENDS rbd) - +distutils_add_cython_module(cython_rbd ${CMAKE_CURRENT_SOURCE_DIR}/rbd.pyx) +add_dependencies(cython_rbd rbd) +distutils_install_cython_module(cython_rbd) -- 2.47.3