blob: 7337260a93b6777b6b65b4b099d4472dea6c9dad [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001#! /usr/bin/python
2#
3# See README for usage instructions.
temporal40ee5512008-07-10 02:12:20 +00004import sys
5import os
kenton@google.coma6de64a2009-04-18 02:28:15 +00006import subprocess
temporal40ee5512008-07-10 02:12:20 +00007
liujisi@google.com9ced30c2012-08-01 06:22:19 +00008# We must use setuptools, not distutils, because we need to use the
9# namespace_packages option for the "google" package.
10try:
jieluo@google.com7580a892014-08-12 21:28:31 +000011 from setuptools import setup, Extension
liujisi@google.com9ced30c2012-08-01 06:22:19 +000012except ImportError:
jieluo@google.com7580a892014-08-12 21:28:31 +000013 try:
14 from ez_setup import use_setuptools
15 use_setuptools()
16 from setuptools import setup, Extension
17 except ImportError:
18 sys.stderr.write(
19 "Could not import setuptools; make sure you have setuptools or "
20 "ez_setup installed.\n")
21 raise
liujisi@google.com9ced30c2012-08-01 06:22:19 +000022from distutils.command.clean import clean as _clean
Dwayne Litzenberger0fd260e2014-10-14 13:47:06 -070023if sys.version_info[0] >= 3:
24 # Python 3
25 from distutils.command.build_py import build_py_2to3 as _build_py
26else:
27 # Python 2
28 from distutils.command.build_py import build_py as _build_py
liujisi@google.com9ced30c2012-08-01 06:22:19 +000029from distutils.spawn import find_executable
30
temporal40ee5512008-07-10 02:12:20 +000031maintainer_email = "protobuf@googlegroups.com"
32
33# Find the Protocol Compiler.
liujisi@google.come34f1f62012-12-05 01:25:12 +000034if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
35 protoc = os.environ['PROTOC']
36elif os.path.exists("../src/protoc"):
temporal40ee5512008-07-10 02:12:20 +000037 protoc = "../src/protoc"
kenton@google.com4152d552009-04-22 03:20:21 +000038elif os.path.exists("../src/protoc.exe"):
39 protoc = "../src/protoc.exe"
kenton@google.com80aa23d2010-09-28 21:58:36 +000040elif os.path.exists("../vsprojects/Debug/protoc.exe"):
41 protoc = "../vsprojects/Debug/protoc.exe"
42elif os.path.exists("../vsprojects/Release/protoc.exe"):
43 protoc = "../vsprojects/Release/protoc.exe"
temporal40ee5512008-07-10 02:12:20 +000044else:
45 protoc = find_executable("protoc")
46
47def generate_proto(source):
48 """Invokes the Protocol Compiler to generate a _pb2.py from the given
49 .proto file. Does nothing if the output already exists and is newer than
50 the input."""
51
52 output = source.replace(".proto", "_pb2.py").replace("../src/", "")
53
temporal40ee5512008-07-10 02:12:20 +000054 if (not os.path.exists(output) or
55 (os.path.exists(source) and
56 os.path.getmtime(source) > os.path.getmtime(output))):
jieluo@google.combde4a322014-08-12 21:10:30 +000057 print ("Generating %s..." % output)
temporal40ee5512008-07-10 02:12:20 +000058
liujisi@google.com9ced30c2012-08-01 06:22:19 +000059 if not os.path.exists(source):
60 sys.stderr.write("Can't find required file: %s\n" % source)
61 sys.exit(-1)
62
temporal40ee5512008-07-10 02:12:20 +000063 if protoc == None:
64 sys.stderr.write(
65 "protoc is not installed nor found in ../src. Please compile it "
66 "or install the binary package.\n")
67 sys.exit(-1)
68
kenton@google.coma6de64a2009-04-18 02:28:15 +000069 protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
70 if subprocess.call(protoc_command) != 0:
temporal40ee5512008-07-10 02:12:20 +000071 sys.exit(-1)
72
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000073def GenerateUnittestProtos():
74 generate_proto("../src/google/protobuf/unittest.proto")
75 generate_proto("../src/google/protobuf/unittest_custom_options.proto")
76 generate_proto("../src/google/protobuf/unittest_import.proto")
77 generate_proto("../src/google/protobuf/unittest_import_public.proto")
78 generate_proto("../src/google/protobuf/unittest_mset.proto")
79 generate_proto("../src/google/protobuf/unittest_no_generic_services.proto")
jieluo@google.com4de8f552014-07-18 00:47:59 +000080 generate_proto("google/protobuf/internal/descriptor_pool_test1.proto")
81 generate_proto("google/protobuf/internal/descriptor_pool_test2.proto")
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000082 generate_proto("google/protobuf/internal/test_bad_identifiers.proto")
jieluo@google.com4de8f552014-07-18 00:47:59 +000083 generate_proto("google/protobuf/internal/missing_enum_values.proto")
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000084 generate_proto("google/protobuf/internal/more_extensions.proto")
85 generate_proto("google/protobuf/internal/more_extensions_dynamic.proto")
86 generate_proto("google/protobuf/internal/more_messages.proto")
87 generate_proto("google/protobuf/internal/factory_test1.proto")
88 generate_proto("google/protobuf/internal/factory_test2.proto")
Feng Xiao6ef984a2014-11-10 17:34:54 -080089 generate_proto("google/protobuf/internal/import_test_package/inner.proto")
90 generate_proto("google/protobuf/internal/import_test_package/outer.proto")
jieluo@google.combde4a322014-08-12 21:10:30 +000091 generate_proto("google/protobuf/pyext/python.proto")
liujisi@google.com9ced30c2012-08-01 06:22:19 +000092
jieluo@google.com1eba9d92014-08-25 20:17:53 +000093def MakeTestSuite():
94 # Test C++ implementation
95 import unittest
96 import google.protobuf.pyext.descriptor_cpp2_test as descriptor_cpp2_test
97 import google.protobuf.pyext.message_factory_cpp2_test \
98 as message_factory_cpp2_test
99 import google.protobuf.pyext.reflection_cpp2_generated_test \
100 as reflection_cpp2_generated_test
101
102 loader = unittest.defaultTestLoader
103 suite = unittest.TestSuite()
104 for test in [ descriptor_cpp2_test,
105 message_factory_cpp2_test,
106 reflection_cpp2_generated_test]:
107 suite.addTest(loader.loadTestsFromModule(test))
108 return suite
109
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000110class clean(_clean):
111 def run(self):
112 # Delete generated files in the code tree.
temporal40ee5512008-07-10 02:12:20 +0000113 for (dirpath, dirnames, filenames) in os.walk("."):
114 for filename in filenames:
115 filepath = os.path.join(dirpath, filename)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000116 if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000117 filepath.endswith(".so") or filepath.endswith(".o") or \
118 filepath.endswith('google/protobuf/compiler/__init__.py'):
temporal40ee5512008-07-10 02:12:20 +0000119 os.remove(filepath)
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000120 # _clean is an old-style class, so super() doesn't work.
121 _clean.run(self)
122
123class build_py(_build_py):
124 def run(self):
temporal40ee5512008-07-10 02:12:20 +0000125 # Generate necessary .proto file if it doesn't exist.
temporal40ee5512008-07-10 02:12:20 +0000126 generate_proto("../src/google/protobuf/descriptor.proto")
liujisi@google.com9b7f6c52010-12-08 03:45:27 +0000127 generate_proto("../src/google/protobuf/compiler/plugin.proto")
jieluo@google.combde4a322014-08-12 21:10:30 +0000128 GenerateUnittestProtos()
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000129
jieluo@google.combde4a322014-08-12 21:10:30 +0000130 # Make sure google.protobuf/** are valid packages.
131 for path in ['', 'internal/', 'compiler/', 'pyext/']:
132 try:
133 open('google/protobuf/%s__init__.py' % path, 'a').close()
134 except EnvironmentError:
135 pass
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000136 # _build_py is an old-style class, so super() doesn't work.
137 _build_py.run(self)
jieluo@google.combde4a322014-08-12 21:10:30 +0000138 # TODO(mrovner): Subclass to run 2to3 on some files only.
139 # Tracing what https://wiki.python.org/moin/PortingPythonToPy3k's "Approach 2"
140 # section on how to get 2to3 to run on source files during install under
141 # Python 3. This class seems like a good place to put logic that calls
142 # python3's distutils.util.run_2to3 on the subset of the files we have in our
143 # release that are subject to conversion.
144 # See code reference in previous code review.
145
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000146if __name__ == '__main__':
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000147 ext_module_list = []
jieluo@google.coma21bf2e2014-08-25 23:26:40 +0000148 cpp_impl = '--cpp_implementation'
149 if cpp_impl in sys.argv:
jieluo@google.comb70e5862014-08-13 21:05:19 +0000150 sys.argv.remove(cpp_impl)
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000151 # C++ implementation extension
152 ext_module_list.append(Extension(
jieluo@google.combde4a322014-08-12 21:10:30 +0000153 "google.protobuf.pyext._message",
154 [ "google/protobuf/pyext/descriptor.cc",
155 "google/protobuf/pyext/message.cc",
156 "google/protobuf/pyext/extension_dict.cc",
157 "google/protobuf/pyext/repeated_scalar_container.cc",
158 "google/protobuf/pyext/repeated_composite_container.cc" ],
159 define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')],
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000160 include_dirs = [ ".", "../src"],
jieluo@google.combde4a322014-08-12 21:10:30 +0000161 libraries = [ "protobuf" ],
162 library_dirs = [ '../src/.libs' ],
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000163 ))
liujisi@google.com33165fe2010-11-02 13:14:58 +0000164
temporal40ee5512008-07-10 02:12:20 +0000165 setup(name = 'protobuf',
Feng Xiaodf5481c2014-10-21 16:47:33 -0700166 version = '2.6.2-pre',
temporal40ee5512008-07-10 02:12:20 +0000167 packages = [ 'google' ],
168 namespace_packages = [ 'google' ],
jieluo@google.com1eba9d92014-08-25 20:17:53 +0000169 test_suite = 'setup.MakeTestSuite',
170 google_test_dir = "google/protobuf/internal",
temporal40ee5512008-07-10 02:12:20 +0000171 # Must list modules explicitly so that we don't install tests.
172 py_modules = [
liujisi@google.com33165fe2010-11-02 13:14:58 +0000173 'google.protobuf.internal.api_implementation',
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000174 'google.protobuf.internal.containers',
liujisi@google.com33165fe2010-11-02 13:14:58 +0000175 'google.protobuf.internal.cpp_message',
temporal40ee5512008-07-10 02:12:20 +0000176 'google.protobuf.internal.decoder',
177 'google.protobuf.internal.encoder',
xiaofeng@google.coma655b982012-12-08 18:44:32 +0000178 'google.protobuf.internal.enum_type_wrapper',
temporal40ee5512008-07-10 02:12:20 +0000179 'google.protobuf.internal.message_listener',
liujisi@google.com33165fe2010-11-02 13:14:58 +0000180 'google.protobuf.internal.python_message',
temporalea9d0d82008-08-18 22:38:20 +0000181 'google.protobuf.internal.type_checkers',
temporal40ee5512008-07-10 02:12:20 +0000182 'google.protobuf.internal.wire_format',
183 'google.protobuf.descriptor',
184 'google.protobuf.descriptor_pb2',
liujisi@google.com9b7f6c52010-12-08 03:45:27 +0000185 'google.protobuf.compiler.plugin_pb2',
temporal40ee5512008-07-10 02:12:20 +0000186 'google.protobuf.message',
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000187 'google.protobuf.descriptor_database',
188 'google.protobuf.descriptor_pool',
189 'google.protobuf.message_factory',
Feng Xiao6ef984a2014-11-10 17:34:54 -0800190 'google.protobuf.proto_builder',
David Hirschfeldef6eff22014-08-27 09:25:26 +0100191 'google.protobuf.pyext.cpp_message',
temporal40ee5512008-07-10 02:12:20 +0000192 'google.protobuf.reflection',
193 'google.protobuf.service',
194 'google.protobuf.service_reflection',
jieluo@google.combde4a322014-08-12 21:10:30 +0000195 'google.protobuf.symbol_database',
196 'google.protobuf.text_encoding',
197 'google.protobuf.text_format'],
liujisi@google.com9ced30c2012-08-01 06:22:19 +0000198 cmdclass = { 'clean': clean, 'build_py': build_py },
199 install_requires = ['setuptools'],
Dwayne Litzenbergerb4606102014-10-14 13:50:00 -0700200 # TODO: Restore dependency once a Python 3 compatible google-apputils
201 # is released.
202 setup_requires = (['google-apputils']
203 if sys.version_info[0] < 3 else
204 []),
liujisi@google.com9b7f6c52010-12-08 03:45:27 +0000205 ext_modules = ext_module_list,
Feng Xiaoe4288622014-10-01 16:26:23 -0700206 url = 'https://developers.google.com/protocol-buffers/',
temporal40ee5512008-07-10 02:12:20 +0000207 maintainer = maintainer_email,
208 maintainer_email = 'protobuf@googlegroups.com',
kenton@google.com24bf56f2008-09-24 20:31:01 +0000209 license = 'New BSD License',
temporal40ee5512008-07-10 02:12:20 +0000210 description = 'Protocol Buffers',
211 long_description =
212 "Protocol Buffers are Google's data interchange format.",
temporal40ee5512008-07-10 02:12:20 +0000213 )