Skip to content

Commit

Permalink
Merge pull request pybind#3 from dean0x7d/master
Browse files Browse the repository at this point in the history
General improvements
  • Loading branch information
dean0x7d committed Jun 5, 2016
2 parents 37c3aec + 1b97821 commit bd4fe01
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 78 deletions.
9 changes: 6 additions & 3 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
dist/
*.so
*.py[cod]
*.egg-info
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include README.md LICENSE
global-include CMakeLists.txt *.cmake
recursive-include src *
recursive-include pybind11/include *.h
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
24 changes: 0 additions & 24 deletions license.md

This file was deleted.

17 changes: 0 additions & 17 deletions readme.md

This file was deleted.

62 changes: 36 additions & 26 deletions setup.py
Original file line number Diff line number Diff line change
@@ -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)

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)
self.build_extension(ext)

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]

cfg = 'Debug' if self.debug else 'Release'
build_args = ['--config', cfg]

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',
Expand Down
3 changes: 0 additions & 3 deletions test.py

This file was deleted.

3 changes: 3 additions & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from cmake_example import add

assert add(1, 2) == 3

0 comments on commit bd4fe01

Please sign in to comment.