Blob Blame History Raw
diff --git a/setup.py b/setup.py
index 8cdaef3..d79bf1c 100644
--- a/setup.py
+++ b/setup.py
@@ -26,6 +26,8 @@ prefer_system_libzstd = True
 prefer_system_libb2 = True
 
 # prefer_system_msgpack is another option, but you need to set it in src/borg/helpers.py.
+prefer_system_msgpack = bool(os.environ.get('BORG_EXTERNAL_MSGPACK'))
+
 
 min_python = (3, 4)
 my_python = sys.version_info
@@ -38,6 +40,20 @@ if my_python < min_python:
 on_rtd = os.environ.get('READTHEDOCS')
 
 install_requires = []
+if prefer_system_msgpack:
+    install_requires.extend([
+        # 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
+        # best versions seem to be 0.4.6, 0.4.7, 0.4.8 and 0.5.6:
+        'msgpack-python >=0.4.6, <=0.5.6, !=0.5.0, !=0.5.1, !=0.5.2, !=0.5.3, !=0.5.4, !=0.5.5',
+        # 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
+        #
+        # Please note:
+        # using any other version is not supported by borg development and
+        # any feedback related to issues caused by this will be ignored.
+    ])
 
 # note for package maintainers: if you package borgbackup for distribution,
 # please add llfuse as a *requirement* on all platforms that have a working
@@ -98,9 +114,9 @@ cython_c_sources = [
 
 cython_cpp_sources = [
     # these .pyx will get compiled to .cpp
-    msgpack_packer_source,
-    msgpack_unpacker_source,
 ]
+if not prefer_system_msgpack:
+    cython_cpp_sources.extend([msgpack_packer_source, msgpack_unpacker_source])
 
 try:
     from Cython.Distutils import build_ext
@@ -130,9 +146,12 @@ try:
                 'src/borg/platform/linux.c',
                 'src/borg/platform/freebsd.c',
                 'src/borg/platform/darwin.c',
-                'src/borg/algorithms/msgpack/_packer.cpp',
-                'src/borg/algorithms/msgpack/_unpacker.cpp',
             ])
+            if not prefer_system_msgpack:
+                self.filelist.extend([
+                    'src/borg/algorithms/msgpack/_packer.cpp',
+                    'src/borg/algorithms/msgpack/_unpacker.cpp',
+                ])
             super().make_distribution()
 
 except ImportError:
@@ -154,11 +173,15 @@ except ImportError:
     msgpack_packer_source = msgpack_packer_source.replace('.pyx', '.cpp')
     msgpack_unpacker_source = msgpack_unpacker_source.replace('.pyx', '.cpp')
 
-    from distutils.command.build_ext import build_ext
-    if not on_rtd and not all(os.path.exists(path) for path in [
+    cythonized_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,
-        msgpack_packer_source, msgpack_unpacker_source]):
+    ]
+    if not prefer_system_msgpack:
+        cythonized_sources.extend([msgpack_packer_source, msgpack_unpacker_source])
+
+    from distutils.command.build_ext import build_ext
+    if not on_rtd and not all(os.path.exists(path) for path in cythonized_sources):
         raise ImportError('The GIT version of Borg needs Cython. Install Cython or use a released version.')
 
 
@@ -801,26 +824,29 @@ if not on_rtd:
                                                system_prefix=libb2_prefix, system=libb2_system,
                                                **crypto_ext_kwargs)
 
-    msgpack_endian = '__BIG_ENDIAN__' if (sys.byteorder == 'big') else '__LITTLE_ENDIAN__'
-    msgpack_macros = [(msgpack_endian, '1')]
-    msgpack_packer_ext_kwargs = dict(
-        sources=[msgpack_packer_source],
-        include_dirs=include_dirs,
-        library_dirs=library_dirs,
-        define_macros=msgpack_macros,
-        language='c++',
-    )
-    msgpack_unpacker_ext_kwargs = dict(
-        sources=[msgpack_unpacker_source],
-        include_dirs=include_dirs,
-        library_dirs=library_dirs,
-        define_macros=msgpack_macros,
-        language='c++',
-    )
+    if not prefer_system_msgpack:
+        msgpack_endian = '__BIG_ENDIAN__' if (sys.byteorder == 'big') else '__LITTLE_ENDIAN__'
+        msgpack_macros = [(msgpack_endian, '1')]
+        msgpack_packer_ext_kwargs = dict(
+            sources=[msgpack_packer_source],
+            include_dirs=include_dirs,
+            library_dirs=library_dirs,
+            define_macros=msgpack_macros,
+            language='c++',
+        )
+        msgpack_unpacker_ext_kwargs = dict(
+            sources=[msgpack_unpacker_source],
+            include_dirs=include_dirs,
+            library_dirs=library_dirs,
+            define_macros=msgpack_macros,
+            language='c++',
+        )
+        ext_modules += [
+            Extension('borg.algorithms.msgpack._packer', **msgpack_packer_ext_kwargs),
+            Extension('borg.algorithms.msgpack._unpacker', **msgpack_unpacker_ext_kwargs),
+        ]
 
     ext_modules += [
-        Extension('borg.algorithms.msgpack._packer', **msgpack_packer_ext_kwargs),
-        Extension('borg.algorithms.msgpack._unpacker', **msgpack_unpacker_ext_kwargs),
         Extension('borg.compress', **compress_ext_kwargs),
         Extension('borg.crypto.low_level', **crypto_ext_kwargs),
         Extension('borg.hashindex', [hashindex_source]),