# This file is part of xrayutilities.
#
# xrayutilies is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2009 Eugen Wintersberger <eugen.wintersberger@desy.de>
# Copyright (C) 2010-2021 Dominik Kriegner <dominik.kriegner@gmail.com>
import glob
import os.path
import subprocess
import sys
import tempfile
from distutils.command.build_py import build_py
from distutils.command.install import INSTALL_SCHEMES
from distutils.errors import CompileError, DistutilsArgError
from distutils.fancy_getopt import FancyGetopt
import numpy
from setuptools import Extension, find_packages, setup
from setuptools.command.build_ext import build_ext
cliopts = []
cliopts.append(("without-openmp", None, "build without OpenMP support"))
options = FancyGetopt(option_table=cliopts)
# Modify the data install dir to match the source install dir
for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']
# first read all the arguments passed to the script
# we need to do this otherwise the --help commands would not work
args = sys.argv[1:]
try:
# search the arguments for options we would like to use
# get new args with the custom options stripped away
args, opts = options.getopt(args)
except DistutilsArgError:
pass
# get options from command line
without_openmp = False
for opts, values in options.get_option_order():
if opts == "without-openmp":
without_openmp = True
def has_flag(compiler, flagname, output_dir=None):
# see https://bugs.python.org/issue26689
"""Return a boolean indicating whether a flag name is supported on
the specified compiler.
"""
with tempfile.NamedTemporaryFile('w', suffix='.c', delete=False) as f:
f.write('int main (int argc, char **argv) { return 0; }')
f.close()
try:
obj = compiler.compile([f.name], output_dir=output_dir,
extra_postargs=[flagname])
os.remove(*obj)
except CompileError:
return False
finally:
os.remove(f.name)
return True
class build_ext_subclass(build_ext):
def build_extensions(self):
c = self.compiler.compiler_type
# set extra compiler options
copt = {}
if c in copt:
for flag in copt[c]:
if has_flag(self.compiler, flag, self.build_temp):
for e in self.extensions:
e.extra_compile_args.append(flag)
# set openMP compiler options
if not without_openmp:
openmpflags = {'msvc': ('/openmp', None),
'mingw32': ('-fopenmp', '-fopenmp'),
'unix': ('-fopenmp', '-lgomp')}
if c in openmpflags:
flag, lib = openmpflags[c]
if has_flag(self.compiler, flag, self.build_temp):
for e in self.extensions:
e.extra_compile_args.append(flag)
if lib is not None:
e.extra_link_args.append(lib)
e.define_macros.append(('__OPENMP__', None))
super().build_extensions()
class build_with_database(build_py):
def build_database(self):
dbfilename = os.path.join(self.build_lib, 'xrayutilities',
'materials', 'data', 'elements.db')
cmd = [sys.executable,
os.path.join('lib', 'xrayutilities', 'materials',
'_create_database.py'),
dbfilename]
self.mkpath(os.path.dirname(dbfilename))
print('building database: {}'.format(dbfilename))
try:
if sys.version_info >= (3, 5):
subprocess.run(cmd, stderr=subprocess.PIPE,
stdout=subprocess.PIPE, check=True)
else:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as cpe:
sys.stdout.buffer.write(cpe.stdout)
sys.stdout.buffer.write(cpe.stderr)
raise
def run(self):
super().run()
self.build_database()
cmdclass = {'build_py': build_with_database,
'build_ext': build_ext_subclass}
with open('README.md') as f:
long_description = f.read()
extmodul = Extension('xrayutilities.cxrayutilities',
sources=glob.glob(os.path.join('src', '*.c')))
with open('lib/xrayutilities/VERSION') as version_file:
version = version_file.read().strip().replace('\n', '.')
try:
import sphinx
from sphinx.setup_command import BuildDoc
class build_doc(BuildDoc):
def run(self):
# make sure the python path is pointing to the newly built
# code so that the documentation is built on this and not a
# previously installed version
build = self.get_finalized_command('build')
sys.path.insert(0, os.path.abspath(build.build_lib))
try:
sphinx.setup_command.BuildDoc.run(self)
except UnicodeDecodeError:
print("ERROR: unable to build documentation"
" because Sphinx do not handle"
" source path with non-ASCII characters. Please"
" try to move the source package to another"
" location (path with *only* ASCII characters)")
sys.path.pop(0)
cmdclass['build_doc'] = build_doc
except ImportError:
pass
setup(
name="xrayutilities",
version=version,
author="Eugen Wintersberger, Dominik Kriegner",
description="package for x-ray diffraction data evaluation",
classifiers=[
"Programming Language :: C",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Scientific/Engineering :: Physics",
"Intended Audience :: Science/Research",
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: GNU General Public License v2 or later "
"(GPLv2+)"
],
long_description=long_description,
long_description_content_type="text/markdown",
author_email="eugen.wintersberger@desy.de, dominik.kriegner@gmail.com",
maintainer="Dominik Kriegner",
maintainer_email="dominik.kriegner@gmail.com",
package_dir={'': 'lib'},
packages=find_packages('lib'),
package_data={
"xrayutilities": ["VERSION", "*.conf"],
"xrayutilities.materials": [os.path.join("data", "*")]
},
python_requires='~=3.6',
setup_requires=['numpy', 'scipy', 'h5py'],
install_requires=['numpy>=1.9.2', 'scipy>=0.13.0', 'h5py'],
extras_require={
'plot': ["matplotlib>=3.1.0"],
'fit': ["lmfit>=1.0.1"],
},
include_dirs=[numpy.get_include()],
ext_modules=[extmodul],
cmdclass=cmdclass,
url="https://xrayutilities.sourceforge.io",
license="GPLv2",
script_args=args
)