Merge pull request #3 from dean0x7d/master

General improvements
This commit is contained in:
Dean Moldovan 2016-06-05 18:18:02 +02:00
commit bd4fe0164e
12 changed files with 123 additions and 75 deletions

View file

@ -2,11 +2,14 @@ version: 1.0.{build}
image: Visual Studio 2015
environment:
matrix:
- PATH: C:\Python27\;C:\Python27\Scripts\;%PATH%
- PATH: C:\Python27-x64\;C:\Python27-x64\Scripts\;%PATH%
- PATH: C:\Python35\;C:\Python35\Scripts\;%PATH%
- PATH: C:\Python35-x64\;C:\Python35-x64\Scripts\;%PATH%
- PATH: C:\Miniconda35-x64\;C:\Miniconda35-x64\Scripts\;%PATH%
install:
- cmd: git submodule update -q --init --recursive
build_script:
- cmd: pip install .
- cmd: python setup.py sdist
- cmd: pip install --verbose dist\cmake_example-0.0.1.zip
test_script:
- cmd: python test.py
- cmd: python tests\test.py

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
build/
dist/
*.so
*.py[cod]
*.egg-info

View file

@ -23,6 +23,7 @@ before_install:
- virtualenv -p python$PYTHON venv
- source venv/bin/activate
install:
- pip install .
- python setup.py sdist
- pip install --verbose dist/*.tar.gz
script:
- python test.py
- python tests/test.py

View file

@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 2.8.12)
project(pybind11_cmake_example)
project(cmake_example)
add_subdirectory(pybind11)
pybind11_add_module(cmake_example src/main.cpp)

4
MANIFEST.in Normal file
View file

@ -0,0 +1,4 @@
include README.md LICENSE
global-include CMakeLists.txt *.cmake
recursive-include src *
recursive-include pybind11/include *.h

71
README.md Normal file
View file

@ -0,0 +1,71 @@
# cmake_example for pybind11
[![Build Status](https://travis-ci.org/pybind/cmake_example.svg?branch=master)](https://travis-ci.org/pybind/cmake_example)
[![Build status](https://ci.appveyor.com/api/projects/status/8gtjyogdmy9amqm1/branch/master?svg=true)](https://ci.appveyor.com/project/dean0x7d/cmake-example/branch/master)
An example [pybind11](https://github.com/pybind/pybind11) module built with a
CMake-based build system. This is useful for C++ codebases that have an existing
CMake project structure.
## Prerequisites
**On Unix (Linux, OS X)**
* A compiler with C++11 support
* CMake >= 2.8.12
**On Windows**
* Visual Studio 2015 (required for all Python versions, see notes below)
* CMake >= 3.1
## Installation
Just clone this repository and pip install. Note the `--recursive` option which is
needed for the pybind11 submodule:
```bash
git clone --recursive https://github.com/pybind/cmake_example.git
pip install ./cmake_example
```
With the `setup.py` file included in this example, the `pip install` command will
invoke CMake and build the pybind11 module as specified in `CMakeLists.txt`.
## Special notes for Windows
**Compiler requirements**
Pybind11 requires a C++11 compliant compiler, i.e Visual Studio 2015 on Windows.
This applies to all Python versions, including 2.7. Unlike regular C extension
modules, it's perfectly fine to compile a pybind11 module with a VS version newer
than the target Python's VS version. See the [FAQ] for more details.
**Runtime requirements**
The Visual C++ 2015 redistributable packages are a runtime requirement for this
project. It can be found [here][vs2015_runtime]. If you use the Anaconda Python
distribution, you can add `vs2015_runtime` as a platform-dependent runtime
requirement for you package: see the `conda.recipe/meta.yaml` file in this example.
## License
Pybind11 is provided under a BSD-style license that can be found in the LICENSE
file. By using, distributing, or contributing to this project, you agree to the
terms and conditions of this license.
## Test call
```python
import cmake_example
cmake_example.add(1, 2)
```
[FAQ]: http://pybind11.rtfd.io/en/latest/faq.html#working-with-ancient-visual-studio-2009-builds-on-windows
[vs2015_runtime]: https://www.microsoft.com/en-us/download/details.aspx?id=48145

View file

@ -1,24 +0,0 @@
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.

@ -1 +1 @@
Subproject commit 0a07805ab663b981d72bbe2663b946f8c18e67cf
Subproject commit 19d95ef09a384d6631308161ead24e5a230c9bf8

View file

@ -1,17 +0,0 @@
## 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)
```

View file

@ -1,47 +1,57 @@
import os
import re
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
from distutils.version import LooseVersion
class CMakeExtension(Extension):
def __init__(self, name, sourcedir=''):
Extension.__init__(self, name, sources=[])
self.sourcedir = sourcedir
self.sourcedir = os.path.abspath(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)
try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError("CMake must be installed to build the following extensions: " +
", ".join(e.name for e in self.extensions))
if platform.system() == "Windows":
cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))
if cmake_version < '3.1.0':
raise RuntimeError("CMake >= 3.1.0 is required on Windows")
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)
self.build_extension(ext)
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']
def build_extension(self, ext):
extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
'-DPYTHON_EXECUTABLE=' + sys.executable]
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']
cfg = 'Debug' if self.debug else 'Release'
build_args = ['--config', cfg]
subprocess.check_call(['cmake', cmake_dir] + cmake_args, cwd=build_dir)
subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=build_dir)
if platform.system() == "Windows":
cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)]
if sys.maxsize > 2**32:
cmake_args += ['-A', 'x64']
build_args += ['--', '/m']
else:
cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg]
build_args += ['--', '-j2']
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp)
subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp)
setup(
name='cmake_example',

View file

@ -1,3 +0,0 @@
import cmake_example
print(cmake_example.add(1, 2))

3
tests/test.py Normal file
View file

@ -0,0 +1,3 @@
from cmake_example import add
assert add(1, 2) == 3