From 2f9aa2054bb88791b459f39ec1b0d975a27b2fab Mon Sep 17 00:00:00 2001 From: EiffL Date: Mon, 28 Jul 2014 21:17:01 +0200 Subject: [PATCH 1/3] Updated custom cmake Find files from the pydata/numexpr project --- libs/numpy/cmake/FindPythonLibsNew.cmake | 43 ++++++++++++++++++------ 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/libs/numpy/cmake/FindPythonLibsNew.cmake b/libs/numpy/cmake/FindPythonLibsNew.cmake index b2a5d60..e1df610 100644 --- a/libs/numpy/cmake/FindPythonLibsNew.cmake +++ b/libs/numpy/cmake/FindPythonLibsNew.cmake @@ -12,7 +12,11 @@ # # PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated) # -# A function PYTHON_ADD_MODULE( src1 src2 ... srcN) is defined to build modules for python. +# A function PYTHON_ADD_MODULE( src1 src2 ... srcN) is defined +# to build modules for python. +# +# Thanks to talljimbo for the patch adding the 'LDVERSION' config +# variable usage. #============================================================================= # Copyright 2001-2009 Kitware, Inc. @@ -66,15 +70,19 @@ endif() # According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter # testing whether sys has the gettotalrefcount function is a reliable, cross-platform # way to detect a CPython debug interpreter. +# +# The library suffix is from the config var LDVERSION sometimes, otherwise +# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows. execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "from distutils import sysconfig as s;import sys;import struct; print('.'.join(str(v) for v in sys.version_info)); -print(s.PREFIX); +print(sys.prefix); print(s.get_python_inc(plat_specific=True)); print(s.get_python_lib(plat_specific=True)); print(s.get_config_var('SO')); print(hasattr(sys, 'gettotalrefcount')+0); print(struct.calcsize('@P')); +print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION')); " RESULT_VARIABLE _PYTHON_SUCCESS OUTPUT_VARIABLE _PYTHON_VALUES @@ -100,9 +108,11 @@ list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES) list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION) list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG) list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P) +list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX) # Make sure the Python has the same pointer-size as the chosen compiler -if(NOT ${PYTHON_SIZEOF_VOID_P} MATCHES ${CMAKE_SIZEOF_VOID_P}) +# Skip the check on OS X, it doesn't consistently have CMAKE_SIZEOF_VOID_P defined +if((NOT APPLE) AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}")) if(PythonLibsNew_FIND_REQUIRED) math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8") math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8") @@ -132,22 +142,28 @@ endif() if(CMAKE_HOST_WIN32) set(PYTHON_LIBRARY - "${PYTHON_PREFIX}/libs/Python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}.lib") + "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib") elseif(APPLE) - set(PYTHON_LIBRARY - "${PYTHON_PREFIX}/lib/libpython${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.dylib") + # Seems to require "-undefined dynamic_lookup" instead of linking + # against the .dylib, otherwise it crashes. This flag is added + # below + set(PYTHON_LIBRARY "") + #set(PYTHON_LIBRARY + # "${PYTHON_PREFIX}/lib/libpython${PYTHON_LIBRARY_SUFFIX}.dylib") else() if(${PYTHON_SIZEOF_VOID_P} MATCHES 8) set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib64" "${PYTHON_PREFIX}/lib") else() set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib") endif() + message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}") # Probably this needs to be more involved. It would be nice if the config # information the python interpreter itself gave us were more complete. find_library(PYTHON_LIBRARY - NAMES "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" + NAMES "python${PYTHON_LIBRARY_SUFFIX}" PATHS ${_PYTHON_LIBS_SEARCH} - NO_SYSTEM_ENVIRONMENT_PATH) + NO_DEFAULT_PATH) + message(STATUS "Found Python lib ${PYTHON_LIBRARY}") endif() # For backward compatibility, set PYTHON_INCLUDE_PATH, but make it internal. @@ -198,8 +214,14 @@ FUNCTION(PYTHON_ADD_MODULE _NAME ) SET_PROPERTY(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME}) ADD_LIBRARY(${_NAME} ${PY_MODULE_TYPE} ${ARGN}) - TARGET_LINK_LIBRARIES(${_NAME} ${PYTHON_LIBRARIES}) - + IF(APPLE) + # On OS X, linking against the Python libraries causes + # segfaults, so do this dynamic lookup instead. + SET_TARGET_PROPERTIES(${_NAME} PROPERTIES LINK_FLAGS + "-undefined dynamic_lookup") + ELSE() + TARGET_LINK_LIBRARIES(${_NAME} ${PYTHON_LIBRARIES}) + ENDIF() IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED) SET_TARGET_PROPERTIES(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") SET_TARGET_PROPERTIES(${_NAME} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") @@ -208,4 +230,3 @@ FUNCTION(PYTHON_ADD_MODULE _NAME ) ENDIF(PYTHON_ENABLE_MODULE_${_NAME}) ENDFUNCTION(PYTHON_ADD_MODULE) - From 2b70db6b9785a568d7aa774e2f7d2ff5d3ef4890 Mon Sep 17 00:00:00 2001 From: EiffL Date: Mon, 28 Jul 2014 21:37:52 +0200 Subject: [PATCH 2/3] Modified cmake to link against Boost.python3 if necessary --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fdfad2e..ba0bb4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,9 @@ find_package(NumPy REQUIRED) # set(Boost_USE_STATIC_LIBS ON) # set(Boost_USE_MULTITHREADED ON) # set(Boost_USE_STATIC_RUNTIME ON) -FIND_PACKAGE(Boost COMPONENTS python REQUIRED) + +# Find the correct Boost.python package depending on the python version +FIND_PACKAGE(Boost COMPONENTS python${PYTHON_VERSION_MAJOR} REQUIRED) message( STATUS "found boost:" "\nINCLUDE: ${Boost_INCLUDE_DIRS}" From 73ca2dea7ade5ba77e29f569e8757696cdfea5ee Mon Sep 17 00:00:00 2001 From: EiffL Date: Mon, 28 Jul 2014 21:47:09 +0200 Subject: [PATCH 3/3] Modified wrap.cpp example to compile under python3 --- libs/numpy/example/wrap.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/numpy/example/wrap.cpp b/libs/numpy/example/wrap.cpp index 06a8d55..724c184 100644 --- a/libs/numpy/example/wrap.cpp +++ b/libs/numpy/example/wrap.cpp @@ -111,7 +111,12 @@ BOOST_PYTHON_MODULE(example) { int main(int argc, char **argv) { // This line makes our module available to the embedded Python intepreter. + +#if PY_MAJOR_VERSION > 2 + PyImport_AppendInittab("example", &PyInit_example); +#else PyImport_AppendInittab("example", &initexample); +#endif // Initialize the Python runtime. Py_Initialize(); @@ -123,8 +128,8 @@ int main(int argc, char **argv) "z2 = numpy.zeros((4,3), dtype=float)\n" "example.fill1(z1)\n" "example.fill2(z2)\n" - "print z1\n" - "print z2\n" + "print( z1 )\n" + "print( z2 )\n" ); Py_Finalize(); }