Skip to content

Commit f9d7ba6

Browse files
committed
setup: simplify build system using scikit-build
This commit introduces new dependencies: "scikit-built" and "cmake". scikit-build is a drop-in replacement to setuptools.setup function allowing to easily compile and package extensions (C/C++/Cython) by bridging CMake and setuptools. See http://scikit-build.org CMake is is an open-source, cross-platform family of tools designed to build, test and package software. See https://cmake.org Currently, scikit-build and cmake have to be explicitly (see [1]) installed on the system. This could be done by simply doing: pip install -U scikit-build cmake
1 parent 7d87934 commit f9d7ba6

File tree

2 files changed

+16
-93
lines changed

2 files changed

+16
-93
lines changed

CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
cmake_minimum_required(VERSION 2.8.12)
2+
23
project(python_cpp_example)
34

45
SET(SOURCE_DIR "src/python_cpp_example")
@@ -14,7 +15,9 @@ SET(TESTS ${SOURCES}
1415
# Generate a test executable
1516
include_directories(lib/catch/include)
1617
add_executable("${PROJECT_NAME}_test" ${TESTS})
18+
set_target_properties("${PROJECT_NAME}_test" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/bin)
1719

1820
# Generate python module
1921
add_subdirectory(lib/pybind11)
20-
pybind11_add_module(python_cpp_example ${SOURCES} "${SOURCE_DIR}/bindings.cpp")
22+
pybind11_add_module(python_cpp_example ${SOURCES} "${SOURCE_DIR}/bindings.cpp")
23+
install(TARGETS python_cpp_example DESTINATION src/python_cpp_example)

setup.py

+12-92
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,28 @@
11
#! /usr/bin/env python3
22

3-
import os
4-
import re
5-
import sys
6-
import sysconfig
7-
import platform
8-
import subprocess
3+
from __future__ import print_function
4+
from os import sys, path
95

10-
from distutils.version import LooseVersion
11-
from setuptools import setup, Extension, find_packages
12-
from setuptools.command.build_ext import build_ext
13-
from setuptools.command.test import test as TestCommand
14-
from shutil import copyfile, copymode
6+
try:
7+
from skbuild import setup
8+
except ImportError:
9+
print('scikit-build is required to build from source.', file=sys.stderr)
10+
print('Please run:', file=sys.stderr)
11+
print('', file=sys.stderr)
12+
print(' python -m pip install scikit-build')
13+
sys.exit(1)
1514

16-
17-
class CMakeExtension(Extension):
18-
def __init__(self, name, sourcedir=''):
19-
Extension.__init__(self, name, sources=[])
20-
self.sourcedir = os.path.abspath(sourcedir)
21-
22-
23-
class CMakeBuild(build_ext):
24-
def run(self):
25-
try:
26-
out = subprocess.check_output(['cmake', '--version'])
27-
except OSError:
28-
raise RuntimeError(
29-
"CMake must be installed to build the following extensions: " +
30-
", ".join(e.name for e in self.extensions))
31-
32-
if platform.system() == "Windows":
33-
cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)',
34-
out.decode()).group(1))
35-
if cmake_version < '3.1.0':
36-
raise RuntimeError("CMake >= 3.1.0 is required on Windows")
37-
38-
for ext in self.extensions:
39-
self.build_extension(ext)
40-
41-
def build_extension(self, ext):
42-
extdir = os.path.abspath(
43-
os.path.dirname(self.get_ext_fullpath(ext.name)))
44-
cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
45-
'-DPYTHON_EXECUTABLE=' + sys.executable]
46-
47-
cfg = 'Debug' if self.debug else 'Release'
48-
build_args = ['--config', cfg]
49-
50-
if platform.system() == "Windows":
51-
cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(
52-
cfg.upper(),
53-
extdir)]
54-
if sys.maxsize > 2**32:
55-
cmake_args += ['-A', 'x64']
56-
build_args += ['--', '/m']
57-
else:
58-
cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg]
59-
build_args += ['--', '-j2']
60-
61-
env = os.environ.copy()
62-
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(
63-
env.get('CXXFLAGS', ''),
64-
self.distribution.get_version())
65-
if not os.path.exists(self.build_temp):
66-
os.makedirs(self.build_temp)
67-
subprocess.check_call(['cmake', ext.sourcedir] + cmake_args,
68-
cwd=self.build_temp, env=env)
69-
subprocess.check_call(['cmake', '--build', '.'] + build_args,
70-
cwd=self.build_temp)
71-
# Copy *_test file to tests directory
72-
test_bin = os.path.join(self.build_temp, 'python_cpp_example_test')
73-
self.copy_test_file(test_bin)
74-
print() # Add an empty line for cleaner output
75-
76-
def copy_test_file(self, src_file):
77-
'''
78-
Copy ``src_file`` to ``dest_file`` ensuring parent directory exists.
79-
By default, message like `creating directory /path/to/package` and
80-
`copying directory /src/path/to/package -> path/to/package` are displayed on standard output. Adapted from scikit-build.
81-
'''
82-
# Create directory if needed
83-
dest_dir = os.path.join(os.path.dirname(
84-
os.path.abspath(__file__)), 'tests', 'bin')
85-
if dest_dir != "" and not os.path.exists(dest_dir):
86-
print("creating directory {}".format(dest_dir))
87-
os.makedirs(dest_dir)
88-
89-
# Copy file
90-
dest_file = os.path.join(dest_dir, os.path.basename(src_file))
91-
print("copying {} -> {}".format(src_file, dest_file))
92-
copyfile(src_file, dest_file)
93-
copymode(src_file, dest_file)
15+
from setuptools import find_packages
9416

9517
setup(
9618
name='python_cpp_example',
97-
version='0.2',
19+
version='0.3',
9820
author='Benjamin Jack',
9921
author_email='[email protected]',
10022
description='A hybrid Python/C++ test project',
10123
long_description='',
10224
packages=find_packages('src'),
10325
package_dir={'':'src'},
104-
ext_modules=[CMakeExtension('python_cpp_example/python_cpp_example')],
105-
cmdclass=dict(build_ext=CMakeBuild),
10626
test_suite='tests',
10727
zip_safe=False,
10828
)

0 commit comments

Comments
 (0)