Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
1503d2fb
Commit
1503d2fb
authored
May 29, 2016
by
Wenzel Jakob
Browse files
Merge pull request #207 from dean0x7d/cmake
Simplify CMake build using add_subdirectory
parents
2c76c693
c3c27c42
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
392 additions
and
325 deletions
+392
-325
.travis.yml
.travis.yml
+2
-0
CMakeLists.txt
CMakeLists.txt
+115
-187
docs/compiling.rst
docs/compiling.rst
+20
-138
example/CMakeLists.txt
example/CMakeLists.txt
+68
-0
tools/FindPythonLibsNew.cmake
tools/FindPythonLibsNew.cmake
+187
-0
No files found.
.travis.yml
View file @
1503d2fb
...
@@ -9,6 +9,7 @@ addons:
...
@@ -9,6 +9,7 @@ addons:
sources
:
sources
:
-
ubuntu-toolchain-r-test
-
ubuntu-toolchain-r-test
-
deadsnakes
-
deadsnakes
-
kubuntu-backports
# cmake 2.8.12
packages
:
packages
:
-
g++-4.8
-
g++-4.8
-
g++-4.8-multilib
-
g++-4.8-multilib
...
@@ -17,6 +18,7 @@ addons:
...
@@ -17,6 +18,7 @@ addons:
-
python3.5-dev
-
python3.5-dev
-
python3.5-venv
-
python3.5-venv
-
python3.5-dev:i386
-
python3.5-dev:i386
-
cmake
matrix
:
matrix
:
include
:
include
:
-
os
:
linux
-
os
:
linux
...
...
CMakeLists.txt
View file @
1503d2fb
...
@@ -5,187 +5,62 @@
...
@@ -5,187 +5,62 @@
# All rights reserved. Use of this source code is governed by a
# All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# BSD-style license that can be found in the LICENSE file.
cmake_minimum_required
(
VERSION 2.8
)
cmake_minimum_required
(
VERSION 2.8
.12
)
project
(
pybind11
)
project
(
pybind11
)
option
(
PYBIND11_INSTALL
"Install pybind11 header files?"
ON
)
# Check if pybind11 is being used directly or via add_subdirectory
set
(
PYBIND11_MASTER_PROJECT OFF
)
if
(
CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR
)
set
(
PYBIND11_MASTER_PROJECT ON
)
endif
()
option
(
PYBIND11_INSTALL
"Install pybind11 header files?"
${
PYBIND11_MASTER_PROJECT
}
)
option
(
PYBIND11_TEST
"Build tests?"
${
PYBIND11_MASTER_PROJECT
}
)
# Add a CMake parameter for choosing a desired Python version
# Add a CMake parameter for choosing a desired Python version
set
(
PYBIND11_PYTHON_VERSION
""
CACHE STRING
"Python version to use for compiling the example application"
)
set
(
PYBIND11_PYTHON_VERSION
""
CACHE STRING
"Python version to use for compiling the example application"
)
include
(
CheckCXXCompilerFlag
)
list
(
APPEND CMAKE_MODULE_PATH
"
${
CMAKE_CURRENT_LIST_DIR
}
/tools"
)
# 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
)
set
(
Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7
)
set
(
Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7
)
if
(
NOT
${
PYBIND11_PYTHON_VERSION
}
STREQUAL
""
)
find_package
(
PythonLibsNew
${
PYBIND11_PYTHON_VERSION
}
REQUIRED
)
find_package
(
PythonLibs
${
PYBIND11_PYTHON_VERSION
}
EXACT
)
if
(
NOT PYTHONLIBS_FOUND
)
include
(
CheckCXXCompilerFlag
)
find_package
(
PythonLibs
${
PYBIND11_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 line to work
string
(
REPLACE
"+"
""
PYTHONLIBS_VERSION_STRING
"+
${
PYTHONLIBS_VERSION_STRING
}
"
)
find_package
(
PythonInterp
${
PYTHONLIBS_VERSION_STRING
}
EXACT REQUIRED
)
if
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
OR CMAKE_CXX_COMPILER_ID MATCHES
"GNU"
OR CMAKE_CXX_COMPILER_ID MATCHES
"Intel"
)
if
(
NOT MSVC AND NOT PYBIND11_CPP_STANDARD
)
CHECK_CXX_COMPILER_FLAG
(
"-std=c++14"
HAS_CPP14_FLAG
)
check_cxx_compiler_flag
(
"-std=c++14"
HAS_CPP14_FLAG
)
CHECK_CXX_COMPILER_FLAG
(
"-std=c++11"
HAS_CPP11_FLAG
)
check_cxx_compiler_flag
(
"-std=c++11"
HAS_CPP11_FLAG
)
if
(
HAS_CPP14_FLAG
)
if
(
HAS_CPP14_FLAG
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++14
"
)
set
(
PYBIND11_CPP_STANDARD
-std=c++14
)
elseif
(
HAS_CPP11_FLAG
)
elseif
(
HAS_CPP11_FLAG
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++11
"
)
set
(
PYBIND11_CPP_STANDARD
-std=c++11
)
else
()
else
()
message
(
FATAL_ERROR
"Unsupported compiler -- pybind11 requires C++11 support!"
)
message
(
FATAL_ERROR
"Unsupported compiler -- pybind11 requires C++11 support!"
)
endif
()
endif
()
# Enable link time optimization and set the default symbol
set
(
PYBIND11_CPP_STANDARD
${
PYBIND11_CPP_STANDARD
}
CACHE STRING
# visibility to hidden (very important to obtain small binaries)
"C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available."
)
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
# (GCC/Clang)
CHECK_CXX_COMPILER_FLAG
(
"-flto"
HAS_LTO_FLAG
)
if
(
HAS_LTO_FLAG
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-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
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-ipo"
)
endif
()
endif
()
endif
()
endif
()
# Compile with compiler warnings turned on
if
(
MSVC
)
if
(
CMAKE_CXX_FLAGS MATCHES
"/W[0-4]"
)
string
(
REGEX REPLACE
"/W[0-4]"
"/W4"
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
"
)
else
()
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
/W4"
)
endif
()
elseif
(
"
${
CMAKE_CXX_COMPILER_ID
}
"
MATCHES
"Clang"
OR
"
${
CMAKE_CXX_COMPILER_ID
}
"
MATCHES
"GNU"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wall -Wextra"
)
endif
()
endif
()
# Cache variables so pybind11_add_module can be used in parent projects
set
(
PYBIND11_INCLUDE_DIR
"
${
CMAKE_CURRENT_LIST_DIR
}
/include"
CACHE INTERNAL
""
)
set
(
PYTHON_INCLUDE_DIRS
${
PYTHON_INCLUDE_DIRS
}
CACHE INTERNAL
""
)
set
(
PYTHON_LIBRARIES
${
PYTHON_LIBRARIES
}
CACHE INTERNAL
""
)
set
(
PYTHON_MODULE_PREFIX
${
PYTHON_MODULE_PREFIX
}
CACHE INTERNAL
""
)
set
(
PYTHON_MODULE_EXTENSION
${
PYTHON_MODULE_EXTENSION
}
CACHE INTERNAL
""
)
# Check if Eigen is available
# Build a Python extension module:
set
(
CMAKE_MODULE_PATH
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/tools"
)
# pybind11_add_module(<name> source1 [source2 ...])
find_package
(
Eigen3 QUIET
)
#
function
(
pybind11_add_module target_name
)
# Include path for pybind11 header files
add_library
(
${
target_name
}
MODULE
${
ARGN
}
)
include_directories
(
include
)
target_include_directories
(
${
target_name
}
PUBLIC
${
PYBIND11_INCLUDE_DIR
}
${
PYTHON_INCLUDE_DIRS
}
)
# Include path for Python header files
include_directories
(
${
PYTHON_INCLUDE_DIR
}
)
set
(
PYBIND11_HEADERS
include/pybind11/attr.h
include/pybind11/cast.h
include/pybind11/common.h
include/pybind11/complex.h
include/pybind11/descr.h
include/pybind11/eigen.h
include/pybind11/functional.h
include/pybind11/numpy.h
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/stl.h
include/pybind11/stl_bind.h
include/pybind11/typeid.h
)
set
(
PYBIND11_EXAMPLES
example/example1.cpp
example/example2.cpp
example/example3.cpp
example/example4.cpp
example/example5.cpp
example/example6.cpp
example/example7.cpp
example/example8.cpp
example/example9.cpp
example/example10.cpp
example/example11.cpp
example/example12.cpp
example/example13.cpp
example/example14.cpp
example/example15.cpp
example/example16.cpp
example/example17.cpp
example/issues.cpp
)
if
(
EIGEN3_FOUND
)
include_directories
(
${
EIGEN3_INCLUDE_DIR
}
)
list
(
APPEND PYBIND11_EXAMPLES example/eigen.cpp
)
add_definitions
(
-DPYBIND11_TEST_EIGEN
)
message
(
STATUS
"Building Eigen testcase"
)
else
()
message
(
STATUS
"NOT Building Eigen testcase"
)
endif
()
# Create the binding library
add_library
(
example SHARED
${
PYBIND11_HEADERS
}
example/example.cpp
${
PYBIND11_EXAMPLES
}
)
# Don't add a 'lib' prefix to the shared library
set_target_properties
(
example PROPERTIES PREFIX
""
)
# 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
()
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
# The prefix and extension are provided by FindPythonLibsNew.cmake
set_target_properties
(
example PROPERTIES SUFFIX
".pyd"
)
set_target_properties
(
${
target_name
}
PROPERTIES PREFIX
"
${
PYTHON_MODULE_PREFIX
}
"
)
set_target_properties
(
${
target_name
}
PROPERTIES SUFFIX
"
${
PYTHON_MODULE_EXTENSION
}
"
)
# 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
# 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
# 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.
# that's statically linked into an application like Blender or Maya.
...
@@ -199,41 +74,94 @@ elseif (UNIX)
...
@@ -199,41 +74,94 @@ elseif (UNIX)
# link against the Python library. The resulting shared library will have
# link against the Python library. The resulting shared library will have
# missing symbols, but that's perfectly fine -- they will be resolved at
# missing symbols, but that's perfectly fine -- they will be resolved at
# import time.
# import time.
if
(
MSVC
)
# .SO file extension on Linux/Mac OS
target_link_libraries
(
${
target_name
}
PRIVATE
${
PYTHON_LIBRARIES
}
)
set_target_properties
(
example PROPERTIES SUFFIX
".so"
)
elseif
(
APPLE
)
# Make sure OS X does not have any issues with missing symbols
# Optimize for a small binary size
target_link_libraries
(
${
target_name
}
PRIVATE
"-undefined dynamic_lookup"
)
if
(
NOT
${
U_CMAKE_BUILD_TYPE
}
MATCHES DEBUG
)
set_target_properties
(
example PROPERTIES COMPILE_FLAGS
"-Os"
)
endif
()
endif
()
# Strip unnecessary sections of the binary on Linux/Mac OS
if
(
NOT MSVC
)
if
(
APPLE
)
# Make sure C++11/14 are enabled
set_target_properties
(
example PROPERTIES MACOSX_RPATH
"."
)
target_compile_options
(
${
target_name
}
PUBLIC
${
PYBIND11_CPP_STANDARD
}
)
set_target_properties
(
example PROPERTIES LINK_FLAGS
"-undefined dynamic_lookup "
)
if
(
NOT
${
U_CMAKE_BUILD_TYPE
}
MATCHES DEBUG
)
# Enable link time optimization and set the default symbol
add_custom_command
(
TARGET example POST_BUILD COMMAND strip -u -r
${
PROJECT_SOURCE_DIR
}
/example/example.so
)
# visibility to hidden (very important to obtain small binaries)
endif
()
string
(
TOUPPER
"
${
CMAKE_BUILD_TYPE
}
"
U_CMAKE_BUILD_TYPE
)
else
()
if
(
NOT
${
U_CMAKE_BUILD_TYPE
}
MATCHES DEBUG
)
if
(
NOT
${
U_CMAKE_BUILD_TYPE
}
MATCHES DEBUG
)
add_custom_command
(
TARGET example POST_BUILD COMMAND strip
${
PROJECT_SOURCE_DIR
}
/example/example.so
)
# Check for Link Time Optimization support (GCC/Clang)
check_cxx_compiler_flag
(
"-flto"
HAS_LTO_FLAG
)
if
(
HAS_LTO_FLAG
)
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
()
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
()
endif
()
end
i
f
()
endf
unction
()
enable_testing
()
# Compile with compiler warnings turned on
function
(
pybind11_turn_on_warnings target_name
)
if
(
MSVC
)
target_compile_options
(
${
target_name
}
PRIVATE /W4
)
else
()
target_compile_options
(
${
target_name
}
PRIVATE -Wall -Wextra
)
endif
()
endfunction
()
set
(
RUN_TEST
${
PYTHON_EXECUTABLE
}
${
CMAKE_CURRENT_SOURCE_DIR
}
/example/run_test.py
)
if
(
PYBIND11_TEST
)
if
(
MSVC OR CMAKE_CXX_COMPILER_ID MATCHES
"Intel"
)
enable_testing
(
)
set
(
RUN_TEST
${
RUN_TEST
}
--relaxed
)
add_subdirectory
(
example
)
endif
()
endif
()
foreach
(
VALUE
${
PYBIND11_EXAMPLES
}
)
string
(
REGEX REPLACE
"^example/(.+).cpp$"
"
\\
1"
EXAMPLE_NAME
"
${
VALUE
}
"
)
add_test
(
NAME
${
EXAMPLE_NAME
}
COMMAND
${
RUN_TEST
}
${
EXAMPLE_NAME
}
)
endforeach
()
if
(
PYBIND11_INSTALL
)
if
(
PYBIND11_INSTALL
)
install
(
FILES
${
PYBIND11_HEADERS
}
DESTINATION include/pybind11
)
set
(
PYBIND11_HEADERS
include/pybind11/attr.h
include/pybind11/cast.h
include/pybind11/common.h
include/pybind11/complex.h
include/pybind11/descr.h
include/pybind11/eigen.h
include/pybind11/functional.h
include/pybind11/numpy.h
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/stl.h
include/pybind11/stl_bind.h
include/pybind11/typeid.h
)
install
(
FILES
${
PYBIND11_HEADERS
}
DESTINATION include/pybind11
)
endif
()
endif
()
docs/compiling.rst
View file @
1503d2fb
...
@@ -26,146 +26,28 @@ Building with cppimport
...
@@ -26,146 +26,28 @@ Building with cppimport
Building with CMake
Building with CMake
===================
===================
For C++ codebases that already have an existing CMake-based build system, the
For C++ codebases that have an existing CMake-based build system, a Python
following snippet should be a good starting point to create bindings across
extension module can be created with just a few lines of code:
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`.
.. code-block:: cmake
.. code-block:: cmake
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.8.12)
project(example)
project(example)
# Add a CMake parameter for choosing a desired Python version
add_subdirectory(pybind11)
set(EXAMPLE_PYTHON_VERSION "" CACHE STRING
pybind11_add_module(example example.cpp)
"Python version to use for compiling the example library")
This assumes that the pybind11 repository is located in a subdirectory named
include(CheckCXXCompilerFlag)
: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
# Set a default build configuration if none is specified.
``pybind11_add_module(<name> source1 [source2 ...])``. It will take care of all
# 'MinSizeRel' produces the smallest binaries
the details needed to build a Python extension module on any platform.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION``
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
variable before adding the pybind11 subdirectory. Alternatively, an exact Python
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
installation can be specified by setting ``PYTHON_EXECUTABLE``.
"MinSizeRel" "RelWithDebInfo")
endif()
A working sample project, including a way to invoke CMake from :file:`setup.py` for
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
PyPI integration, can be found in the [cmake_example]_ repository.
# Try to autodetect Python (can be overridden manually if needed)
.. [cmake_example] https://github.com/dean0x7d/pybind11_cmake_example
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()
example/CMakeLists.txt
0 → 100644
View file @
1503d2fb
# 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_turn_on_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
()
tools/FindPythonLibsNew.cmake
0 → 100644
View file @
1503d2fb
# - 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