summaryrefslogtreecommitdiff
path: root/ext/pybind11/tools
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2017-02-27 13:17:51 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-05-02 12:37:32 +0000
commitc79706ff4ce591df2151db5504d3c224f3c9965f (patch)
treeb56cd2bfe704a40575a71075e78194a4c516c98d /ext/pybind11/tools
parent359cb08623324b62d7c34973ae54d5bc7f23f9fd (diff)
downloadgem5-c79706ff4ce591df2151db5504d3c224f3c9965f.tar.xz
ext: Add pybind rev f4b81b3
Change-Id: I52e4fc9ebf2f59da57d8cf8f3e37cc79598c2f5f Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Andreas Hansson <andreas.hansson@arm.com> Reviewed-by: Curtis Dunham <curtis.dunham@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2229 Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Pierre-Yves PĂ©neau <pierre-yves.peneau@lirmm.fr>
Diffstat (limited to 'ext/pybind11/tools')
-rw-r--r--ext/pybind11/tools/FindEigen3.cmake81
-rw-r--r--ext/pybind11/tools/FindPythonLibsNew.cmake194
-rwxr-xr-xext/pybind11/tools/check-style.sh83
-rw-r--r--ext/pybind11/tools/libsize.py38
-rw-r--r--ext/pybind11/tools/mkdoc.py309
-rw-r--r--ext/pybind11/tools/pybind11Config.cmake.in92
-rw-r--r--ext/pybind11/tools/pybind11Tools.cmake140
7 files changed, 937 insertions, 0 deletions
diff --git a/ext/pybind11/tools/FindEigen3.cmake b/ext/pybind11/tools/FindEigen3.cmake
new file mode 100644
index 000000000..9c546a05d
--- /dev/null
+++ b/ext/pybind11/tools/FindEigen3.cmake
@@ -0,0 +1,81 @@
+# - Try to find Eigen3 lib
+#
+# This module supports requiring a minimum version, e.g. you can do
+# find_package(Eigen3 3.1.2)
+# to require version 3.1.2 or newer of Eigen3.
+#
+# Once done this will define
+#
+# EIGEN3_FOUND - system has eigen lib with correct version
+# EIGEN3_INCLUDE_DIR - the eigen include directory
+# EIGEN3_VERSION - eigen version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
+
+if(NOT Eigen3_FIND_VERSION)
+ if(NOT Eigen3_FIND_VERSION_MAJOR)
+ set(Eigen3_FIND_VERSION_MAJOR 2)
+ endif(NOT Eigen3_FIND_VERSION_MAJOR)
+ if(NOT Eigen3_FIND_VERSION_MINOR)
+ set(Eigen3_FIND_VERSION_MINOR 91)
+ endif(NOT Eigen3_FIND_VERSION_MINOR)
+ if(NOT Eigen3_FIND_VERSION_PATCH)
+ set(Eigen3_FIND_VERSION_PATCH 0)
+ endif(NOT Eigen3_FIND_VERSION_PATCH)
+
+ set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
+endif(NOT Eigen3_FIND_VERSION)
+
+macro(_eigen3_check_version)
+ file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+
+ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
+ set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
+
+ set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
+ if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+ set(EIGEN3_VERSION_OK FALSE)
+ else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+ set(EIGEN3_VERSION_OK TRUE)
+ endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+
+ if(NOT EIGEN3_VERSION_OK)
+
+ message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
+ "but at least version ${Eigen3_FIND_VERSION} is required")
+ endif(NOT EIGEN3_VERSION_OK)
+endmacro(_eigen3_check_version)
+
+if (EIGEN3_INCLUDE_DIR)
+
+ # in cache already
+ _eigen3_check_version()
+ set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
+
+else (EIGEN3_INCLUDE_DIR)
+
+ find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
+ PATHS
+ ${CMAKE_INSTALL_PREFIX}/include
+ ${KDE4_INCLUDE_DIR}
+ PATH_SUFFIXES eigen3 eigen
+ )
+
+ if(EIGEN3_INCLUDE_DIR)
+ _eigen3_check_version()
+ endif(EIGEN3_INCLUDE_DIR)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
+
+ mark_as_advanced(EIGEN3_INCLUDE_DIR)
+
+endif(EIGEN3_INCLUDE_DIR)
+
diff --git a/ext/pybind11/tools/FindPythonLibsNew.cmake b/ext/pybind11/tools/FindPythonLibsNew.cmake
new file mode 100644
index 000000000..dc44a9df5
--- /dev/null
+++ b/ext/pybind11/tools/FindPythonLibsNew.cmake
@@ -0,0 +1,194 @@
+# - 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_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd'
+# PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string
+# PYTHON_SITE_PACKAGES - path to installation site-packages
+# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
+#
+# 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.
+#=============================================================================
+
+if(PYTHONLIBS_FOUND)
+ return()
+endif()
+
+# 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'));
+print(s.get_config_var('LIBDIR') or '');
+print(s.get_config_var('MULTIARCH') or '');
+"
+ RESULT_VARIABLE _PYTHON_SUCCESS
+ OUTPUT_VARIABLE _PYTHON_VALUES
+ ERROR_VARIABLE _PYTHON_ERROR_VALUE)
+
+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)
+list(GET _PYTHON_VALUES 8 PYTHON_LIBDIR)
+list(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH)
+
+# 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})
+
+if(CMAKE_HOST_WIN32)
+ set(PYTHON_LIBRARY
+ "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
+
+ # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
+ # original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
+ if(NOT EXISTS "${PYTHON_LIBRARY}")
+ get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
+ set(PYTHON_LIBRARY
+ "${_PYTHON_ROOT}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
+ endif()
+
+ # raise an error if the python libs are still not found.
+ if(NOT EXISTS "${PYTHON_LIBRARY}")
+ message(FATAL_ERROR "Python libraries not found")
+ endif()
+
+else()
+ if(PYTHON_MULTIARCH)
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}")
+ else()
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}")
+ 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()
+
+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}")
+
+set(PYTHONLIBS_FOUND TRUE)
diff --git a/ext/pybind11/tools/check-style.sh b/ext/pybind11/tools/check-style.sh
new file mode 100755
index 000000000..b87cb16e6
--- /dev/null
+++ b/ext/pybind11/tools/check-style.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# Script to check include/test code for common pybind11 code style errors.
+#
+# This script currently checks for
+#
+# 1. use of tabs instead of spaces
+# 2. MSDOS-style CRLF endings
+# 3. trailing spaces
+# 4. missing space between keyword and parenthesis, e.g.: for(, if(, while(
+# 5. Missing space between right parenthesis and brace, e.g. 'for (...){'
+# 6. opening brace on its own line. It should always be on the same line as the
+# if/while/for/do statment.
+#
+# Invoke as: tools/check-style.sh
+#
+
+errors=0
+IFS=$'\n'
+found=
+# The mt=41 sets a red background for matched tabs:
+exec 3< <(GREP_COLORS='mt=41' grep $'\t' include/ tests/*.{cpp,py,h} docs/*.rst -rn --color=always)
+while read -u 3 f; do
+ if [ -z "$found" ]; then
+ echo -e '\e[31m\e[01mError: found tabs instead of spaces in the following files:\e[0m'
+ found=1
+ errors=1
+ fi
+
+ echo " $f"
+done
+
+found=
+# The mt=41 sets a red background for matched MS-DOS CRLF line endings
+exec 3< <(GREP_COLORS='mt=41' grep -IUlr $'\r' include/ tests/*.{cpp,py,h} docs/*.rst --color=always)
+while read -u 3 f; do
+ if [ -z "$found" ]; then
+ echo -e '\e[31m\e[01mError: found CRLF characters in the following files:\e[0m'
+ found=1
+ errors=1
+ fi
+
+ echo " $f"
+done
+
+found=
+# The mt=41 sets a red background for matched trailing spaces
+exec 3< <(GREP_COLORS='mt=41' grep '\s\+$' include/ tests/*.{cpp,py,h} docs/*.rst -rn --color=always)
+while read -u 3 f; do
+ if [ -z "$found" ]; then
+ echo -e '\e[31m\e[01mError: found trailing spaces in the following files:\e[0m'
+ found=1
+ errors=1
+ fi
+
+ echo " $f"
+done
+
+found=
+exec 3< <(grep '\<\(if\|for\|while\|catch\)(\|){' include/ tests/*.{cpp,py,h} -rn --color=always)
+while read -u 3 line; do
+ if [ -z "$found" ]; then
+ echo -e '\e[31m\e[01mError: found the following coding style problems:\e[0m'
+ found=1
+ errors=1
+ fi
+
+ echo " $line"
+done
+
+found=
+exec 3< <(GREP_COLORS='mt=41' grep '^\s*{\s*$' include/ docs/*.rst -rn --color=always)
+while read -u 3 f; do
+ if [ -z "$found" ]; then
+ echo -e '\e[31m\e[01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files: \e[0m'
+ found=1
+ errors=1
+ fi
+
+ echo " $f"
+done
+
+exit $errors
diff --git a/ext/pybind11/tools/libsize.py b/ext/pybind11/tools/libsize.py
new file mode 100644
index 000000000..5dcb8b0d0
--- /dev/null
+++ b/ext/pybind11/tools/libsize.py
@@ -0,0 +1,38 @@
+from __future__ import print_function, division
+import os
+import sys
+
+# Internal build script for generating debugging test .so size.
+# Usage:
+# python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the
+# size in it, then overwrites save.txt with the new size for future runs.
+
+if len(sys.argv) != 3:
+ sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt")
+
+lib = sys.argv[1]
+save = sys.argv[2]
+
+if not os.path.exists(lib):
+ sys.exit("Error: requested file ({}) does not exist".format(lib))
+
+libsize = os.path.getsize(lib)
+
+print("------", os.path.basename(lib), "file size:", libsize, end='')
+
+if os.path.exists(save):
+ with open(save) as sf:
+ oldsize = int(sf.readline())
+
+ if oldsize > 0:
+ change = libsize - oldsize
+ if change == 0:
+ print(" (no change)")
+ else:
+ print(" (change of {:+} bytes = {:+.2%})".format(change, change / oldsize))
+else:
+ print()
+
+with open(save, 'w') as sf:
+ sf.write(str(libsize))
+
diff --git a/ext/pybind11/tools/mkdoc.py b/ext/pybind11/tools/mkdoc.py
new file mode 100644
index 000000000..400fb05da
--- /dev/null
+++ b/ext/pybind11/tools/mkdoc.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python3
+#
+# Syntax: mkdoc.py [-I<path> ..] [.. a list of header files ..]
+#
+# Extract documentation from C++ header files to use it in Python bindings
+#
+
+import os
+import sys
+import platform
+import re
+import textwrap
+
+from clang import cindex
+from clang.cindex import CursorKind
+from collections import OrderedDict
+from threading import Thread, Semaphore
+from multiprocessing import cpu_count
+
+RECURSE_LIST = [
+ CursorKind.TRANSLATION_UNIT,
+ CursorKind.NAMESPACE,
+ CursorKind.CLASS_DECL,
+ CursorKind.STRUCT_DECL,
+ CursorKind.ENUM_DECL,
+ CursorKind.CLASS_TEMPLATE
+]
+
+PRINT_LIST = [
+ CursorKind.CLASS_DECL,
+ CursorKind.STRUCT_DECL,
+ CursorKind.ENUM_DECL,
+ CursorKind.ENUM_CONSTANT_DECL,
+ CursorKind.CLASS_TEMPLATE,
+ CursorKind.FUNCTION_DECL,
+ CursorKind.FUNCTION_TEMPLATE,
+ CursorKind.CONVERSION_FUNCTION,
+ CursorKind.CXX_METHOD,
+ CursorKind.CONSTRUCTOR,
+ CursorKind.FIELD_DECL
+]
+
+CPP_OPERATORS = {
+ '<=': 'le', '>=': 'ge', '==': 'eq', '!=': 'ne', '[]': 'array',
+ '+=': 'iadd', '-=': 'isub', '*=': 'imul', '/=': 'idiv', '%=':
+ 'imod', '&=': 'iand', '|=': 'ior', '^=': 'ixor', '<<=': 'ilshift',
+ '>>=': 'irshift', '++': 'inc', '--': 'dec', '<<': 'lshift', '>>':
+ 'rshift', '&&': 'land', '||': 'lor', '!': 'lnot', '~': 'bnot',
+ '&': 'band', '|': 'bor', '+': 'add', '-': 'sub', '*': 'mul', '/':
+ 'div', '%': 'mod', '<': 'lt', '>': 'gt', '=': 'assign', '()': 'call'
+}
+
+CPP_OPERATORS = OrderedDict(
+ sorted(CPP_OPERATORS.items(), key=lambda t: -len(t[0])))
+
+job_count = cpu_count()
+job_semaphore = Semaphore(job_count)
+
+registered_names = dict()
+
+
+def d(s):
+ return s.decode('utf8')
+
+
+def sanitize_name(name):
+ global registered_names
+ name = re.sub(r'type-parameter-0-([0-9]+)', r'T\1', name)
+ for k, v in CPP_OPERATORS.items():
+ name = name.replace('operator%s' % k, 'operator_%s' % v)
+ name = re.sub('<.*>', '', name)
+ name = ''.join([ch if ch.isalnum() else '_' for ch in name])
+ name = re.sub('_$', '', re.sub('_+', '_', name))
+ if name in registered_names:
+ registered_names[name] += 1
+ name += '_' + str(registered_names[name])
+ else:
+ registered_names[name] = 1
+ return '__doc_' + name
+
+
+def process_comment(comment):
+ result = ''
+
+ # Remove C++ comment syntax
+ leading_spaces = float('inf')
+ for s in comment.expandtabs(tabsize=4).splitlines():
+ s = s.strip()
+ if s.startswith('/*'):
+ s = s[2:].lstrip('*')
+ elif s.endswith('*/'):
+ s = s[:-2].rstrip('*')
+ elif s.startswith('///'):
+ s = s[3:]
+ if s.startswith('*'):
+ s = s[1:]
+ if len(s) > 0:
+ leading_spaces = min(leading_spaces, len(s) - len(s.lstrip()))
+ result += s + '\n'
+
+ if leading_spaces != float('inf'):
+ result2 = ""
+ for s in result.splitlines():
+ result2 += s[leading_spaces:] + '\n'
+ result = result2
+
+ # Doxygen tags
+ cpp_group = '([\w:]+)'
+ param_group = '([\[\w:\]]+)'
+
+ s = result
+ s = re.sub(r'\\c\s+%s' % cpp_group, r'``\1``', s)
+ s = re.sub(r'\\a\s+%s' % cpp_group, r'*\1*', s)
+ s = re.sub(r'\\e\s+%s' % cpp_group, r'*\1*', s)
+ s = re.sub(r'\\em\s+%s' % cpp_group, r'*\1*', s)
+ s = re.sub(r'\\b\s+%s' % cpp_group, r'**\1**', s)
+ s = re.sub(r'\\ingroup\s+%s' % cpp_group, r'', s)
+ s = re.sub(r'\\param%s?\s+%s' % (param_group, cpp_group),
+ r'\n\n$Parameter ``\2``:\n\n', s)
+ s = re.sub(r'\\tparam%s?\s+%s' % (param_group, cpp_group),
+ r'\n\n$Template parameter ``\2``:\n\n', s)
+
+ for in_, out_ in {
+ 'return': 'Returns',
+ 'author': 'Author',
+ 'authors': 'Authors',
+ 'copyright': 'Copyright',
+ 'date': 'Date',
+ 'remark': 'Remark',
+ 'sa': 'See also',
+ 'see': 'See also',
+ 'extends': 'Extends',
+ 'throw': 'Throws',
+ 'throws': 'Throws'
+ }.items():
+ s = re.sub(r'\\%s\s*' % in_, r'\n\n$%s:\n\n' % out_, s)
+
+ s = re.sub(r'\\details\s*', r'\n\n', s)
+ s = re.sub(r'\\brief\s*', r'', s)
+ s = re.sub(r'\\short\s*', r'', s)
+ s = re.sub(r'\\ref\s*', r'', s)
+
+ s = re.sub(r'\\code\s?(.*?)\s?\\endcode',
+ r"```\n\1\n```\n", s, flags=re.DOTALL)
+
+ # HTML/TeX tags
+ s = re.sub(r'<tt>(.*?)</tt>', r'``\1``', s, flags=re.DOTALL)
+ s = re.sub(r'<pre>(.*?)</pre>', r"```\n\1\n```\n", s, flags=re.DOTALL)
+ s = re.sub(r'<em>(.*?)</em>', r'*\1*', s, flags=re.DOTALL)
+ s = re.sub(r'<b>(.*?)</b>', r'**\1**', s, flags=re.DOTALL)
+ s = re.sub(r'\\f\$(.*?)\\f\$', r'$\1$', s, flags=re.DOTALL)
+ s = re.sub(r'<li>', r'\n\n* ', s)
+ s = re.sub(r'</?ul>', r'', s)
+ s = re.sub(r'</li>', r'\n\n', s)
+
+ s = s.replace('``true``', '``True``')
+ s = s.replace('``false``', '``False``')
+
+ # Re-flow text
+ wrapper = textwrap.TextWrapper()
+ wrapper.expand_tabs = True
+ wrapper.replace_whitespace = True
+ wrapper.drop_whitespace = True
+ wrapper.width = 70
+ wrapper.initial_indent = wrapper.subsequent_indent = ''
+
+ result = ''
+ in_code_segment = False
+ for x in re.split(r'(```)', s):
+ if x == '```':
+ if not in_code_segment:
+ result += '```\n'
+ else:
+ result += '\n```\n\n'
+ in_code_segment = not in_code_segment
+ elif in_code_segment:
+ result += x.strip()
+ else:
+ for y in re.split(r'(?: *\n *){2,}', x):
+ wrapped = wrapper.fill(re.sub(r'\s+', ' ', y).strip())
+ if len(wrapped) > 0 and wrapped[0] == '$':
+ result += wrapped[1:] + '\n'
+ wrapper.initial_indent = \
+ wrapper.subsequent_indent = ' ' * 4
+ else:
+ if len(wrapped) > 0:
+ result += wrapped + '\n\n'
+ wrapper.initial_indent = wrapper.subsequent_indent = ''
+ return result.rstrip().lstrip('\n')
+
+
+def extract(filename, node, prefix, output):
+ num_extracted = 0
+ if not (node.location.file is None or
+ os.path.samefile(d(node.location.file.name), filename)):
+ return 0
+ if node.kind in RECURSE_LIST:
+ sub_prefix = prefix
+ if node.kind != CursorKind.TRANSLATION_UNIT:
+ if len(sub_prefix) > 0:
+ sub_prefix += '_'
+ sub_prefix += d(node.spelling)
+ for i in node.get_children():
+ num_extracted += extract(filename, i, sub_prefix, output)
+ if num_extracted == 0:
+ return 0
+ if node.kind in PRINT_LIST:
+ comment = d(node.raw_comment) if node.raw_comment is not None else ''
+ comment = process_comment(comment)
+ sub_prefix = prefix
+ if len(sub_prefix) > 0:
+ sub_prefix += '_'
+ if len(node.spelling) > 0:
+ name = sanitize_name(sub_prefix + d(node.spelling))
+ output.append('\nstatic const char *%s =%sR"doc(%s)doc";' %
+ (name, '\n' if '\n' in comment else ' ', comment))
+ num_extracted += 1
+ return num_extracted
+
+
+class ExtractionThread(Thread):
+ def __init__(self, filename, parameters, output):
+ Thread.__init__(self)
+ self.filename = filename
+ self.parameters = parameters
+ self.output = output
+ job_semaphore.acquire()
+
+ def run(self):
+ print('Processing "%s" ..' % self.filename, file=sys.stderr)
+ try:
+ index = cindex.Index(
+ cindex.conf.lib.clang_createIndex(False, True))
+ tu = index.parse(self.filename, self.parameters)
+ extract(self.filename, tu.cursor, '', self.output)
+ finally:
+ job_semaphore.release()
+
+if __name__ == '__main__':
+ parameters = ['-x', 'c++', '-std=c++11']
+ filenames = []
+
+ if platform.system() == 'Darwin':
+ dev_path = '/Applications/Xcode.app/Contents/Developer/'
+ lib_dir = dev_path + 'Toolchains/XcodeDefault.xctoolchain/usr/lib/'
+ sdk_dir = dev_path + 'Platforms/MacOSX.platform/Developer/SDKs'
+ libclang = lib_dir + 'libclang.dylib'
+
+ if os.path.exists(libclang):
+ cindex.Config.set_library_path(os.path.dirname(libclang))
+
+ if os.path.exists(sdk_dir):
+ sysroot_dir = os.path.join(sdk_dir, next(os.walk(sdk_dir))[1][0])
+ parameters.append('-isysroot')
+ parameters.append(sysroot_dir)
+
+ for item in sys.argv[1:]:
+ if item.startswith('-'):
+ parameters.append(item)
+ else:
+ filenames.append(item)
+
+ if len(filenames) == 0:
+ print('Syntax: %s [.. a list of header files ..]' % sys.argv[0])
+ exit(-1)
+
+ print('''/*
+ This file contains docstrings for the Python bindings.
+ Do not edit! These were automatically extracted by mkdoc.py
+ */
+
+#define __EXPAND(x) x
+#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT
+#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1))
+#define __CAT1(a, b) a ## b
+#define __CAT2(a, b) __CAT1(a, b)
+#define __DOC1(n1) __doc_##n1
+#define __DOC2(n1, n2) __doc_##n1##_##n2
+#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3
+#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4
+#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5
+#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6
+#define __DOC7(n1, n2, n3, n4, n5, n6, n7) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7
+#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__))
+
+#if defined(__GNUG__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+''')
+
+ output = []
+ for filename in filenames:
+ thr = ExtractionThread(filename, parameters, output)
+ thr.start()
+
+ print('Waiting for jobs to finish ..', file=sys.stderr)
+ for i in range(job_count):
+ job_semaphore.acquire()
+
+ output.sort()
+ for l in output:
+ print(l)
+
+ print('''
+#if defined(__GNUG__)
+#pragma GCC diagnostic pop
+#endif
+''')
diff --git a/ext/pybind11/tools/pybind11Config.cmake.in b/ext/pybind11/tools/pybind11Config.cmake.in
new file mode 100644
index 000000000..23588c300
--- /dev/null
+++ b/ext/pybind11/tools/pybind11Config.cmake.in
@@ -0,0 +1,92 @@
+# pybind11Config.cmake
+# --------------------
+#
+# PYBIND11 cmake module.
+# This module sets the following variables in your project::
+#
+# pybind11_FOUND - true if pybind11 and all required components found on the system
+# pybind11_VERSION - pybind11 version in format Major.Minor.Release
+# pybind11_INCLUDE_DIRS - Directories where pybind11 and python headers are located.
+# pybind11_INCLUDE_DIR - Directory where pybind11 headers are located.
+# pybind11_DEFINITIONS - Definitions necessary to use pybind11, namely USING_pybind11.
+# pybind11_LIBRARIES - compile flags and python libraries (as needed) to link against.
+# pybind11_LIBRARY - empty.
+# CMAKE_MODULE_PATH - appends location of accompanying FindPythonLibsNew.cmake and
+# pybind11Tools.cmake modules.
+#
+#
+# Available components: None
+#
+#
+# Exported targets::
+#
+# If pybind11 is found, this module defines the following :prop_tgt:`IMPORTED`
+# target. Python headers, libraries (as needed by platform), and C++ standard
+# are attached to the target. Set PythonLibsNew variables to influence
+# python detection and PYBIND11_CPP_STANDARD (-std=c++11 or -std=c++14) to
+# influence standard setting. ::
+#
+# pybind11::pybind11 - the main pybind11 interface library (i.e., headers)
+#
+# find_package(pybind11 CONFIG REQUIRED)
+# message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIR} (found version ${pybind11_VERSION} & Py${PYTHON_VERSION_STRING})")
+# add_library(mylib MODULE main.cpp)
+# target_link_libraries(mylib pybind11::pybind11)
+#
+# Suggested usage::
+#
+# find_package with version info is not recommended except for release versions. ::
+#
+# find_package(pybind11 CONFIG)
+# find_package(pybind11 2.0 EXACT CONFIG REQUIRED)
+#
+#
+# The following variables can be set to guide the search for this package::
+#
+# pybind11_DIR - CMake variable, set to directory containing this Config file
+# CMAKE_PREFIX_PATH - CMake variable, set to root directory of this package
+# PATH - environment variable, set to bin directory of this package
+# CMAKE_DISABLE_FIND_PACKAGE_pybind11 - CMake variable, disables
+# find_package(pybind11) when not REQUIRED, perhaps to force internal build
+
+@PACKAGE_INIT@
+
+set(PN pybind11)
+
+# location of pybind11/pybind11.h
+set(${PN}_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
+
+set(${PN}_LIBRARY "")
+set(${PN}_DEFINITIONS USING_${PN})
+
+check_required_components(${PN})
+
+# make detectable the FindPythonLibsNew.cmake module
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+include(pybind11Tools)
+
+if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
+#-----------------------------------------------------------------------------
+# Don't include targets if this file is being picked up by another
+# project which has already built this as a subproject
+#-----------------------------------------------------------------------------
+if(NOT TARGET ${PN}::pybind11)
+ include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake")
+
+ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
+ set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
+ if(WIN32 OR CYGWIN)
+ set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
+ endif()
+
+ select_cxx_standard()
+ set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
+
+ get_property(_iid TARGET ${PN}::pybind11 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+ get_property(_ill TARGET ${PN}::pybind11 PROPERTY INTERFACE_LINK_LIBRARIES)
+ get_property(_ico TARGET ${PN}::pybind11 PROPERTY INTERFACE_COMPILE_OPTIONS)
+ set(${PN}_INCLUDE_DIRS ${_iid})
+ set(${PN}_LIBRARIES ${_ico} ${_ill})
+endif()
+endif()
diff --git a/ext/pybind11/tools/pybind11Tools.cmake b/ext/pybind11/tools/pybind11Tools.cmake
new file mode 100644
index 000000000..4922982fa
--- /dev/null
+++ b/ext/pybind11/tools/pybind11Tools.cmake
@@ -0,0 +1,140 @@
+# tools/pybind11Tools.cmake -- Build system for the pybind11 modules
+#
+# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
+#
+# All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+cmake_minimum_required(VERSION 2.8.12)
+
+# Add a CMake parameter for choosing a desired Python version
+set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
+
+set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
+find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
+
+include(CheckCXXCompilerFlag)
+
+function(select_cxx_standard)
+ if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD)
+ 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(PYBIND11_CPP_STANDARD -std=c++14)
+ elseif (HAS_CPP11_FLAG)
+ set(PYBIND11_CPP_STANDARD -std=c++11)
+ else()
+ message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
+ endif()
+
+ set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
+ "C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available." FORCE)
+ endif()
+endfunction()
+
+# Build a Python extension module:
+# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] source1 [source2 ...])
+#
+function(pybind11_add_module target_name)
+ set(lib_type "MODULE")
+ set(do_lto True)
+ set(exclude_from_all "")
+ set(sources "")
+
+ set(_args_to_try "${ARGN}")
+ foreach(_ex_arg IN LISTS _args_to_try)
+ if(${_ex_arg} STREQUAL "MODULE")
+ set(lib_type "MODULE")
+ elseif(${_ex_arg} STREQUAL "SHARED")
+ set(lib_type "SHARED")
+ elseif(${_ex_arg} STREQUAL "EXCLUDE_FROM_ALL")
+ set(exclude_from_all "EXCLUDE_FROM_ALL")
+ else()
+ list(APPEND sources "${_ex_arg}")
+ endif()
+ endforeach()
+
+ add_library(${target_name} ${lib_type} ${exclude_from_all} ${sources})
+
+ target_include_directories(${target_name}
+ PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt
+ PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config
+ PRIVATE ${PYTHON_INCLUDE_DIRS})
+
+ # The prefix and extension are provided by FindPythonLibsNew.cmake
+ set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
+ set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
+
+ if(WIN32 OR CYGWIN)
+ # Link against the Python shared library on Windows
+ target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
+ elseif(APPLE)
+ # 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.
+
+ target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
+ endif()
+
+ select_cxx_standard()
+ if(NOT MSVC)
+ # Make sure C++11/14 are enabled
+ target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
+
+ # Enable link time optimization and set the default symbol
+ # visibility to hidden (very important to obtain small binaries)
+ string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
+ if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
+ # Check for Link Time Optimization support (GCC/Clang)
+ check_cxx_compiler_flag("-flto" HAS_LTO_FLAG)
+ if(HAS_LTO_FLAG AND NOT CYGWIN)
+ target_compile_options(${target_name} PRIVATE -flto)
+ endif()
+
+ # Intel equivalent to LTO is called IPO
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+ check_cxx_compiler_flag("-ipo" HAS_IPO_FLAG)
+ if(HAS_IPO_FLAG)
+ target_compile_options(${target_name} PRIVATE -ipo)
+ endif()
+ endif()
+
+ # Default symbol visibility
+ target_compile_options(${target_name} PRIVATE "-fvisibility=hidden")
+
+ # Strip unnecessary sections of the binary on Linux/Mac OS
+ if(CMAKE_STRIP)
+ if(APPLE)
+ add_custom_command(TARGET ${target_name} POST_BUILD
+ COMMAND ${CMAKE_STRIP} -u -r $<TARGET_FILE:${target_name}>)
+ else()
+ add_custom_command(TARGET ${target_name} POST_BUILD
+ COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>)
+ endif()
+ endif()
+ endif()
+ elseif(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
+ target_compile_options(${target_name} PRIVATE /MP /bigobj)
+
+ # Enforce link time code generation on MSVC, except in debug mode
+ target_compile_options(${target_name} PRIVATE $<$<NOT:$<CONFIG:Debug>>:/GL>)
+
+ # Fancy generator expressions don't work with linker flags, for reasons unknown
+ set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE /LTCG)
+ set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL /LTCG)
+ set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO /LTCG)
+ endif()
+endfunction()