compile cython using the manual 2-step process

This is to leverage all compile and linking flags within the cmake build system.
http://cython.readthedocs.io/en/latest/src/reference/compilation.html#compiling-from-the-command-line
release/4.3a0
Duy-Nguyen Ta 2017-05-24 23:51:45 +08:00
parent 544b06510a
commit 1521a7e8ef
5 changed files with 76 additions and 62 deletions

27
cmake/FindEigency.cmake Normal file
View File

@ -0,0 +1,27 @@
# Find Eigency
#
# This code sets the following variables:
#
# EIGENCY_FOUND
# EIGENCY_INCLUDE_DIRS
#
# Find python
find_package( PythonInterp )
if ( PYTHONINTERP_FOUND )
execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-c"
"import eigency; includes=eigency.get_includes(include_eigen=False); print includes[0], ';', includes[1]"
RESULT_VARIABLE RESULT
OUTPUT_VARIABLE EIGENCY_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif ()
include( FindPackageHandleStandardArgs )
find_package_handle_standard_args(Eigency
FOUND_VAR
EIGENCY_FOUND
REQUIRED_VARS
EIGENCY_INCLUDE_DIRS
)

View File

@ -22,22 +22,19 @@ endif()
# extra_imports: extra header to import in the Cython pxd file.
# For example, to use Cython gtsam.pxd in your own module,
# use "from gtsam cimport *"
# setup_py_in_path: Path to the setup.py.in config file, which will be converted
# to setup.py file by cmake and used to compile the Cython module
# by invoking "python setup.py build_ext --inplace"
# install_path: destination to install the library
# dependencies: Dependencies which need to be built before the wrapper
function(wrap_and_install_library_cython interface_header extra_imports setup_py_in_path install_path dependencies)
function(wrap_and_install_library_cython interface_header extra_imports install_path dependencies)
# Paths for generated files
get_filename_component(module_name "${interface_header}" NAME_WE)
set(generated_files_path "${PROJECT_BINARY_DIR}/cython/${module_name}")
wrap_library_cython("${interface_header}" "${generated_files_path}" "${extra_imports}" "${setup_py_in_path}" "${dependencies}")
wrap_library_cython("${interface_header}" "${generated_files_path}" "${extra_imports}" "${dependencies}")
install_cython_wrapped_library("${interface_header}" "${generated_files_path}" "${install_path}")
endfunction()
# Internal function that wraps a library and compiles the wrapper
function(wrap_library_cython interface_header generated_files_path extra_imports setup_py_in_path dependencies)
function(wrap_library_cython interface_header generated_files_path extra_imports dependencies)
# Wrap codegen interface
# Extract module path and name from interface header file name
# wrap requires interfacePath to be *absolute*
@ -48,34 +45,37 @@ function(wrap_library_cython interface_header generated_files_path extra_imports
set(generated_cpp_file "${generated_files_path}/${module_name}.cpp")
message(STATUS "Building wrap module ${module_name}")
# Get build type postfix - gtsam_library_postfix is used in setup.py.in
# to link cythonized library to appropriate version of gtsam library
set(gtsam_library_postfix "")
if(GTSAM_BUILD_TYPE_POSTFIXES)
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type_upper)
set(gtsam_library_postfix ${CMAKE_${build_type_upper}_POSTFIX})
endif()
# Set up generation of module source file
file(MAKE_DIRECTORY "${generated_files_path}")
configure_file(${setup_py_in_path}/setup.py.in ${generated_files_path}/setup.py)
add_custom_command(
OUTPUT ${generated_cpp_file}
DEPENDS ${interface_header} wrap
COMMAND
DEPENDS ${interface_header} wrap
COMMAND
wrap --cython
${module_path}
${module_name}
${generated_files_path}
${module_name}
${generated_files_path}
"${extra_imports}"
&& python setup.py build_ext --inplace
&& cython --cplus -I. "${generated_files_path}/${module_name}.pyx"
VERBATIM
WORKING_DIRECTORY ${generated_files_path})
# Set up building of mex module
WORKING_DIRECTORY ${generated_files_path}/../)
add_custom_target(${module_name}_cython_wrapper ALL DEPENDS ${generated_cpp_file} ${interface_header} ${dependencies})
add_custom_target(wrap_${module_name}_cython_distclean
# Set up building of cython module
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
find_package(Eigency REQUIRED)
include_directories(${EIGENCY_INCLUDE_DIRS})
add_library(${module_name}_cython MODULE ${generated_cpp_file})
set_target_properties(${module_name}_cython PROPERTIES LINK_FLAGS "-undefined dynamic_lookup"
OUTPUT_NAME ${module_name} PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${generated_files_path})
target_link_libraries(${module_name}_cython ${module_name})
add_dependencies(${module_name}_cython ${module_name}_cython_wrapper)
# distclean
add_custom_target(wrap_${module_name}_cython_distclean
COMMAND cmake -E remove_directory ${generated_files_path})
endfunction()

View File

@ -1,15 +1,30 @@
# Install cython components
include(GtsamCythonWrap)
# install scripts and tests
install_cython_scripts("${PROJECT_SOURCE_DIR}/cython/gtsam" "${GTSAM_CYTHON_INSTALL_PATH}" "*.py")
# Create the cython toolbox for the gtsam library
if (GTSAM_INSTALL_CYTHON_TOOLBOX)
wrap_and_install_library_cython("../gtsam.h" # interface_header
"" # extra imports
"${GTSAM_CYTHON_INSTALL_PATH}/gtsam" # install path
gtsam # dependencies which need to be built before the wrapper
)
# generate __init__.py into build folder (configured with or without gtsam_unstable import line)
# This also makes the build/cython/gtsam folder a python package, so gtsam can be found while wrapping gtsam_unstable
if(GTSAM_BUILD_UNSTABLE)
set(GTSAM_UNSTABLE_IMPORT "from gtsam_unstable import *")
endif()
configure_file(${PROJECT_SOURCE_DIR}/cython/gtsam/__init__.py.in ${PROJECT_BINARY_DIR}/cython/gtsam/__init__.py)
# wrap gtsam_unstable
if(GTSAM_BUILD_UNSTABLE)
set(GTSAM_UNSTABLE_IMPORT "from gtsam_unstable import *")
wrap_and_install_library_cython("../gtsam_unstable/gtsam_unstable.h" # interface_header
"from gtsam.gtsam cimport *" # extra imports
"${GTSAM_CYTHON_INSTALL_PATH}/gtsam" # install path
gtsam_unstable # dependencies which need to be built before the wrapper
)
add_dependencies(gtsam_unstable_cython_wrapper gtsam_cython_wrapper)
endif()
# Install the custom-generated __init__.py
install_cython_files("${PROJECT_BINARY_DIR}/cython/gtsam/__init__.py" "${GTSAM_CYTHON_INSTALL_PATH}/gtsam")
# Install the custom-generated __init__.py with gtsam_unstable disabled
# This is to make the build/cython/gtsam folder a python package, so gtsam can be found while wrapping gtsam_unstable
configure_file(${PROJECT_SOURCE_DIR}/cython/gtsam/__init__.py.in ${PROJECT_BINARY_DIR}/cython/gtsam/__init__.py)
install_cython_files("${PROJECT_BINARY_DIR}/cython/gtsam/__init__.py" "${GTSAM_CYTHON_INSTALL_PATH}/gtsam")
# install scripts and tests
install_cython_scripts("${PROJECT_SOURCE_DIR}/cython/gtsam" "${GTSAM_CYTHON_INSTALL_PATH}" "*.py")
endif ()

View File

@ -166,16 +166,3 @@ if (GTSAM_INSTALL_MATLAB_TOOLBOX)
wrap_and_install_library(../gtsam.h "${GTSAM_ADDITIONAL_LIBRARIES}" "" "${mexFlags}")
endif ()
# Create the cython toolbox for the gtsam library
if (GTSAM_INSTALL_CYTHON_TOOLBOX)
# Set up codegen
include(GtsamCythonWrap)
# Wrap
wrap_and_install_library_cython("../gtsam.h" # interface_header
"" # extra imports
"../cython/gtsam" # path to setup.py.in
"${GTSAM_CYTHON_INSTALL_PATH}/gtsam" # install path
gtsam # dependencies which need to be built before the wrapper
)
endif ()

View File

@ -118,21 +118,6 @@ if (GTSAM_INSTALL_MATLAB_TOOLBOX)
wrap_and_install_library(gtsam_unstable.h "gtsam" "" "${mexFlags}")
endif(GTSAM_INSTALL_MATLAB_TOOLBOX)
# Cython wrap for gtsam_unstable
# Create the matlab toolbox for the gtsam library
if (GTSAM_INSTALL_CYTHON_TOOLBOX)
# Set up codegen
include(GtsamCythonWrap)
# Wrap
wrap_and_install_library_cython("../gtsam_unstable/gtsam_unstable.h" # interface_header
"from gtsam.gtsam cimport *" # extra imports
"../cython/gtsam_unstable" # path to setup.py.in
"${GTSAM_CYTHON_INSTALL_PATH}/gtsam" # install path
gtsam_unstable # dependencies which need to be built before the wrapper
)
add_dependencies(gtsam_unstable_cython_wrapper gtsam_cython_wrapper)
endif ()
# Build examples
add_subdirectory(examples)