Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
3f3ea262
Commit
3f3ea262
authored
May 29, 2016
by
Boris Schäling
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into cygwin
parents
9309b022
0a07805a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
351 additions
and
192 deletions
+351
-192
.travis.yml
+2
-0
CMakeLists.txt
+0
-0
README.md
+5
-2
docs/compiling.rst
+20
-138
example/CMakeLists.txt
+68
-0
example/example6.cpp
+5
-5
include/pybind11/cast.h
+6
-6
include/pybind11/common.h
+7
-6
include/pybind11/eigen.h
+16
-4
include/pybind11/numpy.h
+7
-7
include/pybind11/pybind11.h
+5
-5
include/pybind11/pytypes.h
+10
-7
include/pybind11/stl_bind.h
+13
-12
tools/FindPythonLibsNew.cmake
+187
-0
No files found.
.travis.yml
View file @
3f3ea262
...
...
@@ -9,6 +9,7 @@ addons:
sources
:
-
ubuntu-toolchain-r-test
-
deadsnakes
-
kubuntu-backports
# cmake 2.8.12
packages
:
-
g++-4.8
-
g++-4.8-multilib
...
...
@@ -17,6 +18,7 @@ addons:
-
python3.5-dev
-
python3.5-venv
-
python3.5-dev:i386
-
cmake
matrix
:
include
:
-
os
:
linux
...
...
CMakeLists.txt
View file @
3f3ea262
This diff is collapsed.
Click to expand it.
README.md
View file @
3f3ea262
...
...
@@ -90,6 +90,7 @@ In addition to the core functionality, pybind11 provides some extra goodies:
2.
GCC (any non-ancient version with C++11 support)
3.
Microsoft Visual Studio 2015 or newer
4.
Intel C++ compiler v15 or newer
5.
Cygwin
## About
...
...
@@ -101,8 +102,10 @@ Axel Huebl,
@hulucc,
Sergey Lyskov
Johan Mabille,
Tomasz Miąsko, and
Ben Pritchard.
Tomasz Miąsko,
Dean Moldovan,
Ben Pritchard, and
Boris Schäling.
### License
...
...
docs/compiling.rst
View file @
3f3ea262
...
...
@@ -26,146 +26,28 @@ Building with cppimport
Building with CMake
===================
For C++ codebases that already have an existing CMake-based build system, the
following snippet should be a good starting point to create bindings across
platforms. It assumes that the code is located in a file named
:file:`example.cpp`, and that the pybind11 repository is located in a
subdirectory named :file:`pybind11`.
For C++ codebases that have an existing CMake-based build system, a Python
extension module can be created with just a few lines of code:
.. code-block:: cmake
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.8.12)
project(example)
# Add a CMake parameter for choosing a desired Python version
set(EXAMPLE_PYTHON_VERSION "" CACHE STRING
"Python version to use for compiling the example library")
include(CheckCXXCompilerFlag)
# Set a default build configuration if none is specified.
# 'MinSizeRel' produces the smallest binaries
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
# Try to autodetect Python (can be overridden manually if needed)
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
if (NOT ${EXAMPLE_PYTHON_VERSION} STREQUAL "")
find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} EXACT)
if (NOT PYTHONLIBS_FOUND)
find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} REQUIRED)
endif()
else()
find_package(PythonLibs REQUIRED)
endif()
# The above sometimes returns version numbers like "3.4.3+";
# the "+" must be removed for the next lines to work
string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
# Uncomment the following line if you will also require a matching Python interpreter
# find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
if (HAS_CPP14_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
elseif (HAS_CPP11_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(FATAL_ERROR "Unsupported compiler -- at least C++11 support is needed!")
endif()
# Enable link time optimization and set the default symbol
# visibility to hidden (very important to obtain small binaries)
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
# Default symbol visibility
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# Check for Link Time Optimization support
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
if (HAS_LTO_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
endif()
endif()
endif()
# Include path for Python header files
include_directories(${PYTHON_INCLUDE_DIR})
# Include path for pybind11 header files -- this may need to be
# changed depending on your setup
include_directories(${PROJECT_SOURCE_DIR}/pybind11/include)
# Create the binding library
add_library(example SHARED
example.cpp
# ... extra files go here ...
)
# Don't add a 'lib' prefix to the shared library
set_target_properties(example PROPERTIES PREFIX "")
if (WIN32)
if (MSVC)
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
# needed for bigger binding projects due to the limit to 64k addressable sections
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
# Enforce size-based optimization and link time code generation on MSVC
# (~30% smaller binaries in experiments); do nothing in debug mode.
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
"$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
"$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
"$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
)
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
endif()
# .PYD file extension on Windows
set_target_properties(example PROPERTIES SUFFIX ".pyd")
# Link against the Python shared library
target_link_libraries(example ${PYTHON_LIBRARY})
elseif (UNIX)
# It's quite common to have multiple copies of the same Python version
# installed on one's system. E.g.: one copy from the OS and another copy
# that's statically linked into an application like Blender or Maya.
# If we link our plugin library against the OS Python here and import it
# into Blender or Maya later on, this will cause segfaults when multiple
# conflicting Python instances are active at the same time (even when they
# are of the same version).
# Windows is not affected by this issue since it handles DLL imports
# differently. The solution for Linux and Mac OS is simple: we just don't
# link against the Python library. The resulting shared library will have
# missing symbols, but that's perfectly fine -- they will be resolved at
# import time.
# .SO file extension on Linux/Mac OS
set_target_properties(example PROPERTIES SUFFIX ".so")
# Strip unnecessary sections of the binary on Linux/Mac OS
if(APPLE)
set_target_properties(example PROPERTIES MACOSX_RPATH ".")
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
add_custom_command(TARGET example POST_BUILD
COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
endif()
else()
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
add_custom_command(TARGET example POST_BUILD
COMMAND strip ${PROJECT_BINARY_DIR}/example.so)
endif()
endif()
endif()
add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)
This assumes that the pybind11 repository is located in a subdirectory named
:file:`pybind11` and that the code is located in a file named :file:`example.cpp`.
The CMake command ``add_subdirectory`` will import a function with the signature
``pybind11_add_module(<name> source1 [source2 ...])``. It will take care of all
the details needed to build a Python extension module on any platform.
The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION``
variable before adding the pybind11 subdirectory. Alternatively, an exact Python
installation can be specified by setting ``PYTHON_EXECUTABLE``.
A working sample project, including a way to invoke CMake from :file:`setup.py` for
PyPI integration, can be found in the [cmake_example]_ repository.
.. [cmake_example] https://github.com/dean0x7d/pybind11_cmake_example
example/CMakeLists.txt
0 → 100644
View file @
3f3ea262
# Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
if
(
NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES
)
message
(
STATUS
"Setting build type to 'MinSizeRel' as none was specified."
)
set
(
CMAKE_BUILD_TYPE MinSizeRel CACHE STRING
"Choose the type of build."
FORCE
)
set_property
(
CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug"
"Release"
"MinSizeRel"
"RelWithDebInfo"
)
endif
()
set
(
PYBIND11_EXAMPLES
example1.cpp
example2.cpp
example3.cpp
example4.cpp
example5.cpp
example6.cpp
example7.cpp
example8.cpp
example9.cpp
example10.cpp
example11.cpp
example12.cpp
example13.cpp
example14.cpp
example15.cpp
example16.cpp
example17.cpp
issues.cpp
)
# Check if Eigen is available
find_package
(
Eigen3 QUIET
)
if
(
EIGEN3_FOUND
)
list
(
APPEND PYBIND11_EXAMPLES eigen.cpp
)
message
(
STATUS
"Building Eigen testcase"
)
else
()
message
(
STATUS
"NOT Building Eigen testcase"
)
endif
()
# Create the binding library
pybind11_add_module
(
example example.cpp
${
PYBIND11_EXAMPLES
}
)
pybind11_enable_warnings
(
example
)
if
(
EIGEN3_FOUND
)
target_include_directories
(
example PRIVATE
${
EIGEN3_INCLUDE_DIR
}
)
target_compile_definitions
(
example PRIVATE -DPYBIND11_TEST_EIGEN
)
endif
()
# Always write the output file directly into the 'example' directory (even on MSVC)
set
(
CompilerFlags
LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
)
foreach
(
CompilerFlag
${
CompilerFlags
}
)
set_target_properties
(
example PROPERTIES
${
CompilerFlag
}
${
PROJECT_SOURCE_DIR
}
/example
)
endforeach
()
set
(
RUN_TEST
${
PYTHON_EXECUTABLE
}
${
CMAKE_CURRENT_SOURCE_DIR
}
/run_test.py
)
if
(
MSVC OR CMAKE_CXX_COMPILER_ID MATCHES
"Intel"
)
set
(
RUN_TEST
${
RUN_TEST
}
--relaxed
)
endif
()
foreach
(
VALUE
${
PYBIND11_EXAMPLES
}
)
string
(
REGEX REPLACE
"^(.+).cpp$"
"
\\
1"
EXAMPLE_NAME
"
${
VALUE
}
"
)
add_test
(
NAME
${
EXAMPLE_NAME
}
COMMAND
${
RUN_TEST
}
${
EXAMPLE_NAME
}
)
endforeach
()
example/example6.cpp
View file @
3f3ea262
...
...
@@ -133,22 +133,22 @@ void init_ex6(py::module &m) {
.
def
(
"__reversed__"
,
[](
const
Sequence
&
s
)
->
Sequence
{
return
s
.
reversed
();
})
/// Slicing protocol (optional)
.
def
(
"__getitem__"
,
[](
const
Sequence
&
s
,
py
::
slice
slice
)
->
Sequence
*
{
py
::
s
size_t
start
,
stop
,
step
,
slicelength
;
size_t
start
,
stop
,
step
,
slicelength
;
if
(
!
slice
.
compute
(
s
.
size
(),
&
start
,
&
stop
,
&
step
,
&
slicelength
))
throw
py
::
error_already_set
();
Sequence
*
seq
=
new
Sequence
(
slicelength
);
for
(
in
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
for
(
size_
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
(
*
seq
)[
i
]
=
s
[
start
];
start
+=
step
;
}
return
seq
;
})
.
def
(
"__setitem__"
,
[](
Sequence
&
s
,
py
::
slice
slice
,
const
Sequence
&
value
)
{
py
::
s
size_t
start
,
stop
,
step
,
slicelength
;
size_t
start
,
stop
,
step
,
slicelength
;
if
(
!
slice
.
compute
(
s
.
size
(),
&
start
,
&
stop
,
&
step
,
&
slicelength
))
throw
py
::
error_already_set
();
if
(
(
size_t
)
slicelength
!=
value
.
size
())
if
(
slicelength
!=
value
.
size
())
throw
std
::
runtime_error
(
"Left and right hand size of slice assignment have different sizes!"
);
for
(
in
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
for
(
size_
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
s
[
start
]
=
value
[
i
];
start
+=
step
;
}
})
...
...
include/pybind11/cast.h
View file @
3f3ea262
...
...
@@ -471,13 +471,13 @@ public:
ssize_t
length
;
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
load_src
.
ptr
(),
&
buffer
,
&
length
);
if
(
err
==
-
1
)
{
PyErr_Clear
();
return
false
;
}
// TypeError
value
=
std
::
string
(
buffer
,
length
);
value
=
std
::
string
(
buffer
,
(
size_t
)
length
);
success
=
true
;
return
true
;
}
static
handle
cast
(
const
std
::
string
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
return
PyUnicode_FromStringAndSize
(
src
.
c_str
(),
src
.
length
());
return
PyUnicode_FromStringAndSize
(
src
.
c_str
(),
(
ssize_t
)
src
.
length
());
}
PYBIND11_TYPE_CASTER
(
std
::
string
,
_
(
PYBIND11_STRING_NAME
));
...
...
@@ -520,17 +520,17 @@ public:
if
(
temp
)
{
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
temp
.
ptr
(),
(
char
**
)
&
buffer
,
&
length
);
if
(
err
==
-
1
)
{
buffer
=
nullptr
;
}
// TypeError
length
=
length
/
sizeof
(
wchar_t
)
-
1
;
++
buffer
;
// Skip BOM
length
=
length
/
(
ssize_t
)
sizeof
(
wchar_t
)
-
1
;
++
buffer
;
// Skip BOM
}
#endif
if
(
!
buffer
)
{
PyErr_Clear
();
return
false
;
}
value
=
std
::
wstring
(
buffer
,
length
);
value
=
std
::
wstring
(
buffer
,
(
size_t
)
length
);
success
=
true
;
return
true
;
}
static
handle
cast
(
const
std
::
wstring
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
return
PyUnicode_FromWideChar
(
src
.
c_str
(),
src
.
length
());
return
PyUnicode_FromWideChar
(
src
.
c_str
(),
(
ssize_t
)
src
.
length
());
}
PYBIND11_TYPE_CASTER
(
std
::
wstring
,
_
(
PYBIND11_STRING_NAME
));
...
...
@@ -570,7 +570,7 @@ public:
static
handle
cast
(
const
wchar_t
*
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
if
(
src
==
nullptr
)
return
handle
(
Py_None
).
inc_ref
();
return
PyUnicode_FromWideChar
(
src
,
wcslen
(
src
));
return
PyUnicode_FromWideChar
(
src
,
(
ssize_t
)
wcslen
(
src
));
}
static
handle
cast
(
wchar_t
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
...
...
include/pybind11/common.h
View file @
3f3ea262
...
...
@@ -197,22 +197,23 @@ struct buffer_info {
size_t
itemsize
;
// Size of individual items in bytes
size_t
size
;
// Total number of entries
std
::
string
format
;
// For homogeneous buffers, this should be set to format_descriptor<T>::value
int
ndim
;
// Number of dimensions
size_t
ndim
;
// Number of dimensions
std
::
vector
<
size_t
>
shape
;
// Shape of the tensor (1 entry per dimension)
std
::
vector
<
size_t
>
strides
;
// Number of entries between adjacent entries (for each per dimension)
buffer_info
()
:
ptr
(
nullptr
),
view
(
nullptr
)
{}
buffer_info
(
void
*
ptr
,
size_t
itemsize
,
const
std
::
string
&
format
,
in
t
ndim
,
buffer_info
(
void
*
ptr
,
size_t
itemsize
,
const
std
::
string
&
format
,
size_
t
ndim
,
const
std
::
vector
<
size_t
>
&
shape
,
const
std
::
vector
<
size_t
>
&
strides
)
:
ptr
(
ptr
),
itemsize
(
itemsize
),
size
(
1
),
format
(
format
),
ndim
(
ndim
),
shape
(
shape
),
strides
(
strides
)
{
for
(
int
i
=
0
;
i
<
ndim
;
++
i
)
size
*=
shape
[
i
];
for
(
size_t
i
=
0
;
i
<
ndim
;
++
i
)
size
*=
shape
[
i
];
}
buffer_info
(
Py_buffer
*
view
)
:
ptr
(
view
->
buf
),
itemsize
(
view
->
itemsize
),
size
(
1
),
format
(
view
->
format
),
ndim
(
view
->
ndim
),
shape
(
view
->
ndim
),
strides
(
view
->
ndim
),
view
(
view
)
{
for
(
int
i
=
0
;
i
<
view
->
ndim
;
++
i
)
{
:
ptr
(
view
->
buf
),
itemsize
(
(
size_t
)
view
->
itemsize
),
size
(
1
),
format
(
view
->
format
),
ndim
(
(
size_t
)
view
->
ndim
),
shape
((
size_t
)
view
->
ndim
),
strides
((
size_t
)
view
->
ndim
),
view
(
view
)
{
for
(
size_t
i
=
0
;
i
<
(
size_t
)
view
->
ndim
;
++
i
)
{
shape
[
i
]
=
(
size_t
)
view
->
shape
[
i
];
strides
[
i
]
=
(
size_t
)
view
->
strides
[
i
];
size
*=
shape
[
i
];
...
...
include/pybind11/eigen.h
View file @
3f3ea262
...
...
@@ -10,9 +10,19 @@
#pragma once
#include "numpy.h"
#if defined(__GNUG__) || defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion"
#endif
#include <Eigen/Core>
#include <Eigen/SparseCore>
#if defined(__GNUG__) || defined(__clang__)
# pragma GCC diagnostic pop
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
...
...
@@ -63,7 +73,7 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
auto
strides
=
Strides
(
info
.
strides
[
0
]
/
sizeof
(
Scalar
),
0
);
value
=
Eigen
::
Map
<
Type
,
0
,
Strides
>
(
(
Scalar
*
)
info
.
ptr
,
info
.
shape
[
0
]
,
1
,
strides
);
(
Scalar
*
)
info
.
ptr
,
typename
Strides
::
Index
(
info
.
shape
[
0
])
,
1
,
strides
);
}
else
if
(
info
.
ndim
==
2
)
{
typedef
Eigen
::
Stride
<
Eigen
::
Dynamic
,
Eigen
::
Dynamic
>
Strides
;
...
...
@@ -76,7 +86,9 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
info
.
strides
[
rowMajor
?
1
:
0
]
/
sizeof
(
Scalar
));
value
=
Eigen
::
Map
<
Type
,
0
,
Strides
>
(
(
Scalar
*
)
info
.
ptr
,
info
.
shape
[
0
],
info
.
shape
[
1
],
strides
);
(
Scalar
*
)
info
.
ptr
,
typename
Strides
::
Index
(
info
.
shape
[
0
]),
typename
Strides
::
Index
(
info
.
shape
[
1
]),
strides
);
}
else
{
return
false
;
}
...
...
@@ -117,8 +129,8 @@ struct type_caster<Type, typename std::enable_if<is_eigen_dense<Type>::value>::t
{
(
size_t
)
src
.
rows
(),
(
size_t
)
src
.
cols
()
},
/* Strides (in bytes) for each index */
{
sizeof
(
Scalar
)
*
(
rowMajor
?
src
.
cols
()
:
1
),
sizeof
(
Scalar
)
*
(
rowMajor
?
1
:
src
.
rows
())
}
{
sizeof
(
Scalar
)
*
(
rowMajor
?
(
size_t
)
src
.
cols
()
:
1
),
sizeof
(
Scalar
)
*
(
rowMajor
?
1
:
(
size_t
)
src
.
rows
())
}
)).
release
();
}
}
...
...
include/pybind11/numpy.h
View file @
3f3ea262
...
...
@@ -109,7 +109,7 @@ public:
if
(
descr
==
nullptr
)
pybind11_fail
(
"NumPy: unsupported buffer format '"
+
info
.
format
+
"'!"
);
object
tmp
(
api
.
PyArray_NewFromDescr_
(
api
.
PyArray_Type_
,
descr
,
info
.
ndim
,
(
Py_intptr_t
*
)
&
info
.
shape
[
0
],
api
.
PyArray_Type_
,
descr
,
(
int
)
info
.
ndim
,
(
Py_intptr_t
*
)
&
info
.
shape
[
0
],
(
Py_intptr_t
*
)
&
info
.
strides
[
0
],
info
.
ptr
,
0
,
nullptr
),
false
);
if
(
info
.
ptr
&&
tmp
)
tmp
=
object
(
api
.
PyArray_NewCopy_
(
tmp
.
ptr
(),
-
1
/* any order */
),
false
);
...
...
@@ -261,7 +261,7 @@ private:
while
(
buffer_shape_iter
!=
buffer
.
shape
.
rend
())
{
if
(
*
shape_iter
==
*
buffer_shape_iter
)
*
strides_iter
=
static_cast
<
in
t
>
(
*
buffer_strides_iter
);
*
strides_iter
=
static_cast
<
size_
t
>
(
*
buffer_strides_iter
);
else
*
strides_iter
=
0
;
...
...
@@ -286,12 +286,12 @@ private:
};
template
<
size_t
N
>
bool
broadcast
(
const
std
::
array
<
buffer_info
,
N
>&
buffers
,
in
t
&
ndim
,
std
::
vector
<
size_t
>&
shape
)
{
ndim
=
std
::
accumulate
(
buffers
.
begin
(),
buffers
.
end
(),
0
,
[](
in
t
res
,
const
buffer_info
&
buf
)
{
bool
broadcast
(
const
std
::
array
<
buffer_info
,
N
>&
buffers
,
size_
t
&
ndim
,
std
::
vector
<
size_t
>&
shape
)
{
ndim
=
std
::
accumulate
(
buffers
.
begin
(),
buffers
.
end
(),
size_t
(
0
),
[](
size_
t
res
,
const
buffer_info
&
buf
)
{
return
std
::
max
(
res
,
buf
.
ndim
);
});
shape
=
std
::
vector
<
size_t
>
(
static_cast
<
size_t
>
(
ndim
)
,
1
);
shape
=
std
::
vector
<
size_t
>
(
ndim
,
1
);
bool
trivial_broadcast
=
true
;
for
(
size_t
i
=
0
;
i
<
N
;
++
i
)
{
auto
res_iter
=
shape
.
rbegin
();
...
...
@@ -329,7 +329,7 @@ struct vectorize_helper {
std
::
array
<
buffer_info
,
N
>
buffers
{{
args
.
request
()...
}};
/* Determine dimensions parameters of output array */
in
t
ndim
=
0
;
size_
t
ndim
=
0
;
std
::
vector
<
size_t
>
shape
(
0
);
bool
trivial_broadcast
=
broadcast
(
buffers
,
ndim
,
shape
);
...
...
@@ -337,7 +337,7 @@ struct vectorize_helper {
std
::
vector
<
size_t
>
strides
(
ndim
);
if
(
ndim
>
0
)
{
strides
[
ndim
-
1
]
=
sizeof
(
Return
);
for
(
in
t
i
=
ndim
-
1
;
i
>
0
;
--
i
)
{
for
(
size_
t
i
=
ndim
-
1
;
i
>
0
;
--
i
)
{
strides
[
i
-
1
]
=
strides
[
i
]
*
shape
[
i
];
size
*=
shape
[
i
];
}
...
...
include/pybind11/pybind11.h
View file @
3f3ea262
...
...
@@ -336,8 +336,8 @@ protected:
*
it
=
overloads
;
/* Need to know how many arguments + keyword arguments there are to pick the right overload */
size_t
nargs
=
PyTuple_GET_SIZE
(
args
),
nkwargs
=
kwargs
?
PyDict_Size
(
kwargs
)
:
0
;
size_t
nargs
=
(
size_t
)
PyTuple_GET_SIZE
(
args
),
nkwargs
=
kwargs
?
(
size_t
)
PyDict_Size
(
kwargs
)
:
0
;
handle
parent
=
nargs
>
0
?
PyTuple_GET_ITEM
(
args
,
0
)
:
nullptr
,
result
=
PYBIND11_TRY_NEXT_OVERLOAD
;
...
...
@@ -547,7 +547,7 @@ protected:
:
std
::
string
(
rec
->
name
));
/* Basic type attributes */
type
->
ht_type
.
tp_name
=
strdup
(
full_name
.
c_str
());
type
->
ht_type
.
tp_basicsize
=
rec
->
instance_size
;
type
->
ht_type
.
tp_basicsize
=
(
ssize_t
)
rec
->
instance_size
;
type
->
ht_type
.
tp_base
=
(
PyTypeObject
*
)
rec
->
base_handle
.
ptr
();
rec
->
base_handle
.
inc_ref
();
...
...
@@ -702,14 +702,14 @@ protected:
view
->
ndim
=
1
;
view
->
internal
=
info
;
view
->
buf
=
info
->
ptr
;
view
->
itemsize
=
info
->
itemsize
;
view
->
itemsize
=
(
ssize_t
)
info
->
itemsize
;
view
->
len
=
view
->
itemsize
;
for
(
auto
s
:
info
->
shape
)
view
->
len
*=
s
;
if
((
flags
&
PyBUF_FORMAT
)
==
PyBUF_FORMAT
)
view
->
format
=
const_cast
<
char
*>
(
info
->
format
.
c_str
());
if
((
flags
&
PyBUF_STRIDES
)
==
PyBUF_STRIDES
)
{
view
->
ndim
=
info
->
ndim
;
view
->
ndim
=
(
int
)
info
->
ndim
;
view
->
strides
=
(
ssize_t
*
)
&
info
->
strides
[
0
];
view
->
shape
=
(
ssize_t
*
)
&
info
->
shape
[
0
];
}
...
...
include/pybind11/pytypes.h
View file @
3f3ea262
...
...
@@ -336,7 +336,7 @@ public:
PYBIND11_OBJECT_DEFAULT
(
str
,
object
,
detail
::
PyUnicode_Check_Permissive
)
str
(
const
std
::
string
&
s
)
:
object
(
PyUnicode_FromStringAndSize
(
s
.
c_str
(),
s
.
length
()),
false
)
{
:
object
(
PyUnicode_FromStringAndSize
(
s
.
c_str
(),
(
ssize_t
)
s
.
length
()),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate string object!"
);
}
...
...
@@ -352,7 +352,7 @@ public:
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
temp
.
ptr
(),
&
buffer
,
&
length
);
if
(
err
==
-
1
)
pybind11_fail
(
"Unable to extract string contents! (invalid type)"
);
return
std
::
string
(
buffer
,
length
);
return
std
::
string
(
buffer
,
(
size_t
)
length
);
}
};
...
...
@@ -370,7 +370,7 @@ public:
PYBIND11_OBJECT_DEFAULT
(
bytes
,
object
,
PYBIND11_BYTES_CHECK
)
bytes
(
const
std
::
string
&
s
)
:
object
(
PYBIND11_BYTES_FROM_STRING_AND_SIZE
(
s
.
data
(),
s
.
size
()),
false
)
{
:
object
(
PYBIND11_BYTES_FROM_STRING_AND_SIZE
(
s
.
data
(),
(
ssize_t
)
s
.
size
()),
false
)
{
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate bytes object!"
);
}
...
...
@@ -380,7 +380,7 @@ public:
int
err
=
PYBIND11_BYTES_AS_STRING_AND_SIZE
(
m_ptr
,
&
buffer
,
&
length
);
if
(
err
==
-
1
)
pybind11_fail
(
"Unable to extract bytes contents!"
);
return
std
::
string
(
buffer
,
length
);
return
std
::
string
(
buffer
,
(
size_t
)
length
);
}
};
...
...
@@ -463,9 +463,12 @@ public:
m_ptr
=
PySlice_New
(
start
.
ptr
(),
stop
.
ptr
(),
step
.
ptr
());
if
(
!
m_ptr
)
pybind11_fail
(
"Could not allocate slice object!"
);
}
bool
compute
(
ssize_t
length
,
ssize_t
*
start
,
ssize_t
*
stop
,
ssize_t
*
step
,
ssize_t
*
slicelength
)
const
{
return
PySlice_GetIndicesEx
((
PYBIND11_SLICE_OBJECT
*
)
m_ptr
,
length
,
start
,
stop
,
step
,
slicelength
)
==
0
;
bool
compute
(
size_t
length
,
size_t
*
start
,
size_t
*
stop
,
size_t
*
step
,
size_t
*
slicelength
)
const
{
return
PySlice_GetIndicesEx
((
PYBIND11_SLICE_OBJECT
*
)
m_ptr
,
(
ssize_t
)
length
,
(
ssize_t
*
)
start
,
(
ssize_t
*
)
stop
,
(
ssize_t
*
)
step
,
(
ssize_t
*
)
slicelength
)
==
0
;
}
};
...
...
include/pybind11/stl_bind.h
View file @
3f3ea262
...
...
@@ -135,6 +135,7 @@ template <typename T, typename Allocator = std::allocator<T>, typename holder_ty
pybind11
::
class_
<
std
::
vector
<
T
,
Allocator
>
,
holder_type
>
bind_vector
(
pybind11
::
module
&
m
,
std
::
string
const
&
name
,
Args
&&
...
args
)
{
using
Vector
=
std
::
vector
<
T
,
Allocator
>
;
using
SizeType
=
typename
Vector
::
size_type
;
using
DiffType
=
typename
Vector
::
difference_type
;
using
Class_
=
pybind11
::
class_
<
Vector
,
holder_type
>
;
Class_
cl
(
m
,
name
.
c_str
(),
std
::
forward
<
Args
>
(
args
)...);
...
...
@@ -176,7 +177,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
cl
.
def
(
"insert"
,
[](
Vector
&
v
,
SizeType
i
,
const
T
&
x
)
{
v
.
insert
(
v
.
begin
()
+
i
,
x
);
v
.
insert
(
v
.
begin
()
+
(
DiffType
)
i
,
x
);
},
arg
(
"i"
)
,
arg
(
"x"
),
"Insert an item at a given position."
...
...
@@ -198,7 +199,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
if
(
i
>=
v
.
size
())
throw
pybind11
::
index_error
();
T
t
=
v
[
i
];
v
.
erase
(
v
.
begin
()
+
i
);
v
.
erase
(
v
.
begin
()
+
(
DiffType
)
i
);
return
t
;
},
arg
(
"i"
),
...
...
@@ -232,7 +233,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
[](
Vector
&
v
,
SizeType
i
)
{
if
(
i
>=
v
.
size
())
throw
pybind11
::
index_error
();
v
.
erase
(
v
.
begin
()
+
i
);
v
.
erase
(
v
.
begin
()
+
typename
Vector
::
difference_type
(
i
)
);
},
"Delete list elements using a slice object"
);
...
...
@@ -249,7 +250,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
/// Slicing protocol
cl
.
def
(
"__getitem__"
,
[](
const
Vector
&
v
,
slice
slice
)
->
Vector
*
{
s
s
ize_t
start
,
stop
,
step
,
slicelength
;
size_t
start
,
stop
,
step
,
slicelength
;
if
(
!
slice
.
compute
(
v
.
size
(),
&
start
,
&
stop
,
&
step
,
&
slicelength
))
throw
pybind11
::
error_already_set
();
...
...
@@ -257,7 +258,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
Vector
*
seq
=
new
Vector
();
seq
->
reserve
((
size_t
)
slicelength
);
for
(
in
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
for
(
size_
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
seq
->
push_back
(
v
[
start
]);
start
+=
step
;
}
...
...
@@ -269,14 +270,14 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
cl
.
def
(
"__setitem__"
,
[](
Vector
&
v
,
slice
slice
,
const
Vector
&
value
)
{
s
s
ize_t
start
,
stop
,
step
,
slicelength
;
size_t
start
,
stop
,
step
,
slicelength
;
if
(
!
slice
.
compute
(
v
.
size
(),
&
start
,
&
stop
,
&
step
,
&
slicelength
))
throw
pybind11
::
error_already_set
();
if
(
(
size_t
)
slicelength
!=
value
.
size
())
if
(
slicelength
!=
value
.
size
())
throw
std
::
runtime_error
(
"Left and right hand size of slice assignment have different sizes!"
);
for
(
in
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
for
(
size_
t
i
=
0
;
i
<
slicelength
;
++
i
)
{
v
[
start
]
=
value
[
i
];
start
+=
step
;
}
...
...
@@ -286,16 +287,16 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
cl
.
def
(
"__delitem__"
,
[](
Vector
&
v
,
slice
slice
)
{
s
s
ize_t
start
,
stop
,
step
,
slicelength
;
size_t
start
,
stop
,
step
,
slicelength
;
if
(
!
slice
.
compute
(
v
.
size
(),
&
start
,
&
stop
,
&
step
,
&
slicelength
))
throw
pybind11
::
error_already_set
();
if
(
step
==
1
&&
false
)
{
v
.
erase
(
v
.
begin
()
+
start
,
v
.
begin
()
+
start
+
slicelength
);
v
.
erase
(
v
.
begin
()
+
(
DiffType
)
start
,
v
.
begin
()
+
DiffType
(
start
+
slicelength
)
);
}
else
{
for
(
s
s
ize_t
i
=
0
;
i
<
slicelength
;
++
i
)
{
v
.
erase
(
v
.
begin
()
+
start
);
for
(
size_t
i
=
0
;
i
<
slicelength
;
++
i
)
{
v
.
erase
(
v
.
begin
()
+
DiffType
(
start
)
);
start
+=
step
-
1
;
}
}
...
...
tools/FindPythonLibsNew.cmake
0 → 100644
View file @
3f3ea262
# - Find python libraries
# This module finds the libraries corresponding to the Python interpeter
# FindPythonInterp provides.
# This code sets the following variables:
#
# PYTHONLIBS_FOUND - have the Python libs been found
# PYTHON_PREFIX - path to the Python installation
# PYTHON_LIBRARIES - path to the python library
# PYTHON_INCLUDE_DIRS - path to where Python.h is found
# PYTHON_SITE_PACKAGES - path to installation site-packages
# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
#
# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
#
# A function PYTHON_ADD_MODULE(<name> 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.
# Copyright 2012 Continuum Analytics, Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# Use the Python interpreter to find the libs.
if
(
PythonLibsNew_FIND_REQUIRED
)
find_package
(
PythonInterp
${
PythonLibsNew_FIND_VERSION
}
REQUIRED
)
else
()
find_package
(
PythonInterp
${
PythonLibsNew_FIND_VERSION
}
)
endif
()
if
(
NOT PYTHONINTERP_FOUND
)
set
(
PYTHONLIBS_FOUND FALSE
)
return
()
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(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
ERROR_VARIABLE _PYTHON_ERROR_VALUE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if
(
NOT _PYTHON_SUCCESS MATCHES 0
)
if
(
PythonLibsNew_FIND_REQUIRED
)
message
(
FATAL_ERROR
"Python config failure:
\n
${
_PYTHON_ERROR_VALUE
}
"
)
endif
()
set
(
PYTHONLIBS_FOUND FALSE
)
return
()
endif
()
# Convert the process output into a list
string
(
REGEX REPLACE
";"
"
\\\\
;"
_PYTHON_VALUES
${
_PYTHON_VALUES
}
)
string
(
REGEX REPLACE
"
\n
"
";"
_PYTHON_VALUES
${
_PYTHON_VALUES
}
)
list
(
GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST
)
list
(
GET _PYTHON_VALUES 1 PYTHON_PREFIX
)
list
(
GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR
)
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
# Skip if CMAKE_SIZEOF_VOID_P is not defined
if
(
CMAKE_SIZEOF_VOID_P
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"
)
message
(
FATAL_ERROR
"Python config failure: Python is
${
_PYTHON_BITS
}
-bit, "
"chosen compiler is
${
_CMAKE_BITS
}
-bit"
)
endif
()
set
(
PYTHONLIBS_FOUND FALSE
)
return
()
endif
()
# The built-in FindPython didn't always give the version numbers
string
(
REGEX REPLACE
"
\\
."
";"
_PYTHON_VERSION_LIST
${
_PYTHON_VERSION_LIST
}
)
list
(
GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR
)
list
(
GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR
)
list
(
GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH
)
# Make sure all directory separators are '/'
string
(
REGEX REPLACE
"
\\\\
"
"/"
PYTHON_PREFIX
${
PYTHON_PREFIX
}
)
string
(
REGEX REPLACE
"
\\\\
"
"/"
PYTHON_INCLUDE_DIR
${
PYTHON_INCLUDE_DIR
}
)
string
(
REGEX REPLACE
"
\\\\
"
"/"
PYTHON_SITE_PACKAGES
${
PYTHON_SITE_PACKAGES
}
)
# TODO: All the nuances of CPython debug builds have not been dealt with/tested.
if
(
PYTHON_IS_DEBUG
)
set
(
PYTHON_MODULE_EXTENSION
"_d
${
PYTHON_MODULE_EXTENSION
}
"
)
endif
()
if
(
CMAKE_HOST_WIN32
)
set
(
PYTHON_LIBRARY
"
${
PYTHON_PREFIX
}
/libs/Python
${
PYTHON_LIBRARY_SUFFIX
}
.lib"
)
elseif
(
APPLE
)
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_LIBRARY_SUFFIX
}
"
PATHS
${
_PYTHON_LIBS_SEARCH
}
NO_DEFAULT_PATH
)
# If all else fails, just set the name/version and let the linker figure out the path.
if
(
NOT PYTHON_LIBRARY
)
set
(
PYTHON_LIBRARY python
${
PYTHON_LIBRARY_SUFFIX
}
)
endif
()
endif
()
# For backward compatibility, set PYTHON_INCLUDE_PATH, but make it internal.
SET
(
PYTHON_INCLUDE_PATH
"
${
PYTHON_INCLUDE_DIR
}
"
CACHE INTERNAL
"Path to where Python.h is found (deprecated)"
)
MARK_AS_ADVANCED
(
PYTHON_LIBRARY
PYTHON_INCLUDE_DIR
)
# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
# cache entries because they are meant to specify the location of a single
# library. We now set the variables listed by the documentation for this
# module.
SET
(
PYTHON_INCLUDE_DIRS
"
${
PYTHON_INCLUDE_DIR
}
"
)
SET
(
PYTHON_LIBRARIES
"
${
PYTHON_LIBRARY
}
"
)
SET
(
PYTHON_DEBUG_LIBRARIES
"
${
PYTHON_DEBUG_LIBRARY
}
"
)
find_package_message
(
PYTHON
"Found PythonLibs:
${
PYTHON_LIBRARY
}
"
"
${
PYTHON_EXECUTABLE
}${
PYTHON_VERSION
}
"
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment