From c81dd85c3db228b3e83a8ecde25d551be7116372 Mon Sep 17 00:00:00 2001 From: jcarpent <jcarpent@laas.fr> Date: Tue, 17 Oct 2017 21:42:52 +0200 Subject: [PATCH] [CMake] Make EigenPy a full Python library --- CMakeLists.txt | 70 ++++++++++++++++++++---------- python/CMakeLists.txt | 88 ++++++++++++++++++++++++++++++++++++++ python/main.cpp | 30 +++++++++++++ python/scripts/__init__.py | 18 ++++++++ 4 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 python/CMakeLists.txt create mode 100644 python/main.cpp create mode 100644 python/scripts/__init__.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 8acb0ef3..627d0dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,12 @@ IF(APPLE) ENDIF("${isSystemDir}" STREQUAL "-1") ENDIF(APPLE) +IF(WIN32) + SET(LINK copy_if_different) +ELSE(WIN32) + SET(LINK create_symlink) +ENDIF(WIN32) + # ---------------------------------------------------- # --- OPTIONS --------------------------------------- # ---------------------------------------------------- @@ -74,34 +80,47 @@ INCLUDE_DIRECTORIES(${NUMPY_INCLUDE_DIRS}) # --- INCLUDE ---------------------------------------- # ---------------------------------------------------- SET(HEADERS - src/eigenpy.hpp - src/exception.hpp - src/details.hpp - src/fwd.hpp - src/map.hpp - src/geometry.hpp - src/memory.hpp - src/registration.hpp - src/angle-axis.hpp - src/quaternion.hpp + eigenpy.hpp + exception.hpp + details.hpp + fwd.hpp + map.hpp + geometry.hpp + memory.hpp + registration.hpp + angle-axis.hpp + quaternion.hpp ) MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy") INCLUDE_DIRECTORIES(${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy) +#FOREACH(header ${HEADERS}) +# GET_FILENAME_COMPONENT(headerName ${header} NAME) +# IF(WIN32) +# execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different +# ${${PROJECT_NAME}_SOURCE_DIR}/${header} +# ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/) +# ELSE(WIN32) +# execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink +# ${${PROJECT_NAME}_SOURCE_DIR}/${header} +# ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${headerName}) +# ENDIF(WIN32) +# INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/${header} +# DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME} +# PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) +#ENDFOREACH(header) + +SET(${PROJECT_NAME}_HEADERS) FOREACH(header ${HEADERS}) GET_FILENAME_COMPONENT(headerName ${header} NAME) - IF(WIN32) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${${PROJECT_NAME}_SOURCE_DIR}/${header} - ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/) - ELSE(WIN32) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink - ${${PROJECT_NAME}_SOURCE_DIR}/${header} - ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${headerName}) - ENDIF(WIN32) - INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/${header} - DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME} - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + GET_FILENAME_COMPONENT(headerPath ${header} PATH) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK} + ${${PROJECT_NAME}_SOURCE_DIR}/src/${header} + ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${header}) + INSTALL(FILES ${${PROJECT_NAME}_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/${headerPath} + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE) + LIST(APPEND ${PROJECT_NAME}_HEADERS src/${header}) ENDFOREACH(header) # ---------------------------------------------------- @@ -114,7 +133,7 @@ SET(${PROJECT_NAME}_SOURCES src/quaternion.cpp ) -ADD_LIBRARY(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${HEADERS}) +ADD_LIBRARY(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS}) TARGET_LINK_BOOST_PYTHON(${PROJECT_NAME}) PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME} eigen3) @@ -129,6 +148,11 @@ ADD_SUBDIRECTORY(unittest) # --- EXECUTABLES ------------------------------------ # ---------------------------------------------------- +# ---------------------------------------------------- +# --- PYTHON BINDINGS -------------------------------- +# ---------------------------------------------------- +ADD_SUBDIRECTORY(python) + IF(EIGEN_NUMPY_ALIGNED) PKG_CONFIG_APPEND_CFLAGS("-DEIGENPY_ALIGNED") ENDIF(EIGEN_NUMPY_ALIGNED) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt new file mode 100644 index 00000000..9faeefcd --- /dev/null +++ b/python/CMakeLists.txt @@ -0,0 +1,88 @@ +# +# Copyright (c) 2017 CNRS +# +# This file is part of eigenpy +# eigenpy is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either version +# 3 of the License, or (at your option) any later version. +# eigenpy is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Lesser Public License for more details. You should have +# received a copy of the GNU Lesser General Public License along with +# eigenpy If not, see +# <http://www.gnu.org/licenses/>. + +MACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH) + FOREACH(header ${HEADERS}) + GET_FILENAME_COMPONENT(headerName ${header} NAME) + GET_FILENAME_COMPONENT(headerPath ${header} PATH) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK} + ${CMAKE_CURRENT_SOURCE_DIR}/${header} + ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${SUBPATH}/${header}) + + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${header} + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/${SUBPATH}/${headerPath} + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE) + ENDFOREACH(header) +ENDMACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH) + +# --- LIBRARY --- # +SET(PYWRAP ${PROJECT_NAME}_pywrap) +MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}") + +ADD_LIBRARY(${PYWRAP} SHARED main.cpp) +TARGET_LINK_LIBRARIES(${PYWRAP} ${PROJECT_NAME}) +TARGET_LINK_BOOST_PYTHON(${PYWRAP}) +#IF(BUILD_WITH_COMMIT_VERSION) +# TAG_LIBRARY_VERSION(${PYWRAP}) +#ENDIF(BUILD_WITH_COMMIT_VERSION) +SET(${PYWRAP}_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME}) + +SET_PROPERTY(TARGET ${PYWRAP} PROPERTY LINKER_LANGUAGE CXX) +IF(APPLE) + # We need to change the extension for python bindings + SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES SUFFIX ".so") +ENDIF(APPLE) + +SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}") + +SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES PREFIX "") +SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}") + +INSTALL(TARGETS ${PYWRAP} DESTINATION ${${PYWRAP}_INSTALL_DIR}) + +# --- INSTALL SCRIPTS +SET(PYTHON_FILES + __init__.py + ) + +FOREACH(python ${PYTHON_FILES}) + GET_FILENAME_COMPONENT(pythonFile ${python} NAME) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK} + ${${PROJECT_NAME}_SOURCE_DIR}/python/scripts/${python} + ${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}) + + # Generate pyc file + EXECUTE_PROCESS(COMMAND + ${PYTHON_EXECUTABLE} -m py_compile + ${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}) + # Tag pyc file as generated. + SET_SOURCE_FILES_PROPERTIES( + "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c" + PROPERTIES GENERATED TRUE) + + # Clean generated files. + SET_PROPERTY( + DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES + "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c") + + INSTALL(FILES + "${${PROJECT_NAME}_SOURCE_DIR}/python/scripts/${python}" + "${${PROJECT_NAME}_BINARY_DIR}/python/${PROJECT_NAME}/${pythonFile}c" + DESTINATION ${${PYWRAP}_INSTALL_DIR}) +ENDFOREACH(python) + diff --git a/python/main.cpp b/python/main.cpp new file mode 100644 index 00000000..95ec5c44 --- /dev/null +++ b/python/main.cpp @@ -0,0 +1,30 @@ +// +// Copyright (c) 2017, Justin Carpentier, CNRS +// +// This file is part of eigenpy +// eigenpy is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version +// 3 of the License, or (at your option) any later version. +// +// eigenpy is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. You should have +// received a copy of the GNU Lesser General Public License along with +// eigenpy If not, see +// <http://www.gnu.org/licenses/>. + +#include "eigenpy/eigenpy.hpp" +#include "eigenpy/geometry.hpp" + +#include <iostream> + + +BOOST_PYTHON_MODULE(eigenpy) +{ + eigenpy::enableEigenPy(); + eigenpy::exposeAngleAxis(); + eigenpy::exposeQuaternion(); + +} diff --git a/python/scripts/__init__.py b/python/scripts/__init__.py new file mode 100644 index 00000000..3f79365c --- /dev/null +++ b/python/scripts/__init__.py @@ -0,0 +1,18 @@ +# +# Copyright (c) 2017 CNRS +# +# This file is part of eigenpy +# eigenpy is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either version +# 3 of the License, or (at your option) any later version. +# Pinocchio is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Lesser Public License for more details. You should have +# received a copy of the GNU Lesser General Public License along with +# eigenpy If not, see +# <http://www.gnu.org/licenses/>. + +import numpy as np +from eigenpy import * -- GitLab