From 40a567c1eda547bbbfacf232221cc088d0308115 Mon Sep 17 00:00:00 2001 From: Ellon Mendes Date: Tue, 1 Dec 2015 12:52:31 +0100 Subject: [PATCH] Look for NumPy C-API if building the python module --- cmake/FindNumPy.cmake | 102 ++++++++++++++++++++++++++++++++++++++++++ python/CMakeLists.txt | 18 +++++--- 2 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 cmake/FindNumPy.cmake diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake new file mode 100644 index 000000000..eafed165e --- /dev/null +++ b/cmake/FindNumPy.cmake @@ -0,0 +1,102 @@ +# - Find the NumPy libraries +# This module finds if NumPy is installed, and sets the following variables +# indicating where it is. +# +# TODO: Update to provide the libraries and paths for linking npymath lib. +# +# NUMPY_FOUND - was NumPy found +# NUMPY_VERSION - the version of NumPy found as a string +# NUMPY_VERSION_MAJOR - the major version number of NumPy +# NUMPY_VERSION_MINOR - the minor version number of NumPy +# NUMPY_VERSION_PATCH - the patch version number of NumPy +# NUMPY_VERSION_DECIMAL - e.g. version 1.6.1 is 10601 +# NUMPY_INCLUDE_DIRS - path to the NumPy include files + +#============================================================================ +# Copyright 2012 Continuum Analytics, Inc. +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#============================================================================ + +# Finding NumPy involves calling the Python interpreter +if(NumPy_FIND_REQUIRED) + find_package(PythonInterp REQUIRED) +else() + find_package(PythonInterp) +endif() + +if(NOT PYTHONINTERP_FOUND) + set(NUMPY_FOUND FALSE) + return() +endif() + +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "import numpy as n; print(n.__version__); print(n.get_include());" + RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS + OUTPUT_VARIABLE _NUMPY_VALUES_OUTPUT + ERROR_VARIABLE _NUMPY_ERROR_VALUE + OUTPUT_STRIP_TRAILING_WHITESPACE) + +if(NOT _NUMPY_SEARCH_SUCCESS MATCHES 0) + if(NumPy_FIND_REQUIRED) + message(FATAL_ERROR + "NumPy import failure:\n${_NUMPY_ERROR_VALUE}") + endif() + set(NUMPY_FOUND FALSE) + return() +endif() + +# Convert the process output into a list +string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES_OUTPUT}) +string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES}) +# Just in case there is unexpected output from the Python command. +list(GET _NUMPY_VALUES -2 NUMPY_VERSION) +list(GET _NUMPY_VALUES -1 NUMPY_INCLUDE_DIRS) + +string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" _VER_CHECK "${NUMPY_VERSION}") +if("${_VER_CHECK}" STREQUAL "") + # The output from Python was unexpected. Raise an error always + # here, because we found NumPy, but it appears to be corrupted somehow. + message(FATAL_ERROR + "Requested version and include path from NumPy, got instead:\n${_NUMPY_VALUES_OUTPUT}\n") + return() +endif() + +# Make sure all directory separators are '/' +string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS}) + +# Get the major and minor version numbers +string(REGEX REPLACE "\\." ";" _NUMPY_VERSION_LIST ${NUMPY_VERSION}) +list(GET _NUMPY_VERSION_LIST 0 NUMPY_VERSION_MAJOR) +list(GET _NUMPY_VERSION_LIST 1 NUMPY_VERSION_MINOR) +list(GET _NUMPY_VERSION_LIST 2 NUMPY_VERSION_PATCH) +string(REGEX MATCH "[0-9]*" NUMPY_VERSION_PATCH ${NUMPY_VERSION_PATCH}) +math(EXPR NUMPY_VERSION_DECIMAL + "(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}") + +find_package_message(NUMPY + "Found NumPy: version \"${NUMPY_VERSION}\" ${NUMPY_INCLUDE_DIRS}" + "${NUMPY_INCLUDE_DIRS}${NUMPY_VERSION}") + +set(NUMPY_FOUND TRUE) + diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 28b916ab2..0e1a5f0dd 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -28,14 +28,16 @@ else() set(UPPER_BOOST_PYTHON_VERSION_STRING "") endif() -# Be sure that python version can be found by FindPythonLibs.cmake +# Find NumPy C-API +find_package(NumPy) + +# Find Python +# First, be sure that python version can be found by FindPythonLibs.cmake # See: http://stackoverflow.com/a/15660652/2220173 set(Python_ADDITIONAL_VERSIONS ${GTSAM_PYTHON_VERSION}) - -# Find Python +# Then look for the the lib. If no version is specified when looking for PythonLibs it searches the default version. +# See: https://cmake.org/cmake/help/v3.1/module/FindPythonInterp.html if(GTSAM_PYTHON_VERSION STREQUAL "Default") - # If no version is specified when looking for PythonLibs it searches the default version. - # See: https://cmake.org/cmake/help/v3.1/module/FindPythonInterp.html find_package(PythonLibs) else() find_package(PythonLibs ${GTSAM_PYTHON_VERSION}) @@ -45,7 +47,7 @@ endif() find_package(Boost COMPONENTS python${BOOST_PYTHON_VERSION_STRING}) # Add handwritten directory if we found python and boost python -if(Boost_PYTHON${UPPER_BOOST_PYTHON_VERSION_STRING}_FOUND AND PYTHONLIBS_FOUND) +if(Boost_PYTHON${UPPER_BOOST_PYTHON_VERSION_STRING}_FOUND AND PYTHONLIBS_FOUND AND NUMPY_FOUND) include_directories(${PYTHON_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CMAKE_SOURCE_DIR}/gtsam/3rdparty/numpy_eigen/include/) @@ -70,4 +72,8 @@ if(NOT Boost_PYTHON${UPPER_BOOST_PYTHON_VERSION_STRING}_FOUND) else() message(WARNING "Boost Python for python ${GTSAM_PYTHON_VERSION} was not found -- Python module cannot be built. Option GTSAM_BUILD_PYTHON disabled.") endif() +endif() + +if(NOT NUMPY_FOUND) + message(WARNING "NumPy C-API was not found -- Python module cannot be built. Option GTSAM_BUILD_PYTHON disabled.") endif() \ No newline at end of file