blob: b36a43987ed29b5d20b607418e15cb77e3468dd8 [file] [log] [blame]
Cosimo Lupob2f6c6d2015-10-01 12:57:50 +01001try:
2 import setuptools
3except:
4 pass
Cosimo Lupoc3540e22015-08-10 18:01:29 +01005import distutils
Cosimo Lupo77c23992015-03-31 09:30:56 +01006from distutils.core import setup, Extension
7from distutils.command.build_ext import build_ext
8from distutils.cmd import Command
9import platform
Cosimo Lupod2c8b272015-08-11 10:38:20 +010010import os
11import re
Cosimo Lupo77c23992015-03-31 09:30:56 +010012
13
Cosimo Lupod2c8b272015-08-11 10:38:20 +010014CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
15
Cosimo Lupoc3540e22015-08-10 18:01:29 +010016
Cosimo Lupod2c8b272015-08-11 10:38:20 +010017def get_version():
Eugene Kliuchnikov2c2d5572016-08-22 15:44:12 +020018 """ Return BROTLI_VERSION string as defined in 'common/version.h' file. """
19 brotlimodule = os.path.join(CURR_DIR, 'common', 'version.h')
20 version = 0
Cosimo Lupod2c8b272015-08-11 10:38:20 +010021 with open(brotlimodule, 'r') as f:
22 for line in f:
Eugene Kliuchnikovcedddde2016-08-22 15:59:08 +020023 m = re.match(r'#define\sBROTLI_VERSION\s+0x([0-9a-fA-F]+)', line)
Cosimo Lupod2c8b272015-08-11 10:38:20 +010024 if m:
Eugene Kliuchnikov2c2d5572016-08-22 15:44:12 +020025 version = int(m.group(1), 16)
26 if version == 0:
27 return ""
28 return "{0}.{1}.{2}".format(version >> 24, (version >> 12) & 0xFFF, version & 0xFFF)
Cosimo Lupod2c8b272015-08-11 10:38:20 +010029
30
Cosimo Lupo77c23992015-03-31 09:30:56 +010031class TestCommand(Command):
32 """ Run all *_test.py scripts in 'tests' folder with the same Python
33 interpreter used to run setup.py.
34 """
35
36 user_options = []
37
38 def initialize_options(self):
39 pass
40
41 def finalize_options(self):
42 pass
43
44 def run(self):
Cosimo Lupod2c8b272015-08-11 10:38:20 +010045 import sys, subprocess, glob
Cosimo Lupo77c23992015-03-31 09:30:56 +010046
Cosimo Lupod2c8b272015-08-11 10:38:20 +010047 test_dir = os.path.join(CURR_DIR, 'python', 'tests')
Cosimo Lupo77c23992015-03-31 09:30:56 +010048 os.chdir(test_dir)
49
50 for test in glob.glob("*_test.py"):
51 try:
52 subprocess.check_call([sys.executable, test])
53 except subprocess.CalledProcessError:
54 raise SystemExit(1)
55
56
57class BuildExt(build_ext):
58 def get_source_files(self):
59 filenames = build_ext.get_source_files(self)
60 for ext in self.extensions:
61 filenames.extend(ext.depends)
62 return filenames
63
64 def build_extension(self, ext):
65 c_sources = []
66 cxx_sources = []
67 for source in ext.sources:
68 if source.endswith(".c"):
69 c_sources.append(source)
70 else:
71 cxx_sources.append(source)
72 extra_args = ext.extra_compile_args or []
73
74 objects = []
75 for lang, sources in (("c", c_sources), ("c++", cxx_sources)):
Cosimo Lupo8b2ca8e2015-12-08 12:33:06 +000076 if lang == "c++":
77 if self.compiler.compiler_type == "msvc":
Cosimo Lupo77c23992015-03-31 09:30:56 +010078 extra_args.append("/EHsc")
79
80 macros = ext.define_macros[:]
81 if platform.system() == "Darwin":
82 macros.append(("OS_MACOSX", "1"))
Cosimo Lupo54baf432015-08-10 18:04:30 +010083 elif self.compiler.compiler_type == "mingw32":
84 # On Windows Python 2.7, pyconfig.h defines "hypot" as "_hypot",
85 # This clashes with GCC's cmath, and causes compilation errors when
86 # building under MinGW: http://bugs.python.org/issue11566
87 macros.append(("_hypot", "hypot"))
Cosimo Lupo77c23992015-03-31 09:30:56 +010088 for undef in ext.undef_macros:
89 macros.append((undef,))
90
91 objs = self.compiler.compile(sources,
92 output_dir=self.build_temp,
93 macros=macros,
94 include_dirs=ext.include_dirs,
95 debug=self.debug,
96 extra_postargs=extra_args,
97 depends=ext.depends)
98 objects.extend(objs)
99
100 self._built_objects = objects[:]
101 if ext.extra_objects:
102 objects.extend(ext.extra_objects)
103 extra_args = ext.extra_link_args or []
Cosimo Lupo54baf432015-08-10 18:04:30 +0100104 # when using GCC on Windows, we statically link libgcc and libstdc++,
105 # so that we don't need to package extra DLLs
106 if self.compiler.compiler_type == "mingw32":
107 extra_args.extend(['-static-libgcc', '-static-libstdc++'])
Cosimo Lupo77c23992015-03-31 09:30:56 +0100108
109 ext_path = self.get_ext_fullpath(ext.name)
110 # Detect target language, if not provided
111 language = ext.language or self.compiler.detect_language(sources)
112
113 self.compiler.link_shared_object(
114 objects, ext_path,
115 libraries=self.get_libraries(ext),
116 library_dirs=ext.library_dirs,
117 runtime_library_dirs=ext.runtime_library_dirs,
118 extra_postargs=extra_args,
119 export_symbols=self.get_export_symbols(ext),
120 debug=self.debug,
121 build_temp=self.build_temp,
122 target_lang=language)
123
124brotli = Extension("brotli",
125 sources=[
126 "python/brotlimodule.cc",
Eugene Kliuchnikov11d13372016-06-03 12:02:01 +0200127 "common/dictionary.c",
128 "dec/bit_reader.c",
129 "dec/decode.c",
130 "dec/huffman.c",
131 "dec/state.c",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200132 "enc/backward_references.c",
133 "enc/bit_cost.c",
134 "enc/block_splitter.c",
135 "enc/brotli_bit_stream.c",
136 "enc/cluster.c",
137 "enc/compress_fragment.c",
138 "enc/compress_fragment_two_pass.c",
139 "enc/encode.c",
140 "enc/entropy_encode.c",
141 "enc/histogram.c",
142 "enc/literal_cost.c",
143 "enc/memory.c",
144 "enc/metablock.c",
145 "enc/static_dict.c",
146 "enc/utf8_util.c",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100147 ],
148 depends=[
Eugene Kliuchnikov11d13372016-06-03 12:02:01 +0200149 "common/constants.h",
150 "common/dictionary.h",
151 "common/port.h",
Eugene Kliuchnikov2c2d5572016-08-22 15:44:12 +0200152 "common/version.h",
Eugene Kliuchnikov11d13372016-06-03 12:02:01 +0200153 "dec/bit_reader.h",
154 "dec/context.h",
Eugene Kliuchnikov11d13372016-06-03 12:02:01 +0200155 "dec/huffman.h",
156 "dec/port.h",
157 "dec/prefix.h",
158 "dec/state.h",
159 "dec/streams.h",
160 "dec/transform.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100161 "enc/backward_references.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200162 "enc/backward_references_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100163 "enc/bit_cost.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200164 "enc/bit_cost_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100165 "enc/block_splitter.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200166 "enc/block_splitter_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100167 "enc/brotli_bit_stream.h",
168 "enc/cluster.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200169 "enc/cluster_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100170 "enc/command.h",
Zoltan Szabadka47f1eab2016-01-11 12:05:18 +0100171 "enc/compress_fragment.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200172 "enc/compress_fragment_two_pass.h"
Cosimo Lupo77c23992015-03-31 09:30:56 +0100173 "enc/context.h",
Zoltan Szabadkae91a4492015-04-23 15:55:43 +0200174 "enc/dictionary_hash.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100175 "enc/entropy_encode.h",
Zoltan Szabadka47f1eab2016-01-11 12:05:18 +0100176 "enc/entropy_encode_static.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100177 "enc/fast_log.h",
178 "enc/find_match_length.h",
179 "enc/hash.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200180 "enc/hash_longest_match_inc.h",
181 "enc/hash_longest_match_quickly_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100182 "enc/histogram.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200183 "enc/histogram_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100184 "enc/literal_cost.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200185 "enc/memory.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100186 "enc/metablock.h",
Eugene Kliuchnikovdb3a1162016-06-13 15:22:13 +0200187 "enc/metablock_inc.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100188 "enc/port.h",
189 "enc/prefix.h",
190 "enc/ringbuffer.h",
191 "enc/static_dict.h",
Zoltan Szabadka66098832015-06-12 16:45:17 +0200192 "enc/static_dict_lut.h",
Zoltan Szabadka4c375662015-10-01 15:10:42 +0200193 "enc/utf8_util.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100194 "enc/write_bits.h",
Eugene Kliuchnikov403729c2016-08-22 13:59:21 +0200195 "public/decode.h",
196 "public/encode.h",
197 "public/types.h",
Cosimo Lupo77c23992015-03-31 09:30:56 +0100198 ],
199 language="c++",
200 )
201
202setup(
203 name="Brotli",
Cosimo Lupod2c8b272015-08-11 10:38:20 +0100204 version=get_version(),
Cosimo Lupo77c23992015-03-31 09:30:56 +0100205 url="https://github.com/google/brotli",
206 description="Python binding of the Brotli compression library",
207 author="Khaled Hosny",
208 author_email="khaledhosny@eglug.org",
209 license="Apache 2.0",
Cosimo Lupo18a29542015-10-06 12:23:57 +0100210 classifiers=[
211 'Development Status :: 4 - Beta',
212 'Environment :: Console',
213 'Intended Audience :: Developers',
214 'License :: OSI Approved :: Apache Software License',
215 'Operating System :: MacOS :: MacOS X',
216 'Operating System :: Microsoft :: Windows',
217 'Operating System :: POSIX :: Linux',
218 'Programming Language :: C',
219 'Programming Language :: C++',
220 'Programming Language :: Python',
221 'Programming Language :: Python :: 2',
222 'Programming Language :: Python :: 2.7',
223 'Programming Language :: Python :: 3',
224 'Programming Language :: Python :: 3.3',
225 'Programming Language :: Python :: 3.4',
226 'Programming Language :: Python :: 3.5',
227 'Programming Language :: Unix Shell',
228 'Topic :: Software Development :: Libraries',
229 'Topic :: Software Development :: Libraries :: Python Modules',
230 'Topic :: System :: Archiving',
231 'Topic :: System :: Archiving :: Compression',
232 'Topic :: Text Processing :: Fonts',
233 'Topic :: Utilities',
234 ],
Cosimo Lupo77c23992015-03-31 09:30:56 +0100235 ext_modules=[brotli],
236 cmdclass={
237 'build_ext': BuildExt,
238 'test': TestCommand
239 },
240)