summaryrefslogtreecommitdiff
path: root/ext/pybind11/tools
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pybind11/tools')
-rw-r--r--ext/pybind11/tools/FindCatch.cmake57
-rw-r--r--ext/pybind11/tools/FindPythonLibsNew.cmake3
-rwxr-xr-xext/pybind11/tools/check-style.sh109
-rw-r--r--ext/pybind11/tools/mkdoc.py45
-rw-r--r--ext/pybind11/tools/pybind11Config.cmake.in28
-rw-r--r--ext/pybind11/tools/pybind11Tools.cmake41
6 files changed, 168 insertions, 115 deletions
diff --git a/ext/pybind11/tools/FindCatch.cmake b/ext/pybind11/tools/FindCatch.cmake
new file mode 100644
index 000000000..9d490c5aa
--- /dev/null
+++ b/ext/pybind11/tools/FindCatch.cmake
@@ -0,0 +1,57 @@
+# - Find the Catch test framework or download it (single header)
+#
+# This is a quick module for internal use. It assumes that Catch is
+# REQUIRED and that a minimum version is provided (not EXACT). If
+# a suitable version isn't found locally, the single header file
+# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR.
+#
+# This code sets the following variables:
+# CATCH_INCLUDE_DIR - path to catch.hpp
+# CATCH_VERSION - version number
+
+if(NOT Catch_FIND_VERSION)
+ message(FATAL_ERROR "A version number must be specified.")
+elseif(Catch_FIND_REQUIRED)
+ message(FATAL_ERROR "This module assumes Catch is not required.")
+elseif(Catch_FIND_VERSION_EXACT)
+ message(FATAL_ERROR "Exact version numbers are not supported, only minimum.")
+endif()
+
+# Extract the version number from catch.hpp
+function(_get_catch_version)
+ file(STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line REGEX "Catch v.*" LIMIT_COUNT 1)
+ if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)")
+ set(CATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Download the single-header version of Catch
+function(_download_catch version destination_dir)
+ message(STATUS "Downloading catch v${version}...")
+ set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)
+ file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status)
+ list(GET status 0 error)
+ if(error)
+ message(FATAL_ERROR "Could not download ${url}")
+ endif()
+ set(CATCH_INCLUDE_DIR "${destination_dir}" CACHE INTERNAL "")
+endfunction()
+
+# Look for catch locally
+find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch)
+if(CATCH_INCLUDE_DIR)
+ _get_catch_version()
+endif()
+
+# Download the header if it wasn't found or if it's outdated
+if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})
+ if(DOWNLOAD_CATCH)
+ _download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/")
+ _get_catch_version()
+ else()
+ set(CATCH_FOUND FALSE)
+ return()
+ endif()
+endif()
+
+set(CATCH_FOUND TRUE)
diff --git a/ext/pybind11/tools/FindPythonLibsNew.cmake b/ext/pybind11/tools/FindPythonLibsNew.cmake
index dc44a9df5..ad3ed48fa 100644
--- a/ext/pybind11/tools/FindPythonLibsNew.cmake
+++ b/ext/pybind11/tools/FindPythonLibsNew.cmake
@@ -50,7 +50,8 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
-if(PYTHONLIBS_FOUND)
+# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`.
+if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)
return()
endif()
diff --git a/ext/pybind11/tools/check-style.sh b/ext/pybind11/tools/check-style.sh
index b87cb16e6..a9eeb170b 100755
--- a/ext/pybind11/tools/check-style.sh
+++ b/ext/pybind11/tools/check-style.sh
@@ -1,7 +1,7 @@
#!/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
@@ -11,73 +11,60 @@
# 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
+check_style_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
+found="$( GREP_COLORS='mt=41' GREP_COLOR='41' grep $'\t' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )"
+if [ -n "$found" ]; then
+ # The mt=41 sets a red background for matched tabs:
+ echo -e '\033[31;01mError: found tab characters in the following files:\033[0m'
+ check_style_errors=1
+ echo "$found" | sed -e 's/^/ /'
+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
+found="$( grep -IUlr $'\r' include tests/*.{cpp,py,h} docs/*.rst --color=always )"
+if [ -n "$found" ]; then
+ echo -e '\033[31;01mError: found CRLF characters in the following files:\033[0m'
+ check_style_errors=1
+ echo "$found" | sed -e 's/^/ /'
+fi
- echo " $line"
-done
+found="$(GREP_COLORS='mt=41' GREP_COLOR='41' grep '[[:blank:]]\+$' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )"
+if [ -n "$found" ]; then
+ # The mt=41 sets a red background for matched trailing spaces
+ echo -e '\033[31;01mError: found trailing spaces in the following files:\033[0m'
+ check_style_errors=1
+ echo "$found" | sed -e 's/^/ /'
+fi
-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
+found="$(grep '\<\(if\|for\|while\|catch\)(\|){' include tests/*.{cpp,h} -rn --color=always)"
+if [ -n "$found" ]; then
+ echo -e '\033[31;01mError: found the following coding style problems:\033[0m'
+ check_style_errors=1
+ echo "$found" | sed -e 's/^/ /'
+fi
- echo " $f"
-done
+found="$(awk '
+function prefix(filename, lineno) {
+ return " \033[35m" filename "\033[36m:\033[32m" lineno "\033[36m:\033[0m"
+}
+function mark(pattern, string) { sub(pattern, "\033[01;31m&\033[0m", string); return string }
+last && /^\s*{/ {
+ print prefix(FILENAME, FNR-1) mark("\\)\\s*$", last)
+ print prefix(FILENAME, FNR) mark("^\\s*{", $0)
+ last=""
+}
+{ last = /(if|for|while|catch|switch)\s*\(.*\)\s*$/ ? $0 : "" }
+' $(find include -type f) tests/*.{cpp,h} docs/*.rst)"
+if [ -n "$found" ]; then
+ check_style_errors=1
+ echo -e '\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\033[0m'
+ echo "$found"
+fi
-exit $errors
+exit $check_style_errors
diff --git a/ext/pybind11/tools/mkdoc.py b/ext/pybind11/tools/mkdoc.py
index 400fb05da..1fd8cceed 100644
--- a/ext/pybind11/tools/mkdoc.py
+++ b/ext/pybind11/tools/mkdoc.py
@@ -56,26 +56,19 @@ CPP_OPERATORS = OrderedDict(
job_count = cpu_count()
job_semaphore = Semaphore(job_count)
-registered_names = dict()
-
+output = []
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
@@ -189,8 +182,7 @@ def process_comment(comment):
return result.rstrip().lstrip('\n')
-def extract(filename, node, prefix, output):
- num_extracted = 0
+def extract(filename, node, prefix):
if not (node.location.file is None or
os.path.samefile(d(node.location.file.name), filename)):
return 0
@@ -201,9 +193,7 @@ def extract(filename, node, prefix, output):
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
+ extract(filename, i, sub_prefix)
if node.kind in PRINT_LIST:
comment = d(node.raw_comment) if node.raw_comment is not None else ''
comment = process_comment(comment)
@@ -212,18 +202,15 @@ def extract(filename, node, prefix, output):
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
+ global output
+ output.append((name, filename, comment))
class ExtractionThread(Thread):
- def __init__(self, filename, parameters, output):
+ def __init__(self, filename, parameters):
Thread.__init__(self)
self.filename = filename
self.parameters = parameters
- self.output = output
job_semaphore.acquire()
def run(self):
@@ -232,7 +219,7 @@ class ExtractionThread(Thread):
index = cindex.Index(
cindex.conf.lib.clang_createIndex(False, True))
tu = index.parse(self.filename, self.parameters)
- extract(self.filename, tu.cursor, '', self.output)
+ extract(self.filename, tu.cursor, '')
finally:
job_semaphore.release()
@@ -289,18 +276,26 @@ if __name__ == '__main__':
#endif
''')
- output = []
+ output.clear()
for filename in filenames:
- thr = ExtractionThread(filename, parameters, output)
+ thr = ExtractionThread(filename, parameters)
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)
+ name_ctr = 1
+ name_prev = None
+ for name, _, comment in list(sorted(output, key=lambda x: (x[0], x[1]))):
+ if name == name_prev:
+ name_ctr += 1
+ name = name + "_%i" % name_ctr
+ else:
+ name_prev = name
+ name_ctr = 1
+ print('\nstatic const char *%s =%sR"doc(%s)doc";' %
+ (name, '\n' if '\n' in comment else ' ', comment))
print('''
#if defined(__GNUG__)
diff --git a/ext/pybind11/tools/pybind11Config.cmake.in b/ext/pybind11/tools/pybind11Config.cmake.in
index ae6d2daee..3dd1b2c1a 100644
--- a/ext/pybind11/tools/pybind11Config.cmake.in
+++ b/ext/pybind11/tools/pybind11Config.cmake.in
@@ -21,18 +21,27 @@
# 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
+# interface library targets::
+#
+# pybind11::module - for extension modules
+# pybind11::embed - for embedding the Python interpreter
+#
+# Python headers, libraries (as needed by platform), and the 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::module - the main pybind11 interface library for extension modules (i.e., headers)
-#
# find_package(pybind11 CONFIG REQUIRED)
-# message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIR} (found version ${pybind11_VERSION} & Py${PYTHON_VERSION_STRING})")
+# message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
+#
+# # Create an extension module
# add_library(mylib MODULE main.cpp)
# target_link_libraries(mylib pybind11::module)
#
+# # Or embed the Python interpreter into an executable
+# add_executable(myexe main.cpp)
+# target_link_libraries(myexe pybind11::embed)
+#
# Suggested usage::
#
# find_package with version info is not recommended except for release versions. ::
@@ -71,21 +80,20 @@ 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}::module)
+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}::module APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
+ set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
+ set_property(TARGET ${PN}::embed APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
if(WIN32 OR CYGWIN)
set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
endif()
- select_cxx_standard()
- set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
+ set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
- get_property(_iid TARGET ${PN}::module PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+ get_property(_iid TARGET ${PN}::pybind11 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
get_property(_ill TARGET ${PN}::module PROPERTY INTERFACE_LINK_LIBRARIES)
- get_property(_ico TARGET ${PN}::module PROPERTY INTERFACE_COMPILE_OPTIONS)
set(${PN}_INCLUDE_DIRS ${_iid})
set(${PN}_LIBRARIES ${_ico} ${_ill})
endif()
diff --git a/ext/pybind11/tools/pybind11Tools.cmake b/ext/pybind11/tools/pybind11Tools.cmake
index 3fbffeeff..a7c471a07 100644
--- a/ext/pybind11/tools/pybind11Tools.cmake
+++ b/ext/pybind11/tools/pybind11Tools.cmake
@@ -18,23 +18,27 @@ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
include(CheckCXXCompilerFlag)
include(CMakeParseArguments)
-function(select_cxx_standard)
- if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD)
+if(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD)
+ if(NOT MSVC)
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!")
+ check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
+ if (HAS_CPP11_FLAG)
+ set(PYBIND11_CPP_STANDARD -std=c++11)
+ else()
+ message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
+ endif()
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)
+ elseif(MSVC)
+ set(PYBIND11_CPP_STANDARD /std:c++14)
endif()
-endfunction()
+
+ set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
+ "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE)
+endif()
# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
# linkerflags are lists of flags to use. The result variable is a unique variable name for each set
@@ -135,6 +139,13 @@ function(pybind11_add_module target_name)
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
+ # -fvisibility=hidden is required to allow multiple modules compiled against
+ # different pybind versions to work properly, and for some features (e.g.
+ # py::module_local). We force it on everything inside the `pybind11`
+ # namespace; also turning it on for a pybind module compilation here avoids
+ # potential warnings or issues from having mixed hidden/non-hidden types.
+ set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
+
if(WIN32 OR CYGWIN)
# Link against the Python shared library on Windows
target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
@@ -161,11 +172,8 @@ function(pybind11_add_module target_name)
endif()
endif()
- select_cxx_standard()
- if(NOT MSVC)
- # Make sure C++11/14 are enabled
- target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
- endif()
+ # Make sure C++11/14 are enabled
+ target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
if(ARG_NO_EXTRAS)
return()
@@ -174,9 +182,6 @@ function(pybind11_add_module target_name)
_pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO})
if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug)
- # Set the default symbol visibility to hidden (very important to obtain small binaries)
- target_compile_options(${target_name} PRIVATE "-fvisibility=hidden")
-
# Strip unnecessary sections of the binary on Linux/Mac OS
if(CMAKE_STRIP)
if(APPLE)