1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-25 17:27:31 +00:00
borg/setup.py
Thomas Waldmann 55314f807e drop support for python 3.5, fixes #3919
if you do not have python 3.6.x, you can still use borg 1.1.x or 1.0.x.

another option is to use the fat binary from github releases, which
includes python 3.6 and all other stuff needed.
2018-06-30 21:02:19 +02:00

305 lines
12 KiB
Python

# -*- encoding: utf-8 *-*
import os
import io
import re
import sys
from collections import OrderedDict
from datetime import datetime
from glob import glob
try:
import multiprocessing
except ImportError:
multiprocessing = None
from distutils.command.clean import clean
from setuptools.command.build_ext import build_ext
from setuptools import setup, find_packages, Extension
from setuptools.command.sdist import sdist
try:
from Cython.Build import cythonize
except ImportError:
cythonize = None
import setup_lz4
import setup_zstd
import setup_b2
import setup_docs
# True: use the shared liblz4 (>= 1.7.0 / r129) from the system, False: use the bundled lz4 code
prefer_system_liblz4 = True
# True: use the shared libzstd (>= 1.3.0) from the system, False: use the bundled zstd code
prefer_system_libzstd = True
# True: use the shared libb2 from the system, False: use the bundled blake2 code
prefer_system_libb2 = True
cpu_threads = multiprocessing.cpu_count() if multiprocessing else 1
# Are we building on ReadTheDocs?
on_rtd = os.environ.get('READTHEDOCS')
install_requires = [
# we are rather picky about msgpack versions, because a good working msgpack is
# very important for borg, see https://github.com/borgbackup/borg/issues/3753
# as of now, 0.5.6 is the only preferred version of msgpack:
'msgpack==0.5.6',
# if you can't satisfy the above requirement, these are versions that might
# also work ok, IF you make sure to use the COMPILED version of msgpack-python,
# NOT the PURE PYTHON fallback implementation: ==0.5.1, ==0.5.4
# using any other version is not supported by borg development, feel free to
# do it on your own risk (and after own testing).
]
# note for package maintainers: if you package borgbackup for distribution,
# please add llfuse as a *requirement* on all platforms that have a working
# llfuse package. "borg mount" needs llfuse to work.
# if you do not have llfuse, do not require it, most of borgbackup will work.
extras_require = {
# llfuse 1.x should work, llfuse 2.0 will break API
'fuse': [
'llfuse >=1.1, <2.0',
'llfuse >=1.3.4; python_version >="3.7"',
],
}
compress_source = 'src/borg/compress.pyx'
crypto_ll_source = 'src/borg/crypto/low_level.pyx'
crypto_helpers = 'src/borg/crypto/_crypto_helpers.c'
chunker_source = 'src/borg/chunker.pyx'
hashindex_source = 'src/borg/hashindex.pyx'
item_source = 'src/borg/item.pyx'
checksums_source = 'src/borg/algorithms/checksums.pyx'
platform_posix_source = 'src/borg/platform/posix.pyx'
platform_linux_source = 'src/borg/platform/linux.pyx'
platform_darwin_source = 'src/borg/platform/darwin.pyx'
platform_freebsd_source = 'src/borg/platform/freebsd.pyx'
cython_sources = [
compress_source,
crypto_ll_source,
chunker_source,
hashindex_source,
item_source,
checksums_source,
platform_posix_source,
platform_linux_source,
platform_freebsd_source,
platform_darwin_source,
]
if cythonize:
Sdist = sdist
else:
class Sdist(sdist):
def __init__(self, *args, **kwargs):
raise Exception('Cython is required to run sdist')
if not on_rtd and not all(os.path.exists(path) for path in [
compress_source, crypto_ll_source, chunker_source, hashindex_source, item_source, checksums_source,
platform_posix_source, platform_linux_source, platform_freebsd_source, platform_darwin_source]):
raise ImportError('The GIT version of Borg needs Cython. Install Cython or use a released version.')
def detect_openssl(prefixes):
for prefix in prefixes:
filename = os.path.join(prefix, 'include', 'openssl', 'evp.h')
if os.path.exists(filename):
with open(filename, 'rb') as fd:
if b'PKCS5_PBKDF2_HMAC(' in fd.read():
return prefix
include_dirs = []
library_dirs = []
define_macros = []
possible_openssl_prefixes = ['/usr', '/usr/local', '/usr/local/opt/openssl', '/usr/local/ssl', '/usr/local/openssl',
'/usr/local/borg', '/opt/local', '/opt/pkg', ]
if os.environ.get('BORG_OPENSSL_PREFIX'):
possible_openssl_prefixes.insert(0, os.environ.get('BORG_OPENSSL_PREFIX'))
ssl_prefix = detect_openssl(possible_openssl_prefixes)
if not ssl_prefix:
raise Exception('Unable to find OpenSSL >= 1.0 headers. (Looked here: {})'.format(', '.join(possible_openssl_prefixes)))
include_dirs.append(os.path.join(ssl_prefix, 'include'))
library_dirs.append(os.path.join(ssl_prefix, 'lib'))
possible_liblz4_prefixes = ['/usr', '/usr/local', '/usr/local/opt/lz4', '/usr/local/lz4',
'/usr/local/borg', '/opt/local', '/opt/pkg', ]
if os.environ.get('BORG_LIBLZ4_PREFIX'):
possible_liblz4_prefixes.insert(0, os.environ.get('BORG_LIBLZ4_PREFIX'))
liblz4_prefix = setup_lz4.lz4_system_prefix(possible_liblz4_prefixes)
if prefer_system_liblz4 and liblz4_prefix:
print('Detected and preferring liblz4 over bundled LZ4')
define_macros.append(('BORG_USE_LIBLZ4', 'YES'))
liblz4_system = True
else:
liblz4_system = False
possible_libb2_prefixes = ['/usr', '/usr/local', '/usr/local/opt/libb2', '/usr/local/libb2',
'/usr/local/borg', '/opt/local', '/opt/pkg', ]
if os.environ.get('BORG_LIBB2_PREFIX'):
possible_libb2_prefixes.insert(0, os.environ.get('BORG_LIBB2_PREFIX'))
libb2_prefix = setup_b2.b2_system_prefix(possible_libb2_prefixes)
if prefer_system_libb2 and libb2_prefix:
print('Detected and preferring libb2 over bundled BLAKE2')
define_macros.append(('BORG_USE_LIBB2', 'YES'))
libb2_system = True
else:
libb2_system = False
possible_libzstd_prefixes = ['/usr', '/usr/local', '/usr/local/opt/libzstd', '/usr/local/libzstd',
'/usr/local/borg', '/opt/local', '/opt/pkg', ]
if os.environ.get('BORG_LIBZSTD_PREFIX'):
possible_libzstd_prefixes.insert(0, os.environ.get('BORG_LIBZSTD_PREFIX'))
libzstd_prefix = setup_zstd.zstd_system_prefix(possible_libzstd_prefixes)
if prefer_system_libzstd and libzstd_prefix:
print('Detected and preferring libzstd over bundled ZSTD')
define_macros.append(('BORG_USE_LIBZSTD', 'YES'))
libzstd_system = True
else:
libzstd_system = False
with open('README.rst', 'r') as fd:
long_description = fd.read()
# remove header, but have one \n before first headline
start = long_description.find('What is BorgBackup?')
assert start >= 0
long_description = '\n' + long_description[start:]
# remove badges
long_description = re.compile(r'^\.\. start-badges.*^\.\. end-badges', re.M | re.S).sub('', long_description)
# remove unknown directives
long_description = re.compile(r'^\.\. highlight:: \w+$', re.M).sub('', long_description)
def rm(file):
try:
os.unlink(file)
print('rm', file)
except FileNotFoundError:
pass
class Clean(clean):
def run(self):
super().run()
for source in cython_sources:
genc = source.replace('.pyx', '.c')
rm(genc)
compiled_glob = source.replace('.pyx', '.cpython*')
for compiled in sorted(glob(compiled_glob)):
rm(compiled)
cmdclass = {
'build_ext': build_ext,
'build_usage': setup_docs.build_usage,
'build_man': setup_docs.build_man,
'sdist': Sdist,
'clean': Clean,
}
ext_modules = []
if not on_rtd:
compress_ext_kwargs = dict(sources=[compress_source], include_dirs=include_dirs, library_dirs=library_dirs,
define_macros=define_macros)
compress_ext_kwargs = setup_lz4.lz4_ext_kwargs(bundled_path='src/borg/algorithms/lz4',
system_prefix=liblz4_prefix, system=liblz4_system,
**compress_ext_kwargs)
compress_ext_kwargs = setup_zstd.zstd_ext_kwargs(bundled_path='src/borg/algorithms/zstd',
system_prefix=libzstd_prefix, system=libzstd_system,
multithreaded=False, legacy=False, **compress_ext_kwargs)
crypto_ext_kwargs = dict(sources=[crypto_ll_source, crypto_helpers], libraries=['crypto'],
include_dirs=include_dirs, library_dirs=library_dirs, define_macros=define_macros)
crypto_ext_kwargs = setup_b2.b2_ext_kwargs(bundled_path='src/borg/algorithms/blake2',
system_prefix=libb2_prefix, system=libb2_system,
**crypto_ext_kwargs)
ext_modules += [
Extension('borg.compress', **compress_ext_kwargs),
Extension('borg.crypto.low_level', **crypto_ext_kwargs),
Extension('borg.hashindex', [hashindex_source]),
Extension('borg.item', [item_source]),
Extension('borg.chunker', [chunker_source]),
Extension('borg.algorithms.checksums', [checksums_source]),
]
posix_ext = Extension('borg.platform.posix', [platform_posix_source])
linux_ext = Extension('borg.platform.linux', [platform_linux_source], libraries=['acl'])
freebsd_ext = Extension('borg.platform.freebsd', [platform_freebsd_source])
darwin_ext = Extension('borg.platform.darwin', [platform_darwin_source])
if not sys.platform.startswith(('win32', )):
ext_modules.append(posix_ext)
if sys.platform == 'linux':
ext_modules.append(linux_ext)
elif sys.platform.startswith('freebsd'):
ext_modules.append(freebsd_ext)
elif sys.platform == 'darwin':
ext_modules.append(darwin_ext)
# sometimes there's no need to cythonize
# this breaks chained commands like 'clean sdist'
cythonizing = len(sys.argv) > 1 and sys.argv[1] not in ('clean', 'egg_info', '--help-commands', '--version') \
and '--help' not in sys.argv[1:]
if cythonize and cythonizing:
# compile .pyx extensions to .c in parallel
cythonize([posix_ext, linux_ext, freebsd_ext, darwin_ext], nthreads=cpu_threads+1)
ext_modules = cythonize(ext_modules, nthreads=cpu_threads+1)
setup(
name='borgbackup',
use_scm_version={
'write_to': 'src/borg/_version.py',
},
author='The Borg Collective (see AUTHORS file)',
author_email='borgbackup@python.org',
url='https://borgbackup.readthedocs.io/',
description='Deduplicated, encrypted, authenticated and compressed backups',
long_description=long_description,
license='BSD',
platforms=['Linux', 'MacOS X', 'FreeBSD', 'OpenBSD', 'NetBSD', ],
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'Environment :: Console',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: BSD License',
'Operating System :: POSIX :: BSD :: FreeBSD',
'Operating System :: POSIX :: BSD :: OpenBSD',
'Operating System :: POSIX :: BSD :: NetBSD',
'Operating System :: MacOS :: MacOS X',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Topic :: Security :: Cryptography',
'Topic :: System :: Archiving :: Backup',
],
packages=find_packages('src'),
package_dir={'': 'src'},
zip_safe=False,
entry_points={
'console_scripts': [
'borg = borg.archiver:main',
'borgfs = borg.archiver:main',
]
},
# See also the MANIFEST.in file.
# We want to install all the files in the package directories...
include_package_data=True,
# ...except the source files which have been compiled (C extensions):
exclude_package_data={
'': ['*.c', '*.h', '*.pyx', ],
},
cmdclass=cmdclass,
ext_modules=ext_modules,
setup_requires=['setuptools_scm>=1.7'],
install_requires=install_requires,
extras_require=extras_require,
python_requires='>=3.6',
)