commit cfd899cdf74abf8bb40374fb488aeb2b9d1561c6 Author: Dean Moldovan Date: Sun May 22 22:32:28 2016 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5eb1135 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build/ +*.so +*.py[cod] +*.egg-info diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bc9546d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "pybind11"] + path = pybind11 + url = https://github.com/dean0x7d/pybind11.git + branch = cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0763a57 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 2.8.12) +project(pybind11_cmake_example) + +add_subdirectory(pybind11) + +pybind11_add_module(cmake_example src/main.cpp) diff --git a/license.md b/license.md new file mode 100644 index 0000000..42a65e4 --- /dev/null +++ b/license.md @@ -0,0 +1,24 @@ +Copyright (c) 2016, Dean Moldovan + +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. + +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. diff --git a/pybind11 b/pybind11 new file mode 160000 index 0000000..8c6b0b8 --- /dev/null +++ b/pybind11 @@ -0,0 +1 @@ +Subproject commit 8c6b0b83332c8cb802391ffb08196fa4ebe1ebec diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4e69340 --- /dev/null +++ b/readme.md @@ -0,0 +1,17 @@ +## Building pybind11 modules with CMake + +An example of building a Python extension using [pybind11](https://github.com/pybind/pybind11) and CMake. +This is useful for C++ codebases that already have an existing CMake-based build system. + +### Install + +1. Make sure CMake >= 2.8.12 is installed on your system +2. Clone this repository +3. `pip install ./pybind11_cmake_example` + +### Test + +```python +import cmake_example +cmake_example.add(1, 2) +``` diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..bd6d642 --- /dev/null +++ b/setup.py @@ -0,0 +1,56 @@ +import os +import sys +import platform +import subprocess + +from setuptools import setup, Extension +from setuptools.command.build_ext import build_ext +from distutils.spawn import find_executable + + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = sourcedir + + +class CMakeBuild(build_ext): + def run(self): + if find_executable('cmake') is None: + print("CMake must be installed to build this extension") + sys.exit(-1) + + for ext in self.extensions: + build_dir = os.path.join(os.path.dirname(__file__), 'build', 'cmake') + if not os.path.exists(build_dir): + os.makedirs(build_dir) + cmake_dir = os.path.abspath(ext.sourcedir) + + extpath = self.get_ext_fullpath(ext.name) + extfulldir = os.path.abspath(os.path.dirname(extpath)) + cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extfulldir, + '-DPYTHON_EXECUTABLE=' + sys.executable] + build_args = ['--config', 'Release'] + + if platform.system() == "Windows": + cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=' + extfulldir] + if sys.maxsize > 2**32: + cmake_args += ['-A', 'x64'] + build_args += ['--', '/m'] + else: + build_args += ['--', '-j2'] + + subprocess.check_call(['cmake', cmake_dir] + cmake_args, cwd=build_dir) + subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=build_dir) + +setup( + name='cmake_example', + version='0.0.1', + author='Dean Moldovan', + author_email='dean0x7d@gmail.com', + description='A test project using pybind11 and CMake', + long_description='', + ext_modules=[CMakeExtension('cmake_example')], + cmdclass=dict(build_ext=CMakeBuild), + zip_safe=False, +) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d9e2c97 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,14 @@ +#include +namespace py = pybind11; + +int add(int i, int j) { + return i + j; +} + +PYBIND11_PLUGIN(cmake_example) { + py::module m("cmake_example"); + + m.def("add", &add, "A function which adds two numbers"); + + return m.ptr(); +}