Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 1 | # Copyright 2015 The Brotli Authors. All rights reserved. |
| 2 | # |
| 3 | # Distributed under MIT license. |
| 4 | # See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
| 5 | |
| 6 | import os |
| 7 | import platform |
| 8 | import re |
Alex Nicksay | 89a5b6e | 2016-12-20 08:40:47 -0500 | [diff] [blame] | 9 | import unittest |
| 10 | |
Cosimo Lupo | b2f6c6d | 2015-10-01 12:57:50 +0100 | [diff] [blame] | 11 | try: |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 12 | from setuptools import Extension |
| 13 | from setuptools import setup |
Cosimo Lupo | b2f6c6d | 2015-10-01 12:57:50 +0100 | [diff] [blame] | 14 | except: |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 15 | from distutils.core import Extension |
| 16 | from distutils.core import setup |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 17 | from distutils.command.build_ext import build_ext |
Cosimo Lupo | 4f455ca | 2017-08-23 19:45:13 +0100 | [diff] [blame] | 18 | from distutils import errors |
| 19 | from distutils import dep_util |
| 20 | from distutils import log |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 21 | |
| 22 | |
Cosimo Lupo | d2c8b27 | 2015-08-11 10:38:20 +0100 | [diff] [blame] | 23 | CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) |
| 24 | |
Cosimo Lupo | c3540e2 | 2015-08-10 18:01:29 +0100 | [diff] [blame] | 25 | |
Cosimo Lupo | d2c8b27 | 2015-08-11 10:38:20 +0100 | [diff] [blame] | 26 | def get_version(): |
Eugene Kliuchnikov | 2c2d557 | 2016-08-22 15:44:12 +0200 | [diff] [blame] | 27 | """ Return BROTLI_VERSION string as defined in 'common/version.h' file. """ |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 28 | version_file_path = os.path.join(CURR_DIR, 'c', 'common', 'version.h') |
Eugene Kliuchnikov | 2c2d557 | 2016-08-22 15:44:12 +0200 | [diff] [blame] | 29 | version = 0 |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 30 | with open(version_file_path, 'r') as f: |
Cosimo Lupo | d2c8b27 | 2015-08-11 10:38:20 +0100 | [diff] [blame] | 31 | for line in f: |
Eugene Kliuchnikov | cedddde | 2016-08-22 15:59:08 +0200 | [diff] [blame] | 32 | m = re.match(r'#define\sBROTLI_VERSION\s+0x([0-9a-fA-F]+)', line) |
Cosimo Lupo | d2c8b27 | 2015-08-11 10:38:20 +0100 | [diff] [blame] | 33 | if m: |
Eugene Kliuchnikov | 2c2d557 | 2016-08-22 15:44:12 +0200 | [diff] [blame] | 34 | version = int(m.group(1), 16) |
| 35 | if version == 0: |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 36 | return '' |
| 37 | # Semantic version is calculated as (MAJOR << 24) | (MINOR << 12) | PATCH. |
| 38 | major = version >> 24 |
| 39 | minor = (version >> 12) & 0xFFF |
| 40 | patch = version & 0xFFF |
| 41 | return '{0}.{1}.{2}'.format(major, minor, patch) |
Cosimo Lupo | d2c8b27 | 2015-08-11 10:38:20 +0100 | [diff] [blame] | 42 | |
| 43 | |
Alex Nicksay | 89a5b6e | 2016-12-20 08:40:47 -0500 | [diff] [blame] | 44 | def get_test_suite(): |
| 45 | test_loader = unittest.TestLoader() |
| 46 | test_suite = test_loader.discover('python', pattern='*_test.py') |
| 47 | return test_suite |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 48 | |
| 49 | |
| 50 | class BuildExt(build_ext): |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 51 | |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 52 | def get_source_files(self): |
| 53 | filenames = build_ext.get_source_files(self) |
| 54 | for ext in self.extensions: |
| 55 | filenames.extend(ext.depends) |
| 56 | return filenames |
| 57 | |
| 58 | def build_extension(self, ext): |
Cosimo Lupo | 4f455ca | 2017-08-23 19:45:13 +0100 | [diff] [blame] | 59 | if ext.sources is None or not isinstance(ext.sources, (list, tuple)): |
| 60 | raise errors.DistutilsSetupError( |
| 61 | "in 'ext_modules' option (extension '%s'), " |
| 62 | "'sources' must be present and must be " |
| 63 | "a list of source filenames" % ext.name) |
| 64 | |
| 65 | ext_path = self.get_ext_fullpath(ext.name) |
| 66 | depends = ext.sources + ext.depends |
| 67 | if not (self.force or dep_util.newer_group(depends, ext_path, 'newer')): |
| 68 | log.debug("skipping '%s' extension (up-to-date)", ext.name) |
| 69 | return |
| 70 | else: |
| 71 | log.info("building '%s' extension", ext.name) |
| 72 | |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 73 | c_sources = [] |
| 74 | cxx_sources = [] |
| 75 | for source in ext.sources: |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 76 | if source.endswith('.c'): |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 77 | c_sources.append(source) |
| 78 | else: |
| 79 | cxx_sources.append(source) |
| 80 | extra_args = ext.extra_compile_args or [] |
| 81 | |
| 82 | objects = [] |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 83 | for lang, sources in (('c', c_sources), ('c++', cxx_sources)): |
| 84 | if lang == 'c++': |
| 85 | if self.compiler.compiler_type == 'msvc': |
| 86 | extra_args.append('/EHsc') |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 87 | |
| 88 | macros = ext.define_macros[:] |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 89 | if platform.system() == 'Darwin': |
| 90 | macros.append(('OS_MACOSX', '1')) |
| 91 | elif self.compiler.compiler_type == 'mingw32': |
Cosimo Lupo | 54baf43 | 2015-08-10 18:04:30 +0100 | [diff] [blame] | 92 | # On Windows Python 2.7, pyconfig.h defines "hypot" as "_hypot", |
| 93 | # This clashes with GCC's cmath, and causes compilation errors when |
| 94 | # building under MinGW: http://bugs.python.org/issue11566 |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 95 | macros.append(('_hypot', 'hypot')) |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 96 | for undef in ext.undef_macros: |
| 97 | macros.append((undef,)) |
| 98 | |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 99 | objs = self.compiler.compile( |
| 100 | sources, |
| 101 | output_dir=self.build_temp, |
| 102 | macros=macros, |
| 103 | include_dirs=ext.include_dirs, |
| 104 | debug=self.debug, |
| 105 | extra_postargs=extra_args, |
| 106 | depends=ext.depends) |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 107 | objects.extend(objs) |
| 108 | |
| 109 | self._built_objects = objects[:] |
| 110 | if ext.extra_objects: |
| 111 | objects.extend(ext.extra_objects) |
| 112 | extra_args = ext.extra_link_args or [] |
Cosimo Lupo | 54baf43 | 2015-08-10 18:04:30 +0100 | [diff] [blame] | 113 | # when using GCC on Windows, we statically link libgcc and libstdc++, |
| 114 | # so that we don't need to package extra DLLs |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 115 | if self.compiler.compiler_type == 'mingw32': |
Cosimo Lupo | 54baf43 | 2015-08-10 18:04:30 +0100 | [diff] [blame] | 116 | extra_args.extend(['-static-libgcc', '-static-libstdc++']) |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 117 | |
| 118 | ext_path = self.get_ext_fullpath(ext.name) |
| 119 | # Detect target language, if not provided |
| 120 | language = ext.language or self.compiler.detect_language(sources) |
| 121 | |
| 122 | self.compiler.link_shared_object( |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 123 | objects, |
| 124 | ext_path, |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 125 | libraries=self.get_libraries(ext), |
| 126 | library_dirs=ext.library_dirs, |
| 127 | runtime_library_dirs=ext.runtime_library_dirs, |
| 128 | extra_postargs=extra_args, |
| 129 | export_symbols=self.get_export_symbols(ext), |
| 130 | debug=self.debug, |
| 131 | build_temp=self.build_temp, |
| 132 | target_lang=language) |
| 133 | |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 134 | |
| 135 | NAME = 'Brotli' |
| 136 | |
| 137 | VERSION = get_version() |
| 138 | |
| 139 | URL = 'https://github.com/google/brotli' |
| 140 | |
| 141 | DESCRIPTION = 'Python bindings for the Brotli compression library' |
| 142 | |
| 143 | AUTHOR = 'The Brotli Authors' |
| 144 | |
| 145 | LICENSE = 'Apache 2.0' |
| 146 | |
| 147 | PLATFORMS = ['Posix', 'MacOS X', 'Windows'] |
| 148 | |
| 149 | CLASSIFIERS = [ |
| 150 | 'Development Status :: 4 - Beta', |
| 151 | 'Environment :: Console', |
| 152 | 'Intended Audience :: Developers', |
| 153 | 'License :: OSI Approved :: Apache Software License', |
| 154 | 'Operating System :: MacOS :: MacOS X', |
| 155 | 'Operating System :: Microsoft :: Windows', |
| 156 | 'Operating System :: POSIX :: Linux', |
| 157 | 'Programming Language :: C', |
| 158 | 'Programming Language :: C++', |
| 159 | 'Programming Language :: Python', |
| 160 | 'Programming Language :: Python :: 2', |
| 161 | 'Programming Language :: Python :: 2.7', |
| 162 | 'Programming Language :: Python :: 3', |
| 163 | 'Programming Language :: Python :: 3.3', |
| 164 | 'Programming Language :: Python :: 3.4', |
| 165 | 'Programming Language :: Python :: 3.5', |
| 166 | 'Programming Language :: Unix Shell', |
| 167 | 'Topic :: Software Development :: Libraries', |
| 168 | 'Topic :: Software Development :: Libraries :: Python Modules', |
| 169 | 'Topic :: System :: Archiving', |
| 170 | 'Topic :: System :: Archiving :: Compression', |
| 171 | 'Topic :: Text Processing :: Fonts', |
| 172 | 'Topic :: Utilities', |
| 173 | ] |
| 174 | |
Alex Nicksay | f7b5b3d | 2016-09-28 17:26:00 -0400 | [diff] [blame] | 175 | PACKAGE_DIR = {'': 'python'} |
| 176 | |
| 177 | PY_MODULES = ['brotli'] |
| 178 | |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 179 | EXT_MODULES = [ |
| 180 | Extension( |
Alex Nicksay | f7b5b3d | 2016-09-28 17:26:00 -0400 | [diff] [blame] | 181 | '_brotli', |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 182 | sources=[ |
Alex Nicksay | f7b5b3d | 2016-09-28 17:26:00 -0400 | [diff] [blame] | 183 | 'python/_brotli.cc', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 184 | 'c/common/dictionary.c', |
Eugene Kliuchnikov | 35e69fc | 2018-02-26 09:04:36 -0500 | [diff] [blame] | 185 | 'c/common/transform.c', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 186 | 'c/dec/bit_reader.c', |
| 187 | 'c/dec/decode.c', |
| 188 | 'c/dec/huffman.c', |
| 189 | 'c/dec/state.c', |
| 190 | 'c/enc/backward_references.c', |
| 191 | 'c/enc/backward_references_hq.c', |
| 192 | 'c/enc/bit_cost.c', |
| 193 | 'c/enc/block_splitter.c', |
| 194 | 'c/enc/brotli_bit_stream.c', |
| 195 | 'c/enc/cluster.c', |
| 196 | 'c/enc/compress_fragment.c', |
| 197 | 'c/enc/compress_fragment_two_pass.c', |
| 198 | 'c/enc/dictionary_hash.c', |
| 199 | 'c/enc/encode.c', |
Eugene Kliuchnikov | 35e69fc | 2018-02-26 09:04:36 -0500 | [diff] [blame] | 200 | 'c/enc/encoder_dict.c', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 201 | 'c/enc/entropy_encode.c', |
| 202 | 'c/enc/histogram.c', |
| 203 | 'c/enc/literal_cost.c', |
| 204 | 'c/enc/memory.c', |
| 205 | 'c/enc/metablock.c', |
| 206 | 'c/enc/static_dict.c', |
| 207 | 'c/enc/utf8_util.c', |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 208 | ], |
| 209 | depends=[ |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 210 | 'c/common/constants.h', |
Eugene Kliuchnikov | 35e69fc | 2018-02-26 09:04:36 -0500 | [diff] [blame] | 211 | 'c/common/context.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 212 | 'c/common/dictionary.h', |
Eugene Kliuchnikov | 35e69fc | 2018-02-26 09:04:36 -0500 | [diff] [blame] | 213 | 'c/common/platform.h', |
| 214 | 'c/common/transform.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 215 | 'c/common/version.h', |
| 216 | 'c/dec/bit_reader.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 217 | 'c/dec/huffman.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 218 | 'c/dec/prefix.h', |
| 219 | 'c/dec/state.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 220 | 'c/enc/backward_references.h', |
| 221 | 'c/enc/backward_references_hq.h', |
| 222 | 'c/enc/backward_references_inc.h', |
| 223 | 'c/enc/bit_cost.h', |
| 224 | 'c/enc/bit_cost_inc.h', |
| 225 | 'c/enc/block_encoder_inc.h', |
| 226 | 'c/enc/block_splitter.h', |
| 227 | 'c/enc/block_splitter_inc.h', |
| 228 | 'c/enc/brotli_bit_stream.h', |
| 229 | 'c/enc/cluster.h', |
| 230 | 'c/enc/cluster_inc.h', |
| 231 | 'c/enc/command.h', |
| 232 | 'c/enc/compress_fragment.h', |
Cosimo Lupo | 4f455ca | 2017-08-23 19:45:13 +0100 | [diff] [blame] | 233 | 'c/enc/compress_fragment_two_pass.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 234 | 'c/enc/dictionary_hash.h', |
Eugene Kliuchnikov | 35e69fc | 2018-02-26 09:04:36 -0500 | [diff] [blame] | 235 | 'c/enc/encoder_dict.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 236 | 'c/enc/entropy_encode.h', |
| 237 | 'c/enc/entropy_encode_static.h', |
| 238 | 'c/enc/fast_log.h', |
| 239 | 'c/enc/find_match_length.h', |
| 240 | 'c/enc/hash.h', |
William A. Kennington III | fc4d345 | 2018-07-09 01:40:08 -0700 | [diff] [blame] | 241 | 'c/enc/hash_composite_inc.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 242 | 'c/enc/hash_forgetful_chain_inc.h', |
| 243 | 'c/enc/hash_longest_match64_inc.h', |
| 244 | 'c/enc/hash_longest_match_inc.h', |
| 245 | 'c/enc/hash_longest_match_quickly_inc.h', |
William A. Kennington III | fc4d345 | 2018-07-09 01:40:08 -0700 | [diff] [blame] | 246 | 'c/enc/hash_rolling_inc.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 247 | 'c/enc/hash_to_binary_tree_inc.h', |
| 248 | 'c/enc/histogram.h', |
| 249 | 'c/enc/histogram_inc.h', |
| 250 | 'c/enc/literal_cost.h', |
| 251 | 'c/enc/memory.h', |
| 252 | 'c/enc/metablock.h', |
| 253 | 'c/enc/metablock_inc.h', |
Eugene Kliuchnikov | 631fe19 | 2018-03-20 17:37:41 +0600 | [diff] [blame] | 254 | 'c/enc/params.h', |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 255 | 'c/enc/prefix.h', |
| 256 | 'c/enc/quality.h', |
| 257 | 'c/enc/ringbuffer.h', |
| 258 | 'c/enc/static_dict.h', |
| 259 | 'c/enc/static_dict_lut.h', |
| 260 | 'c/enc/utf8_util.h', |
| 261 | 'c/enc/write_bits.h', |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 262 | ], |
| 263 | include_dirs=[ |
Eugene Kliuchnikov | 6ece1d8 | 2017-04-23 14:07:08 +0200 | [diff] [blame] | 264 | 'c/include', |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 265 | ], |
| 266 | language='c++'), |
| 267 | ] |
| 268 | |
Alex Nicksay | 89a5b6e | 2016-12-20 08:40:47 -0500 | [diff] [blame] | 269 | TEST_SUITE = 'setup.get_test_suite' |
| 270 | |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 271 | CMD_CLASS = { |
| 272 | 'build_ext': BuildExt, |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 273 | } |
Cosimo Lupo | 77c2399 | 2015-03-31 09:30:56 +0100 | [diff] [blame] | 274 | |
| 275 | setup( |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 276 | name=NAME, |
| 277 | description=DESCRIPTION, |
| 278 | version=VERSION, |
| 279 | url=URL, |
| 280 | author=AUTHOR, |
| 281 | license=LICENSE, |
| 282 | platforms=PLATFORMS, |
| 283 | classifiers=CLASSIFIERS, |
Alex Nicksay | f7b5b3d | 2016-09-28 17:26:00 -0400 | [diff] [blame] | 284 | package_dir=PACKAGE_DIR, |
| 285 | py_modules=PY_MODULES, |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 286 | ext_modules=EXT_MODULES, |
Alex Nicksay | 89a5b6e | 2016-12-20 08:40:47 -0500 | [diff] [blame] | 287 | test_suite=TEST_SUITE, |
Alex Nicksay | 6f55ee6 | 2016-09-28 15:19:49 -0400 | [diff] [blame] | 288 | cmdclass=CMD_CLASS) |