blob: a9df075e7becd760ddc5ba2f9c7020cbf2e9e855 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001#! /usr/bin/env python
2#
3# See README for usage instructions.
4import glob
5import os
6import subprocess
7import sys
Austin Schuh40c16522018-10-28 20:27:54 -07008import platform
Brian Silverman9c614bc2016-02-15 20:20:02 -05009
10# We must use setuptools, not distutils, because we need to use the
11# namespace_packages option for the "google" package.
12from setuptools import setup, Extension, find_packages
13
14from 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
23
24# Find the Protocol Compiler.
25if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
26 protoc = os.environ['PROTOC']
27elif os.path.exists("../src/protoc"):
28 protoc = "../src/protoc"
29elif os.path.exists("../src/protoc.exe"):
30 protoc = "../src/protoc.exe"
31elif 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"
35else:
36 protoc = find_executable("protoc")
37
38
39def GetVersion():
40 """Gets the version from google/protobuf/__init__.py
41
42 Do not import google.protobuf.__init__ directly, because an installed
43 protobuf library may be loaded instead."""
44
45 with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
46 exec(version_file.read(), globals())
47 return __version__
48
49
50def generate_proto(source, require = True):
51 """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
55 if not require and not os.path.exists(source):
56 return
57
58 output = source.replace(".proto", "_pb2.py").replace("../src/", "")
59
60 if (not os.path.exists(output) or
61 (os.path.exists(source) and
62 os.path.getmtime(source) > os.path.getmtime(output))):
63 print("Generating %s..." % output)
64
65 if not os.path.exists(source):
66 sys.stderr.write("Can't find required file: %s\n" % source)
67 sys.exit(-1)
68
69 if protoc is None:
70 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
75 protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
76 if subprocess.call(protoc_command) != 0:
77 sys.exit(-1)
78
79def GenerateUnittestProtos():
Austin Schuh40c16522018-10-28 20:27:54 -070080 generate_proto("../src/google/protobuf/any_test.proto", False)
81 generate_proto("../src/google/protobuf/map_proto2_unittest.proto", False)
Brian Silverman9c614bc2016-02-15 20:20:02 -050082 generate_proto("../src/google/protobuf/map_unittest.proto", False)
Austin Schuh40c16522018-10-28 20:27:54 -070083 generate_proto("../src/google/protobuf/test_messages_proto3.proto", False)
84 generate_proto("../src/google/protobuf/test_messages_proto2.proto", False)
Brian Silverman9c614bc2016-02-15 20:20:02 -050085 generate_proto("../src/google/protobuf/unittest_arena.proto", False)
86 generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
87 generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False)
88 generate_proto("../src/google/protobuf/unittest.proto", False)
89 generate_proto("../src/google/protobuf/unittest_custom_options.proto", False)
90 generate_proto("../src/google/protobuf/unittest_import.proto", False)
91 generate_proto("../src/google/protobuf/unittest_import_public.proto", False)
92 generate_proto("../src/google/protobuf/unittest_mset.proto", False)
93 generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
94 generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
95 generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
96 generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
97 generate_proto("google/protobuf/internal/any_test.proto", False)
98 generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
99 generate_proto("google/protobuf/internal/descriptor_pool_test2.proto", False)
100 generate_proto("google/protobuf/internal/factory_test1.proto", False)
101 generate_proto("google/protobuf/internal/factory_test2.proto", False)
Austin Schuh40c16522018-10-28 20:27:54 -0700102 generate_proto("google/protobuf/internal/file_options_test.proto", False)
Brian Silverman9c614bc2016-02-15 20:20:02 -0500103 generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
104 generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
105 generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
106 generate_proto("google/protobuf/internal/message_set_extensions.proto", False)
107 generate_proto("google/protobuf/internal/more_extensions.proto", False)
108 generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False)
109 generate_proto("google/protobuf/internal/more_messages.proto", False)
Austin Schuh40c16522018-10-28 20:27:54 -0700110 generate_proto("google/protobuf/internal/no_package.proto", False)
Brian Silverman9c614bc2016-02-15 20:20:02 -0500111 generate_proto("google/protobuf/internal/packed_field_test.proto", False)
112 generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False)
113 generate_proto("google/protobuf/pyext/python.proto", False)
114
115
116class clean(_clean):
117 def run(self):
118 # Delete generated files in the code tree.
119 for (dirpath, dirnames, filenames) in os.walk("."):
120 for filename in filenames:
121 filepath = os.path.join(dirpath, filename)
122 if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
Austin Schuh40c16522018-10-28 20:27:54 -0700123 filepath.endswith(".so") or filepath.endswith(".o"):
Brian Silverman9c614bc2016-02-15 20:20:02 -0500124 os.remove(filepath)
125 # _clean is an old-style class, so super() doesn't work.
126 _clean.run(self)
127
128class build_py(_build_py):
129 def run(self):
130 # Generate necessary .proto file if it doesn't exist.
131 generate_proto("../src/google/protobuf/descriptor.proto")
132 generate_proto("../src/google/protobuf/compiler/plugin.proto")
133 generate_proto("../src/google/protobuf/any.proto")
134 generate_proto("../src/google/protobuf/api.proto")
135 generate_proto("../src/google/protobuf/duration.proto")
136 generate_proto("../src/google/protobuf/empty.proto")
137 generate_proto("../src/google/protobuf/field_mask.proto")
138 generate_proto("../src/google/protobuf/source_context.proto")
139 generate_proto("../src/google/protobuf/struct.proto")
140 generate_proto("../src/google/protobuf/timestamp.proto")
141 generate_proto("../src/google/protobuf/type.proto")
142 generate_proto("../src/google/protobuf/wrappers.proto")
143 GenerateUnittestProtos()
144
Brian Silverman9c614bc2016-02-15 20:20:02 -0500145 # _build_py is an old-style class, so super() doesn't work.
146 _build_py.run(self)
147
148class test_conformance(_build_py):
149 target = 'test_python'
150 def run(self):
151 if sys.version_info >= (2, 7):
152 # Python 2.6 dodges these extra failures.
153 os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
154 "--failure_list failure_list_python-post26.txt")
155 cmd = 'cd ../conformance && make %s' % (test_conformance.target)
156 status = subprocess.check_call(cmd, shell=True)
157
158
Austin Schuh40c16522018-10-28 20:27:54 -0700159def get_option_from_sys_argv(option_str):
160 if option_str in sys.argv:
161 sys.argv.remove(option_str)
162 return True
163 return False
164
165
Brian Silverman9c614bc2016-02-15 20:20:02 -0500166if __name__ == '__main__':
167 ext_module_list = []
Brian Silverman9c614bc2016-02-15 20:20:02 -0500168 warnings_as_errors = '--warnings_as_errors'
Austin Schuh40c16522018-10-28 20:27:54 -0700169 if get_option_from_sys_argv('--cpp_implementation'):
170 # Link libprotobuf.a and libprotobuf-lite.a statically with the
171 # extension. Note that those libraries have to be compiled with
172 # -fPIC for this to work.
173 compile_static_ext = get_option_from_sys_argv('--compile_static_extension')
174 libraries = ['protobuf']
175 extra_objects = None
176 if compile_static_ext:
177 libraries = None
178 extra_objects = ['../src/.libs/libprotobuf.a',
179 '../src/.libs/libprotobuf-lite.a']
Brian Silverman9c614bc2016-02-15 20:20:02 -0500180 test_conformance.target = 'test_python_cpp'
181
Austin Schuh40c16522018-10-28 20:27:54 -0700182 extra_compile_args = []
183
184 if sys.platform != 'win32':
185 extra_compile_args.append('-Wno-write-strings')
186 extra_compile_args.append('-Wno-invalid-offsetof')
187 extra_compile_args.append('-Wno-sign-compare')
188
189 # https://github.com/Theano/Theano/issues/4926
190 if sys.platform == 'win32':
191 extra_compile_args.append('-D_hypot=hypot')
192
193 # https://github.com/tpaviot/pythonocc-core/issues/48
194 if sys.platform == 'win32' and '64 bit' in sys.version:
195 extra_compile_args.append('-DMS_WIN64')
196
197 # MSVS default is dymanic
198 if (sys.platform == 'win32'):
199 extra_compile_args.append('/MT')
200
Brian Silverman9c614bc2016-02-15 20:20:02 -0500201 if "clang" in os.popen('$CC --version 2> /dev/null').read():
202 extra_compile_args.append('-Wno-shorten-64-to-32')
203
Austin Schuh40c16522018-10-28 20:27:54 -0700204 v, _, _ = platform.mac_ver()
205 if v:
206 extra_compile_args.append('-std=c++11')
207 elif os.getenv('KOKORO_BUILD_NUMBER') or os.getenv('KOKORO_BUILD_ID'):
208 extra_compile_args.append('-std=c++11')
209
Brian Silverman9c614bc2016-02-15 20:20:02 -0500210 if warnings_as_errors in sys.argv:
211 extra_compile_args.append('-Werror')
212 sys.argv.remove(warnings_as_errors)
213
214 # C++ implementation extension
Austin Schuh40c16522018-10-28 20:27:54 -0700215 ext_module_list.extend([
Brian Silverman9c614bc2016-02-15 20:20:02 -0500216 Extension(
217 "google.protobuf.pyext._message",
218 glob.glob('google/protobuf/pyext/*.cc'),
219 include_dirs=[".", "../src"],
Austin Schuh40c16522018-10-28 20:27:54 -0700220 libraries=libraries,
221 extra_objects=extra_objects,
Brian Silverman9c614bc2016-02-15 20:20:02 -0500222 library_dirs=['../src/.libs'],
223 extra_compile_args=extra_compile_args,
Austin Schuh40c16522018-10-28 20:27:54 -0700224 ),
225 Extension(
226 "google.protobuf.internal._api_implementation",
227 glob.glob('google/protobuf/internal/api_implementation.cc'),
228 extra_compile_args=extra_compile_args + ['-DPYTHON_PROTO2_CPP_IMPL_V2'],
229 ),
230 ])
Brian Silverman9c614bc2016-02-15 20:20:02 -0500231 os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
232
233 # Keep this list of dependencies in sync with tox.ini.
234 install_requires = ['six>=1.9', 'setuptools']
235 if sys.version_info <= (2,7):
236 install_requires.append('ordereddict')
237 install_requires.append('unittest2')
238
239 setup(
240 name='protobuf',
241 version=GetVersion(),
242 description='Protocol Buffers',
Austin Schuh40c16522018-10-28 20:27:54 -0700243 download_url='https://github.com/google/protobuf/releases',
Brian Silverman9c614bc2016-02-15 20:20:02 -0500244 long_description="Protocol Buffers are Google's data interchange format",
245 url='https://developers.google.com/protocol-buffers/',
246 maintainer='protobuf@googlegroups.com',
247 maintainer_email='protobuf@googlegroups.com',
Austin Schuh40c16522018-10-28 20:27:54 -0700248 license='3-Clause BSD License',
Brian Silverman9c614bc2016-02-15 20:20:02 -0500249 classifiers=[
250 "Programming Language :: Python",
251 "Programming Language :: Python :: 2",
Brian Silverman9c614bc2016-02-15 20:20:02 -0500252 "Programming Language :: Python :: 2.7",
253 "Programming Language :: Python :: 3",
254 "Programming Language :: Python :: 3.3",
255 "Programming Language :: Python :: 3.4",
256 ],
257 namespace_packages=['google'],
258 packages=find_packages(
259 exclude=[
260 'import_test_package',
261 ],
262 ),
263 test_suite='google.protobuf.internal',
264 cmdclass={
265 'clean': clean,
266 'build_py': build_py,
267 'test_conformance': test_conformance,
268 },
269 install_requires=install_requires,
270 ext_modules=ext_module_list,
271 )