Overhauled and steamlined setup.py

这个提交包含在:
Craig Warren
2022-01-05 16:35:49 +00:00
父节点 f05120f3af
当前提交 81bcf48dc5

158
setup.py
查看文件

@@ -16,17 +16,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with gprMax. If not, see <http://www.gnu.org/licenses/>. # along with gprMax. If not, see <http://www.gnu.org/licenses/>.
try:
from setuptools import Extension, setup
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
try:
import numpy as np
except ImportError:
raise ImportError('gprMax requires the NumPy package.')
import glob import glob
import os import os
import re import re
@@ -35,24 +24,29 @@ import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
import numpy as np
from Cython.Build import cythonize
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from setuptools import Extension, find_packages, setup
MIN_PYTHON_VERSION = (3, 7)
# Check Python version # Check Python version
MIN_PYTHON_VERSION = (3, 7)
if sys.version_info[:2] < MIN_PYTHON_VERSION: if sys.version_info[:2] < MIN_PYTHON_VERSION:
sys.exit('\nExited: Requires Python 3.7 or newer!\n') sys.exit('\nExited: Requires Python {MIN_PYTHON_VERSION[0]}.{MIN_PYTHON_VERSION[1]} or newer!\n')
# Importing gprMax _version__.py before building can cause issues.
with open('gprMax/_version.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
def build_dispersive_material_templates(): def build_dispersive_material_templates():
"""Function to generate Cython .pyx files for dispersive media update. """Function to generate Cython .pyx file for dispersive media update.
Jinja2 templates are used to render the various dispersive update Jinja2 templates are used to render the various dispersive update
functions. functions.
""" """
env = Environment( env = Environment(loader = FileSystemLoader('gprMax/templates'), )
loader=FileSystemLoader('gprMax/templates'),
)
template = env.get_template('fields_updates_dispersive_template') template = env.get_template('fields_updates_dispersive_template')
@@ -109,20 +103,8 @@ def build_dispersive_material_templates():
f.write(r) f.write(r)
# Generate Cython file for dispersive materials update functions # Generate Cython file for dispersive materials update functions
build_dispersive_material_templates() if not os.path.isfile('gprMax/cython/fields_updates_dispersive.pyx'):
build_dispersive_material_templates()
# Importing _version__.py before building can cause issues.
with open('gprMax/_version.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
# Parse package name from init file. Importing __init__.py / gprMax will break
# as gprMax depends on compiled .pyx files.
with open('gprMax/__init__.py', 'r') as fd:
packagename = re.search(r'^__name__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
packages = [packagename, 'tests', 'tools', 'user_libs']
# Process 'build' command line argument # Process 'build' command line argument
if 'build' in sys.argv: if 'build' in sys.argv:
@@ -131,25 +113,16 @@ if 'build' in sys.argv:
sys.argv.append('build_ext') sys.argv.append('build_ext')
sys.argv.append('--inplace') sys.argv.append('--inplace')
# Process '--no-cython' command line argument - either Cythonize or just compile
# the .c files
if '--no-cython' in sys.argv:
USE_CYTHON = False
sys.argv.remove('--no-cython')
else:
USE_CYTHON = True
# Build a list of all the files that need to be Cythonized looking in gprMax # Build a list of all the files that need to be Cythonized looking in gprMax
# directory # directory
cythonfiles = [] cythonfiles = []
for root, dirs, files in os.walk(os.path.join(os.getcwd(), packagename), topdown=True): for root, dirs, files in os.walk(os.path.join(os.getcwd(), 'gprMax'), topdown=True):
for file in files: for file in files:
if file.endswith('.pyx'): if file.endswith('.pyx'):
cythonfiles.append(os.path.relpath(os.path.join(root, file))) cythonfiles.append(os.path.relpath(os.path.join(root, file)))
# Process 'cleanall' command line argument - cleanup Cython files # Process 'cleanall' command line argument
if 'cleanall' in sys.argv: if 'cleanall' in sys.argv:
USE_CYTHON = False
for file in cythonfiles: for file in cythonfiles:
filebase = os.path.splitext(file)[0] filebase = os.path.splitext(file)[0]
# Remove Cython C files # Remove Cython C files
@@ -185,7 +158,7 @@ else:
if sys.platform == 'win32': if sys.platform == 'win32':
compile_args = ['/O2', '/openmp', '/w'] # No static linking as no static version of OpenMP library; /w disables warnings compile_args = ['/O2', '/openmp', '/w'] # No static linking as no static version of OpenMP library; /w disables warnings
linker_args = [] linker_args = []
libraries=[] libraries = []
# Compiler options - macOS - needs gcc (usually via HomeBrew) because the # Compiler options - macOS - needs gcc (usually via HomeBrew) because the
# default compiler LLVM (clang) does not # default compiler LLVM (clang) does not
@@ -203,7 +176,7 @@ else:
os.environ['CC'] = gccpath[-1].split(os.sep)[-1] os.environ['CC'] = gccpath[-1].split(os.sep)[-1]
rpath = '/opt/homebrew/opt/gcc/lib/gcc/' + gccpath[-1].split(os.sep)[-1][-1] + '/' rpath = '/opt/homebrew/opt/gcc/lib/gcc/' + gccpath[-1].split(os.sep)[-1][-1] + '/'
else: else:
raise('Cannot find gcc 4-10 in /opt/homebrew/bin. gprMax requires gcc to be installed - easily done through the Homebrew package manager (http://brew.sh). Note: gcc with OpenMP support is required.') raise('Cannot find gcc in /opt/homebrew/bin. gprMax requires gcc to be installed - easily done through the Homebrew package manager (http://brew.sh). Note: gcc with OpenMP support is required.')
else: else:
gccpath = glob.glob('/usr/local/bin/gcc-[4-9]*') gccpath = glob.glob('/usr/local/bin/gcc-[4-9]*')
gccpath += glob.glob('/usr/local/bin/gcc-[10-11]*') gccpath += glob.glob('/usr/local/bin/gcc-[10-11]*')
@@ -221,7 +194,9 @@ else:
except: except:
pass pass
os.environ['MIN_SUPPORTED_MACOSX_DEPLOYMENT_TARGET'] = MIN_MACOS_VERSION os.environ['MIN_SUPPORTED_MACOSX_DEPLOYMENT_TARGET'] = MIN_MACOS_VERSION
compile_args = ['-O3', '-w', '-fopenmp', '-march=native', '-mmacosx-version-min=' + MIN_MACOS_VERSION] # Sometimes worth testing with '-fstrict-aliasing', '-fno-common' # Sometimes worth testing with '-fstrict-aliasing', '-fno-common'
compile_args = ['-O3', '-w', '-fopenmp', '-march=native',
'-mmacosx-version-min=' + MIN_MACOS_VERSION]
linker_args = ['-fopenmp', '-mmacosx-version-min=' + MIN_MACOS_VERSION] linker_args = ['-fopenmp', '-mmacosx-version-min=' + MIN_MACOS_VERSION]
libraries=['gomp'] libraries=['gomp']
@@ -229,18 +204,14 @@ else:
elif sys.platform == 'linux': elif sys.platform == 'linux':
compile_args = ['-O3', '-w', '-fopenmp', '-march=native'] compile_args = ['-O3', '-w', '-fopenmp', '-march=native']
linker_args = ['-fopenmp'] linker_args = ['-fopenmp']
libraries=[] libraries = []
# Build list of all the extensions - Cython source files # Build list of all the extensions - Cython source files
extensions = [] extensions = []
for file in cythonfiles: for file in cythonfiles:
tmp = os.path.splitext(file) tmp = os.path.splitext(file)
if USE_CYTHON:
fileext = tmp[1]
else:
fileext = '.c'
extension = Extension(tmp[0].replace(os.sep, '.'), extension = Extension(tmp[0].replace(os.sep, '.'),
[tmp[0] + fileext], [tmp[0] + tmp[1]],
language='c', language='c',
include_dirs=[np.get_include()], include_dirs=[np.get_include()],
extra_compile_args=compile_args, extra_compile_args=compile_args,
@@ -249,57 +220,48 @@ else:
extensions.append(extension) extensions.append(extension)
# Cythonize - build .c files # Cythonize - build .c files
if USE_CYTHON: extensions = cythonize(extensions,
from Cython.Build import cythonize compiler_directives={'boundscheck': False,
extensions = cythonize(extensions, 'wraparound': False,
compiler_directives={ 'initializedcheck': False,
'boundscheck': False, 'embedsignature': True,
'wraparound': False, 'language_level': 3},
'initializedcheck': False, nthreads=None,
'embedsignature': True, annotate=False)
'language_level': 3
},
nthreads=None,
annotate=False)
# Parse long_description from README.rst file. # Parse long_description from README.rst file.
with open('README.rst','r') as fd: with open('README.rst','r') as fd:
long_description = fd.read() long_description = fd.read()
setup(name=packagename, setup(name='gprMax',
version=version, version=version,
author='Craig Warren, Antonis Giannopoulos, and John Hartley', author='Craig Warren, Antonis Giannopoulos, and John Hartley',
url='http://www.gprmax.com', url='http://www.gprmax.com',
description='Electromagnetic Modelling Software based on the Finite-Difference Time-Domain (FDTD) method', description='Electromagnetic Modelling Software based on the Finite-Difference Time-Domain (FDTD) method',
long_description=long_description, long_description=long_description,
long_description_content_type="text/x-rst", long_description_content_type="text/x-rst",
license='GPLv3+', license='GPLv3+',
classifiers=[ python_requires='>' + str(MIN_PYTHON_VERSION[0]) + '.' + str(MIN_PYTHON_VERSION[1]),
'Environment :: Console', install_requires=['colorama',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 'cython',
'Operating System :: MacOS', 'h5py',
'Operating System :: Microsoft :: Windows', 'jinja2',
'Operating System :: POSIX :: Linux', 'matplotlib',
'Programming Language :: Cython', 'numpy',
'Programming Language :: Python :: 3', 'psutil',
'Topic :: Scientific/Engineering' 'scipy',
], 'terminaltables',
#requirements 'tqdm'],
python_requires='>' + str(MIN_PYTHON_VERSION[0]) + '.' + str(MIN_PYTHON_VERSION[1]),
install_requires=[
'colorama',
'cython',
'h5py',
'jinja2',
'jupyter',
'matplotlib',
'numpy',
'psutil',
'scipy',
'terminaltables',
'tqdm',
],
ext_modules=extensions, ext_modules=extensions,
packages=packages, packages=find_packages(),
include_package_data=True, include_package_data=True,
include_dirs=[np.get_include()]) include_dirs=[np.get_include()],
zip_safe=False,
classifiers=['Environment :: Console',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX :: Linux',
'Programming Language :: Cython',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering'])