From 1b978218566d0ce45b1c28b248acbdd039076854 Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Sat, 4 Jun 2016 18:31:09 +0200 Subject: [PATCH] Improve CMake extension builder in setup.py - Better conform to build_ext directory structure - Select build type according to build_ext '-g' flag - Check for CMake >= 3.1 on Windows --- .appveyor.yml | 2 +- .travis.yml | 2 +- setup.py | 56 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0c6d117..76c61b8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -10,6 +10,6 @@ install: - cmd: git submodule update -q --init --recursive build_script: - cmd: python setup.py sdist -- cmd: pip install dist\cmake_example-0.0.1.zip +- cmd: pip install --verbose dist\cmake_example-0.0.1.zip test_script: - cmd: python tests\test.py diff --git a/.travis.yml b/.travis.yml index 943df2c..f6d7d44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,6 @@ before_install: - source venv/bin/activate install: - python setup.py sdist -- pip install dist/*.tar.gz +- pip install --verbose dist/*.tar.gz script: - python tests/test.py diff --git a/setup.py b/setup.py index bd6d642..73ae4a6 100644 --- a/setup.py +++ b/setup.py @@ -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',