blob: a2026706e4d92599863774d2f3ecc4936a01e893 [file] [log] [blame]
Tamir Duberstein9d9d0b72015-04-11 20:23:45 -07001#! /usr/bin/env python
temporal40ee5512008-07-10 02:12:20 +00002#
3# See README for usage instructions.
Tamir Duberstein5018c432015-05-08 08:48:40 -04004import glob
temporal40ee5512008-07-10 02:12:20 +00005import os
kenton@google.coma6de64a2009-04-18 02:28:15 +00006import subprocess
Tamir Duberstein5018c432015-05-08 08:48:40 -04007import sys
Paul Yang7f3e2372017-01-31 09:17:32 -08008import platform
temporal40ee5512008-07-10 02:12:20 +00009
liujisi@google.com9ced30c2012-08-01 06:22:19 +000010# We must use setuptools, not distutils, because we need to use the
11# namespace_packages option for the "google" package.
Dan O'Reilly3bdfb4b2015-08-20 13:51:26 -040012from setuptools import setup, Extension, find_packages
liujisi@google.com9ced30c2012-08-01 06:22:19 +000013
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070014from distutils.command.clean import clean as _clean
15
16if sys.version_info[0] == 3:
17 # Python 3
18 from distutils.command.build_py import build_py_2to3 as _build_py
19else:
20 # Python 2
21 from distutils.command.build_py import build_py as _build_py
22from distutils.spawn import find_executable
temporal40ee5512008-07-10 02:12:20 +000023
24# Find the Protocol Compiler.
liujisi@google.come34f1f62012-12-05 01:25:12 +000025if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
26 protoc = os.environ['PROTOC']
27elif os.path.exists("../src/protoc"):
temporal40ee5512008-07-10 02:12:20 +000028 protoc = "../src/protoc"
kenton@google.com4152d552009-04-22 03:20:21 +000029elif os.path.exists("../src/protoc.exe"):
30 protoc = "../src/protoc.exe"
kenton@google.com80aa23d2010-09-28 21:58:36 +000031elif os.path.exists("../vsprojects/Debug/protoc.exe"):
32 protoc = "../vsprojects/Debug/protoc.exe"
33elif os.path.exists("../vsprojects/Release/protoc.exe"):
34 protoc = "../vsprojects/Release/protoc.exe"
temporal40ee5512008-07-10 02:12:20 +000035else:
36 protoc = find_executable("protoc")
37
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070038
Jisi Liu4573e112015-03-04 16:45:13 -080039def GetVersion():
40 """Gets the version from google/protobuf/__init__.py
41
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070042 Do not import google.protobuf.__init__ directly, because an installed
43 protobuf library may be loaded instead."""
Jisi Liu4573e112015-03-04 16:45:13 -080044
Jisi Liu4573e112015-03-04 16:45:13 -080045 with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
Behzad Tabibian2bf92b32015-05-07 19:04:56 +020046 exec(version_file.read(), globals())
Jisi Liu4573e112015-03-04 16:45:13 -080047 return __version__
48
49
Feng Xiao8e142682015-05-26 00:11:09 -070050def generate_proto(source, require = True):
temporal40ee5512008-07-10 02:12:20 +000051 """Invokes the Protocol Compiler to generate a _pb2.py from the given
52 .proto file. Does nothing if the output already exists and is newer than
53 the input."""
54
Feng Xiao8e142682015-05-26 00:11:09 -070055 if not require and not os.path.exists(source):
56 return
57
temporal40ee5512008-07-10 02:12:20 +000058 output = source.replace(".proto", "_pb2.py").replace("../src/", "")
59
temporal40ee5512008-07-10 02:12:20 +000060 if (not os.path.exists(output) or
61 (os.path.exists(source) and
62 os.path.getmtime(source) > os.path.getmtime(output))):
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070063 print("Generating %s..." % output)
temporal40ee5512008-07-10 02:12:20 +000064
liujisi@google.com9ced30c2012-08-01 06:22:19 +000065 if not os.path.exists(source):
66 sys.stderr.write("Can't find required file: %s\n" % source)
67 sys.exit(-1)
68
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070069 if protoc is None:
temporal40ee5512008-07-10 02:12:20 +000070 sys.stderr.write(
71 "protoc is not installed nor found in ../src. Please compile it "
72 "or install the binary package.\n")
73 sys.exit(-1)
74
kenton@google.coma6de64a2009-04-18 02:28:15 +000075 protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
76 if subprocess.call(protoc_command) != 0:
temporal40ee5512008-07-10 02:12:20 +000077 sys.exit(-1)
78
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000079def GenerateUnittestProtos():
Adam Cozzetted64a2d92016-06-29 15:23:27 -070080 generate_proto("../src/google/protobuf/any_test.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070081 generate_proto("../src/google/protobuf/map_unittest.proto", False)
Joshua Habermanf1ce60e2016-12-03 11:51:25 -050082 generate_proto("../src/google/protobuf/test_messages_proto3.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -070083 generate_proto("../src/google/protobuf/unittest_arena.proto", False)
84 generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
85 generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070086 generate_proto("../src/google/protobuf/unittest.proto", False)
87 generate_proto("../src/google/protobuf/unittest_custom_options.proto", False)
88 generate_proto("../src/google/protobuf/unittest_import.proto", False)
89 generate_proto("../src/google/protobuf/unittest_import_public.proto", False)
90 generate_proto("../src/google/protobuf/unittest_mset.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -070091 generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070092 generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
93 generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
Jisi Liu46e8ff62015-10-05 11:59:43 -070094 generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
Feng Xiaoe841bac2015-12-11 17:09:20 -080095 generate_proto("google/protobuf/internal/any_test.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070096 generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
97 generate_proto("google/protobuf/internal/descriptor_pool_test2.proto", False)
98 generate_proto("google/protobuf/internal/factory_test1.proto", False)
99 generate_proto("google/protobuf/internal/factory_test2.proto", False)
Adam Cozzetted64a2d92016-06-29 15:23:27 -0700100 generate_proto("google/protobuf/internal/file_options_test.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -0700101 generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
102 generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
103 generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -0700104 generate_proto("google/protobuf/internal/message_set_extensions.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -0700105 generate_proto("google/protobuf/internal/more_extensions.proto", False)
106 generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False)
107 generate_proto("google/protobuf/internal/more_messages.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -0700108 generate_proto("google/protobuf/internal/packed_field_test.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -0700109 generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False)
110 generate_proto("google/protobuf/pyext/python.proto", False)
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000111
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700112
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000113class clean(_clean):
114 def run(self):
115 # Delete generated files in the code tree.
temporal40ee5512008-07-10 02:12:20 +0000116 for (dirpath, dirnames, filenames) in os.walk("."):
117 for filename in filenames:
118 filepath = os.path.join(dirpath, filename)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000119 if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000120 filepath.endswith(".so") or filepath.endswith(".o") or \
Feng Xiaob7610f12015-12-22 14:36:04 -0800121 filepath.endswith('google/protobuf/compiler/__init__.py') or \
122 filepath.endswith('google/protobuf/util/__init__.py'):
temporal40ee5512008-07-10 02:12:20 +0000123 os.remove(filepath)
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000124 # _clean is an old-style class, so super() doesn't work.
125 _clean.run(self)
126
127class build_py(_build_py):
128 def run(self):
temporal40ee5512008-07-10 02:12:20 +0000129 # Generate necessary .proto file if it doesn't exist.
temporal40ee5512008-07-10 02:12:20 +0000130 generate_proto("../src/google/protobuf/descriptor.proto")
liujisi@google.com9b7f6c52010-12-08 03:45:27 +0000131 generate_proto("../src/google/protobuf/compiler/plugin.proto")
Jisi Liu7464f402015-10-06 14:20:26 -0700132 generate_proto("../src/google/protobuf/any.proto")
Jisi Liuf6fa5c72015-10-06 14:26:00 -0700133 generate_proto("../src/google/protobuf/api.proto")
134 generate_proto("../src/google/protobuf/duration.proto")
135 generate_proto("../src/google/protobuf/empty.proto")
Jisi Liu7464f402015-10-06 14:20:26 -0700136 generate_proto("../src/google/protobuf/field_mask.proto")
Jisi Liuf6fa5c72015-10-06 14:26:00 -0700137 generate_proto("../src/google/protobuf/source_context.proto")
138 generate_proto("../src/google/protobuf/struct.proto")
139 generate_proto("../src/google/protobuf/timestamp.proto")
140 generate_proto("../src/google/protobuf/type.proto")
141 generate_proto("../src/google/protobuf/wrappers.proto")
jieluo@google.combde4a322014-08-12 21:10:30 +0000142 GenerateUnittestProtos()
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000143
jieluo@google.combde4a322014-08-12 21:10:30 +0000144 # Make sure google.protobuf/** are valid packages.
Feng Xiaob7610f12015-12-22 14:36:04 -0800145 for path in ['', 'internal/', 'compiler/', 'pyext/', 'util/']:
jieluo@google.combde4a322014-08-12 21:10:30 +0000146 try:
147 open('google/protobuf/%s__init__.py' % path, 'a').close()
148 except EnvironmentError:
149 pass
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000150 # _build_py is an old-style class, so super() doesn't work.
151 _build_py.run(self)
jieluo@google.combde4a322014-08-12 21:10:30 +0000152
Josh Haberman325392d2015-08-17 12:30:49 -0700153class test_conformance(_build_py):
154 target = 'test_python'
155 def run(self):
Josh Habermane891c292015-12-30 16:03:49 -0800156 if sys.version_info >= (2, 7):
157 # Python 2.6 dodges these extra failures.
158 os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
159 "--failure_list failure_list_python-post26.txt")
Josh Haberman4b31ffa2015-12-03 12:54:54 -0800160 cmd = 'cd ../conformance && make %s' % (test_conformance.target)
161 status = subprocess.check_call(cmd, shell=True)
Josh Haberman325392d2015-08-17 12:30:49 -0700162
temporal40ee5512008-07-10 02:12:20 +0000163
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700164def get_option_from_sys_argv(option_str):
165 if option_str in sys.argv:
166 sys.argv.remove(option_str)
167 return True
168 return False
169
170
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000171if __name__ == '__main__':
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000172 ext_module_list = []
Josh Haberman00700b72015-10-06 14:13:09 -0700173 warnings_as_errors = '--warnings_as_errors'
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700174 if get_option_from_sys_argv('--cpp_implementation'):
175 # Link libprotobuf.a and libprotobuf-lite.a statically with the
176 # extension. Note that those libraries have to be compiled with
177 # -fPIC for this to work.
178 compile_static_ext = get_option_from_sys_argv('--compile_static_extension')
Jisi Liu1bf446c2016-03-31 15:48:25 -0700179 extra_compile_args = ['-Wno-write-strings',
180 '-Wno-invalid-offsetof',
181 '-Wno-sign-compare']
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700182 libraries = ['protobuf']
183 extra_objects = None
184 if compile_static_ext:
185 libraries = None
186 extra_objects = ['../src/.libs/libprotobuf.a',
187 '../src/.libs/libprotobuf-lite.a']
Josh Haberman325392d2015-08-17 12:30:49 -0700188 test_conformance.target = 'test_python_cpp'
Josh Habermand8814ed2015-10-07 11:46:23 -0700189
Josh Habermane1abdf22015-12-22 11:13:03 -0800190 if "clang" in os.popen('$CC --version 2> /dev/null').read():
Josh Habermand8814ed2015-10-07 11:46:23 -0700191 extra_compile_args.append('-Wno-shorten-64-to-32')
Josh Haberman00700b72015-10-06 14:13:09 -0700192
Paul Yang7f3e2372017-01-31 09:17:32 -0800193 v, _, _ = platform.mac_ver()
194 if v:
195 v = float('.'.join(v.split('.')[:2]))
196 if v >= 10.12:
197 extra_compile_args.append('-std=c++11')
198
Josh Haberman00700b72015-10-06 14:13:09 -0700199 if warnings_as_errors in sys.argv:
200 extra_compile_args.append('-Werror')
201 sys.argv.remove(warnings_as_errors)
202
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000203 # C++ implementation extension
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700204 ext_module_list.extend([
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700205 Extension(
206 "google.protobuf.pyext._message",
Tamir Duberstein5018c432015-05-08 08:48:40 -0400207 glob.glob('google/protobuf/pyext/*.cc'),
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700208 include_dirs=[".", "../src"],
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700209 libraries=libraries,
210 extra_objects=extra_objects,
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700211 library_dirs=['../src/.libs'],
Josh Haberman00700b72015-10-06 14:13:09 -0700212 extra_compile_args=extra_compile_args,
Manjunath Kudlurcf828de2016-03-25 10:58:46 -0700213 ),
214 Extension(
215 "google.protobuf.internal._api_implementation",
216 glob.glob('google/protobuf/internal/api_implementation.cc'),
217 extra_compile_args=['-DPYTHON_PROTO2_CPP_IMPL_V2'],
218 ),
219 ])
Jisi Liuada65562015-02-25 16:39:11 -0800220 os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
liujisi@google.com33165fe2010-11-02 13:14:58 +0000221
Dan O'Reilly3791c802015-08-20 20:49:45 -0400222 # Keep this list of dependencies in sync with tox.ini.
Feng Xiao283c40c2015-12-29 14:36:46 -0800223 install_requires = ['six>=1.9', 'setuptools']
Dan O'Reilly2621c8a2015-08-14 22:54:53 -0400224 if sys.version_info <= (2,7):
225 install_requires.append('ordereddict')
226 install_requires.append('unittest2')
227
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700228 setup(
229 name='protobuf',
230 version=GetVersion(),
231 description='Protocol Buffers',
Jisi Liub3bb46c2016-05-17 10:46:54 -0700232 download_url='https://github.com/google/protobuf/releases',
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700233 long_description="Protocol Buffers are Google's data interchange format",
234 url='https://developers.google.com/protocol-buffers/',
235 maintainer='protobuf@googlegroups.com',
236 maintainer_email='protobuf@googlegroups.com',
Sebastian Schuberth902af082017-02-28 09:58:24 +0100237 license='3-Clause BSD License',
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700238 classifiers=[
Dan O'Reillye47cdd52015-08-12 23:57:46 -0400239 "Programming Language :: Python",
240 "Programming Language :: Python :: 2",
241 "Programming Language :: Python :: 2.6",
242 "Programming Language :: Python :: 2.7",
243 "Programming Language :: Python :: 3",
244 "Programming Language :: Python :: 3.3",
245 "Programming Language :: Python :: 3.4",
246 ],
Craig Citro0e7c0c22016-03-04 20:40:24 -0800247 namespace_packages=['google'],
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700248 packages=find_packages(
249 exclude=[
250 'import_test_package',
251 ],
252 ),
253 test_suite='google.protobuf.internal',
254 cmdclass={
255 'clean': clean,
256 'build_py': build_py,
Josh Haberman325392d2015-08-17 12:30:49 -0700257 'test_conformance': test_conformance,
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700258 },
Dan O'Reilly2621c8a2015-08-14 22:54:53 -0400259 install_requires=install_requires,
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700260 ext_modules=ext_module_list,
261 )