rasterio/setup.py
Sean Gillies ee8e35eab7
Rel 1.3.10 take 2 (#3060)
* Require Numpy 2 when building

* Add support for testing Numpy 2/1 compatibility, call import_array()

* Fix job name and specs

* Change to github's docker repo

* Numpy 2 only for python version >= 3.9

* Add other test modules

* Delete source checkout before running tests

* Eliminate last use of pkg_resources

* Update change log and version

* Update change log again.

* Remove duplicated installs

* Disallow rotated rasters for merge 1.3.10

Resolves #3066

* This is 1.3.10

* Pin to 2.0.0rc1 exactly for this release
2024-04-15 12:29:53 -06:00

335 lines
11 KiB
Python
Executable File

#!/usr/bin/env python
# Two environmental variables influence this script.
#
# GDAL_CONFIG: the path to a gdal-config program that points to GDAL headers,
# libraries, and data files.
#
# PACKAGE_DATA: if defined, GDAL and PROJ4 data files will be copied into the
# source or binary distribution. This is essential when creating self-contained
# binary wheels.
import copy
import itertools
import logging
import os
import platform
import pprint
import shutil
from subprocess import check_output
import sys
from pkg_resources import parse_version
from setuptools import setup
from setuptools.extension import Extension
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
log = logging.getLogger()
def copy_data_tree(datadir, destdir):
try:
shutil.rmtree(destdir)
except OSError:
pass
shutil.copytree(datadir, destdir)
# python -W all setup.py ...
if "all" in sys.warnoptions:
log.level = logging.DEBUG
# Parse the version from the rasterio module.
with open("rasterio/__init__.py") as f:
for line in f:
if line.find("__version__") >= 0:
version = line.split("=")[1].strip()
version = version.strip('"')
version = version.strip("'")
continue
with open("VERSION.txt", "w") as f:
f.write(version)
# Use Cython if available.
try:
from Cython.Build import cythonize
except ImportError:
raise SystemExit(
"ERROR: Cython.Build.cythonize not found. "
"Cython is required to build rasterio.")
# By default we'll try to get options via gdal-config. On systems without,
# options will need to be set in setup.cfg or on the setup command line.
include_dirs = []
library_dirs = []
libraries = []
extra_link_args = []
gdal2plus = False
gdal_output = [None] * 4
gdalversion = None
gdal_major_version = 0
gdal_minor_version = 0
gdal_patch_version = 0
try:
import numpy as np
include_dirs.append(np.get_include())
except ImportError:
raise SystemExit("ERROR: Numpy and its headers are required to run setup().")
if "clean" not in sys.argv:
try:
gdal_config = os.environ.get('GDAL_CONFIG', 'gdal-config')
for i, flag in enumerate(("--cflags", "--libs", "--datadir", "--version")):
gdal_output[i] = check_output([gdal_config, flag]).decode("utf-8").strip()
for item in gdal_output[0].split():
if item.startswith("-I"):
include_dirs.extend(item[2:].split(":"))
for item in gdal_output[1].split():
if item.startswith("-L"):
library_dirs.extend(item[2:].split(":"))
elif item.startswith("-l"):
libraries.append(item[2:])
else:
# e.g. -framework GDAL
extra_link_args.append(item)
# datadir, gdal_output[2] handled below
gdalversion = gdal_output[3]
if gdalversion:
log.info("GDAL API version obtained from gdal-config: %s",
gdalversion)
except Exception as e:
if os.name == "nt":
log.info("Building on Windows requires extra options to setup.py "
"to locate needed GDAL files. More information is available "
"in the README.")
else:
log.warning("Failed to get options via gdal-config: %s", str(e))
# Get GDAL API version from environment variable.
if 'GDAL_VERSION' in os.environ:
gdalversion = os.environ['GDAL_VERSION']
log.info("GDAL API version obtained from environment: %s", gdalversion)
# Get GDAL API version from the command line if specified there.
if '--gdalversion' in sys.argv:
index = sys.argv.index('--gdalversion')
sys.argv.pop(index)
gdalversion = sys.argv.pop(index)
log.info("GDAL API version obtained from command line option: %s",
gdalversion)
if not gdalversion:
raise SystemExit("ERROR: A GDAL API version must be specified. Provide a path "
"to gdal-config using a GDAL_CONFIG environment variable "
"or use a GDAL_VERSION environment variable.")
gdal_major_version, gdal_minor_version, gdal_patch_version = parse_version(
gdalversion
).base_version.split(".", maxsplit=3)
gdal_major_version = int(gdal_major_version)
gdal_minor_version = int(gdal_minor_version)
gdal_patch_version = int(gdal_patch_version)
if (gdal_major_version, gdal_minor_version) < (3, 1):
raise SystemExit("ERROR: GDAL >= 3.1 is required for rasterio. "
"Please upgrade GDAL.")
# Conditionally copy the GDAL data. To be used in conjunction with
# the bdist_wheel command to make self-contained binary wheels.
if os.environ.get('PACKAGE_DATA'):
destdir = 'rasterio/gdal_data'
if gdal_output[2]:
log.info("Copying gdal data from %s" % gdal_output[2])
copy_data_tree(gdal_output[2], destdir)
else:
# check to see if GDAL_DATA is defined
gdal_data = os.environ.get('GDAL_DATA', None)
if gdal_data:
log.info("Copying gdal_data from %s" % gdal_data)
copy_data_tree(gdal_data, destdir)
# Conditionally copy PROJ DATA.
projdatadir = os.environ.get('PROJ_DATA', os.environ.get('PROJ_LIB', '/usr/local/share/proj'))
if os.path.exists(projdatadir):
log.info("Copying proj_data from %s" % projdatadir)
copy_data_tree(projdatadir, 'rasterio/proj_data')
compile_time_env = {
"CTE_GDAL_MAJOR_VERSION": gdal_major_version,
"CTE_GDAL_MINOR_VERSION": gdal_minor_version,
"CTE_GDAL_PATCH_VERSION": gdal_patch_version,
}
ext_options = {
'include_dirs': include_dirs,
'library_dirs': library_dirs,
'libraries': libraries,
'extra_link_args': extra_link_args,
'define_macros': [],
'cython_compile_time_env': compile_time_env
}
if not os.name == "nt":
# These options fail on Windows if using Visual Studio
ext_options['extra_compile_args'] = ['-Wno-unused-parameter',
'-Wno-unused-function']
# Copy extension options for cpp extension modules.
cpp_ext_options = copy.deepcopy(ext_options)
# Remove -std=c++11 from C extension options.
try:
ext_options['extra_link_args'].remove('-std=c++11')
ext_options['extra_compile_args'].remove('-std=c++11')
except Exception:
pass
# GDAL 2.3 and newer requires C++11
if (gdal_major_version, gdal_minor_version) >= (2, 3):
cpp11_flag = '-std=c++11'
# 'extra_compile_args' may not be defined
eca = cpp_ext_options.get('extra_compile_args', [])
if platform.system() == 'Darwin':
if cpp11_flag not in eca:
eca.append(cpp11_flag)
eca += [cpp11_flag, '-mmacosx-version-min=10.9', '-stdlib=libc++']
# TODO: Windows
elif cpp11_flag not in eca:
eca.append(cpp11_flag)
cpp_ext_options['extra_compile_args'] = eca
# Configure optional Cython coverage.
cythonize_options = {"language_level": sys.version_info[0]}
if os.environ.get('CYTHON_COVERAGE'):
cythonize_options['compiler_directives'] = {'linetrace': True}
cythonize_options['annotate'] = True
ext_options['define_macros'].extend(
[('CYTHON_TRACE', '1'), ('CYTHON_TRACE_NOGIL', '1')])
log.debug('ext_options:\n%s', pprint.pformat(ext_options))
ext_modules = None
if "clean" not in sys.argv:
extensions = [
Extension(
'rasterio._base', ['rasterio/_base.pyx'], **ext_options),
Extension(
'rasterio._io', ['rasterio/_io.pyx'], **ext_options),
Extension(
'rasterio._features', ['rasterio/_features.pyx'], **ext_options),
Extension(
'rasterio._env', ['rasterio/_env.pyx'], **ext_options),
Extension(
'rasterio._warp', ['rasterio/_warp.pyx'], **cpp_ext_options),
Extension(
'rasterio._fill', ['rasterio/_fill.pyx'], **cpp_ext_options),
Extension(
'rasterio._err', ['rasterio/_err.pyx'], **ext_options),
Extension(
'rasterio._example', ['rasterio/_example.pyx'], **ext_options),
Extension(
'rasterio._version', ['rasterio/_version.pyx'], **ext_options),
Extension(
'rasterio.crs', ['rasterio/crs.pyx'], **ext_options),
Extension(
'rasterio.shutil', ['rasterio/shutil.pyx'], **ext_options),
Extension(
'rasterio._transform', ['rasterio/_transform.pyx'], **ext_options)]
if gdal_major_version >= 3:
# VSI Plugins are only 3.0+
extensions.append(
Extension(
'rasterio._filepath', ['rasterio/_filepath.pyx'], **cpp_ext_options))
ext_modules = cythonize(
extensions, quiet=True, compile_time_env=compile_time_env, **cythonize_options)
with open("README.rst", encoding="utf-8") as f:
readme = f.read()
# Runtime requirements.
inst_reqs = [
"affine",
"attrs",
"certifi",
"click>=4.0",
"cligj>=0.5",
'importlib-metadata;python_version<"3.10"',
"numpy",
"snuggs>=1.4.1",
"click-plugins",
"setuptools",
]
extra_reqs = {
"docs": ["ghp-import", "numpydoc", "sphinx", "sphinx-rtd-theme"],
"ipython": ["ipython>=2.0"],
"plot": ["matplotlib"],
"s3": ["boto3>=1.2.4"],
"test": [
"boto3>=1.2.4",
"hypothesis",
"packaging",
"pytest-cov>=2.2.0",
"pytest>=2.8.2",
"shapely ; python_version < '3.12'",
],
}
# Add all extra requirements
extra_reqs["all"] = list(set(itertools.chain(*extra_reqs.values())))
setup_args = dict(
name="rasterio",
version=version,
description="Fast and direct raster I/O for use with Numpy and SciPy",
long_description=readme,
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: BSD License",
"Programming Language :: C",
"Programming Language :: Cython",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3",
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Scientific/Engineering :: GIS",
],
keywords="raster gdal",
author="Sean Gillies",
author_email="sean@mapbox.com",
url="https://github.com/rasterio/rasterio",
license="BSD",
package_dir={"": "."},
packages=["rasterio", "rasterio.rio"],
include_package_data=True,
ext_modules=ext_modules,
zip_safe=False,
install_requires=inst_reqs,
extras_require=extra_reqs,
python_requires=">=3.8",
)
if os.environ.get('PACKAGE_DATA'):
setup_args['package_data'] = {'rasterio': ['gdal_data/*', 'proj_data/*']}
setup(**setup_args)