blob: cda5686758f0e657b85f6f8054db390ff4af44fe [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
temporal40ee5512008-07-10 02:12:20 +00008
liujisi@google.com9ced30c2012-08-01 06:22:19 +00009# We must use setuptools, not distutils, because we need to use the
10# namespace_packages option for the "google" package.
Dan O'Reilly3bdfb4b2015-08-20 13:51:26 -040011from setuptools import setup, Extension, find_packages
liujisi@google.com9ced30c2012-08-01 06:22:19 +000012
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070013from distutils.command.clean import clean as _clean
14
15if sys.version_info[0] == 3:
16 # Python 3
17 from distutils.command.build_py import build_py_2to3 as _build_py
18else:
19 # Python 2
20 from distutils.command.build_py import build_py as _build_py
21from distutils.spawn import find_executable
temporal40ee5512008-07-10 02:12:20 +000022
23# Find the Protocol Compiler.
liujisi@google.come34f1f62012-12-05 01:25:12 +000024if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
25 protoc = os.environ['PROTOC']
26elif os.path.exists("../src/protoc"):
temporal40ee5512008-07-10 02:12:20 +000027 protoc = "../src/protoc"
kenton@google.com4152d552009-04-22 03:20:21 +000028elif os.path.exists("../src/protoc.exe"):
29 protoc = "../src/protoc.exe"
kenton@google.com80aa23d2010-09-28 21:58:36 +000030elif os.path.exists("../vsprojects/Debug/protoc.exe"):
31 protoc = "../vsprojects/Debug/protoc.exe"
32elif os.path.exists("../vsprojects/Release/protoc.exe"):
33 protoc = "../vsprojects/Release/protoc.exe"
temporal40ee5512008-07-10 02:12:20 +000034else:
35 protoc = find_executable("protoc")
36
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070037
Jisi Liu4573e112015-03-04 16:45:13 -080038def GetVersion():
39 """Gets the version from google/protobuf/__init__.py
40
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070041 Do not import google.protobuf.__init__ directly, because an installed
42 protobuf library may be loaded instead."""
Jisi Liu4573e112015-03-04 16:45:13 -080043
Jisi Liu4573e112015-03-04 16:45:13 -080044 with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
Behzad Tabibian2bf92b32015-05-07 19:04:56 +020045 exec(version_file.read(), globals())
Jisi Liu4573e112015-03-04 16:45:13 -080046 return __version__
47
48
Feng Xiao8e142682015-05-26 00:11:09 -070049def generate_proto(source, require = True):
temporal40ee5512008-07-10 02:12:20 +000050 """Invokes the Protocol Compiler to generate a _pb2.py from the given
51 .proto file. Does nothing if the output already exists and is newer than
52 the input."""
53
Feng Xiao8e142682015-05-26 00:11:09 -070054 if not require and not os.path.exists(source):
55 return
56
temporal40ee5512008-07-10 02:12:20 +000057 output = source.replace(".proto", "_pb2.py").replace("../src/", "")
58
temporal40ee5512008-07-10 02:12:20 +000059 if (not os.path.exists(output) or
60 (os.path.exists(source) and
61 os.path.getmtime(source) > os.path.getmtime(output))):
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070062 print("Generating %s..." % output)
temporal40ee5512008-07-10 02:12:20 +000063
liujisi@google.com9ced30c2012-08-01 06:22:19 +000064 if not os.path.exists(source):
65 sys.stderr.write("Can't find required file: %s\n" % source)
66 sys.exit(-1)
67
Tamir Duberstein21a7cf92015-04-11 18:24:24 -070068 if protoc is None:
temporal40ee5512008-07-10 02:12:20 +000069 sys.stderr.write(
70 "protoc is not installed nor found in ../src. Please compile it "
71 "or install the binary package.\n")
72 sys.exit(-1)
73
kenton@google.coma6de64a2009-04-18 02:28:15 +000074 protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
75 if subprocess.call(protoc_command) != 0:
temporal40ee5512008-07-10 02:12:20 +000076 sys.exit(-1)
77
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000078def GenerateUnittestProtos():
Feng Xiao8e142682015-05-26 00:11:09 -070079 generate_proto("../src/google/protobuf/map_unittest.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -070080 generate_proto("../src/google/protobuf/unittest_arena.proto", False)
81 generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
82 generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070083 generate_proto("../src/google/protobuf/unittest.proto", False)
84 generate_proto("../src/google/protobuf/unittest_custom_options.proto", False)
85 generate_proto("../src/google/protobuf/unittest_import.proto", False)
86 generate_proto("../src/google/protobuf/unittest_import_public.proto", False)
87 generate_proto("../src/google/protobuf/unittest_mset.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -070088 generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070089 generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
90 generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
Jisi Liu46e8ff62015-10-05 11:59:43 -070091 generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -070092 generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
93 generate_proto("google/protobuf/internal/descriptor_pool_test2.proto", False)
94 generate_proto("google/protobuf/internal/factory_test1.proto", False)
95 generate_proto("google/protobuf/internal/factory_test2.proto", False)
96 generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
97 generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
98 generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -070099 generate_proto("google/protobuf/internal/message_set_extensions.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -0700100 generate_proto("google/protobuf/internal/more_extensions.proto", False)
101 generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False)
102 generate_proto("google/protobuf/internal/more_messages.proto", False)
Jisi Liub0f66112015-08-21 11:18:45 -0700103 generate_proto("google/protobuf/internal/packed_field_test.proto", False)
Feng Xiao8e142682015-05-26 00:11:09 -0700104 generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False)
105 generate_proto("google/protobuf/pyext/python.proto", False)
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000106
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700107
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000108class clean(_clean):
109 def run(self):
110 # Delete generated files in the code tree.
temporal40ee5512008-07-10 02:12:20 +0000111 for (dirpath, dirnames, filenames) in os.walk("."):
112 for filename in filenames:
113 filepath = os.path.join(dirpath, filename)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000114 if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000115 filepath.endswith(".so") or filepath.endswith(".o") or \
116 filepath.endswith('google/protobuf/compiler/__init__.py'):
temporal40ee5512008-07-10 02:12:20 +0000117 os.remove(filepath)
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000118 # _clean is an old-style class, so super() doesn't work.
119 _clean.run(self)
120
121class build_py(_build_py):
122 def run(self):
temporal40ee5512008-07-10 02:12:20 +0000123 # Generate necessary .proto file if it doesn't exist.
temporal40ee5512008-07-10 02:12:20 +0000124 generate_proto("../src/google/protobuf/descriptor.proto")
liujisi@google.com9b7f6c52010-12-08 03:45:27 +0000125 generate_proto("../src/google/protobuf/compiler/plugin.proto")
Jisi Liu7464f402015-10-06 14:20:26 -0700126 generate_proto("../src/google/protobuf/any.proto")
Jisi Liuf6fa5c72015-10-06 14:26:00 -0700127 generate_proto("../src/google/protobuf/api.proto")
128 generate_proto("../src/google/protobuf/duration.proto")
129 generate_proto("../src/google/protobuf/empty.proto")
Jisi Liu7464f402015-10-06 14:20:26 -0700130 generate_proto("../src/google/protobuf/field_mask.proto")
Jisi Liuf6fa5c72015-10-06 14:26:00 -0700131 generate_proto("../src/google/protobuf/source_context.proto")
132 generate_proto("../src/google/protobuf/struct.proto")
133 generate_proto("../src/google/protobuf/timestamp.proto")
134 generate_proto("../src/google/protobuf/type.proto")
135 generate_proto("../src/google/protobuf/wrappers.proto")
jieluo@google.combde4a322014-08-12 21:10:30 +0000136 GenerateUnittestProtos()
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000137
jieluo@google.combde4a322014-08-12 21:10:30 +0000138 # Make sure google.protobuf/** are valid packages.
139 for path in ['', 'internal/', 'compiler/', 'pyext/']:
140 try:
141 open('google/protobuf/%s__init__.py' % path, 'a').close()
142 except EnvironmentError:
143 pass
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000144 # _build_py is an old-style class, so super() doesn't work.
145 _build_py.run(self)
jieluo@google.combde4a322014-08-12 21:10:30 +0000146
temporal40ee5512008-07-10 02:12:20 +0000147
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000148if __name__ == '__main__':
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000149 ext_module_list = []
jieluo@google.coma21bf2e2014-08-25 23:26:40 +0000150 cpp_impl = '--cpp_implementation'
151 if cpp_impl in sys.argv:
jieluo@google.comb70e5862014-08-13 21:05:19 +0000152 sys.argv.remove(cpp_impl)
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000153 # C++ implementation extension
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700154 ext_module_list.append(
155 Extension(
156 "google.protobuf.pyext._message",
Tamir Duberstein5018c432015-05-08 08:48:40 -0400157 glob.glob('google/protobuf/pyext/*.cc'),
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700158 define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')],
159 include_dirs=[".", "../src"],
160 libraries=['protobuf'],
161 library_dirs=['../src/.libs'],
162 )
163 )
Jisi Liuada65562015-02-25 16:39:11 -0800164 os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
liujisi@google.com33165fe2010-11-02 13:14:58 +0000165
Dan O'Reilly3791c802015-08-20 20:49:45 -0400166 # Keep this list of dependencies in sync with tox.ini.
Dan O'Reilly2621c8a2015-08-14 22:54:53 -0400167 install_requires = ['six', 'setuptools']
168 if sys.version_info <= (2,7):
169 install_requires.append('ordereddict')
170 install_requires.append('unittest2')
171
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700172 setup(
173 name='protobuf',
174 version=GetVersion(),
175 description='Protocol Buffers',
176 long_description="Protocol Buffers are Google's data interchange format",
177 url='https://developers.google.com/protocol-buffers/',
178 maintainer='protobuf@googlegroups.com',
179 maintainer_email='protobuf@googlegroups.com',
180 license='New BSD License',
181 classifiers=[
Dan O'Reillye47cdd52015-08-12 23:57:46 -0400182 "Programming Language :: Python",
183 "Programming Language :: Python :: 2",
184 "Programming Language :: Python :: 2.6",
185 "Programming Language :: Python :: 2.7",
186 "Programming Language :: Python :: 3",
187 "Programming Language :: Python :: 3.3",
188 "Programming Language :: Python :: 3.4",
189 ],
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700190 namespace_packages=['google'],
191 packages=find_packages(
192 exclude=[
193 'import_test_package',
194 ],
195 ),
196 test_suite='google.protobuf.internal',
197 cmdclass={
198 'clean': clean,
199 'build_py': build_py,
200 },
Dan O'Reilly2621c8a2015-08-14 22:54:53 -0400201 install_requires=install_requires,
Tamir Duberstein21a7cf92015-04-11 18:24:24 -0700202 ext_modules=ext_module_list,
203 )