Skip to content

Commit 985c968

Browse files
committed
Remove hack for building Python support with Bazel.
This change makes use of new imports attribute for Bazel's Python rules, which enable adding directories to the PYTHONPATH. This allows us to remove the hack for building protobuf's Python support with Bazel and now allows projects to include protobuf using a Bazel external repository rather than requiring it to be imported directly into the source tree as //google/protobuf. This change also updates the protobuf BUILD file to use a named repository, @python//, for including Python headers rather than //util/python. This allows projects to specify their own package for Python headers when including protobuf with an external repository. Fixes protocolbuffers#1230
1 parent fb714b3 commit 985c968

File tree

4 files changed

+51
-96
lines changed

4 files changed

+51
-96
lines changed

BUILD

+15-37
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ load(
2222
"protobuf",
2323
"cc_proto_library",
2424
"py_proto_library",
25-
"internal_copied_filegroup",
2625
"internal_protobuf_py_tests",
2726
)
2827

@@ -484,25 +483,7 @@ java_library(
484483
# Python support
485484
################################################################################
486485

487-
# Hack:
488-
# protoc generated files contain imports like:
489-
# "from google.protobuf.xxx import yyy"
490-
# However, the sources files of the python runtime are not directly under
491-
# "google/protobuf" (they are under python/google/protobuf). We workaround
492-
# this by copying runtime source files into the desired location to workaround
493-
# the import issue. Ideally py_library should support something similiar to the
494-
# "include" attribute in cc_library to inject the PYTHON_PATH for all libraries
495-
# that depend on the target.
496-
#
497-
# If you use python protobuf as a third_party library in your bazel managed
498-
# project:
499-
# 1) Please import the whole package to //google/protobuf in your
500-
# project. Otherwise, bazel disallows generated files out of the current
501-
# package, thus we won't be able to copy protobuf runtime files into
502-
# //google/protobuf/.
503-
# 2) The runtime also requires "six" for Python2/3 compatibility, please see the
504-
# WORKSPACE file and bind "six" to your workspace as well.
505-
internal_copied_filegroup(
486+
py_library(
506487
name = "python_srcs",
507488
srcs = glob(
508489
[
@@ -514,7 +495,7 @@ internal_copied_filegroup(
514495
"python/google/protobuf/internal/test_util.py",
515496
],
516497
),
517-
include = "python",
498+
imports = ["python"],
518499
)
519500

520501
cc_binary(
@@ -527,7 +508,7 @@ cc_binary(
527508
linkstatic = 1,
528509
deps = select({
529510
"//conditions:default": [],
530-
":use_fast_cpp_protos": ["//util/python:python_headers"],
511+
":use_fast_cpp_protos": ["//external:python_headers"],
531512
}),
532513
)
533514

@@ -553,7 +534,7 @@ cc_binary(
553534
":protobuf",
554535
] + select({
555536
"//conditions:default": [],
556-
":use_fast_cpp_protos": ["//util/python:python_headers"],
537+
":use_fast_cpp_protos": ["//external:python_headers"],
557538
}),
558539
)
559540

@@ -584,23 +565,14 @@ py_proto_library(
584565
}),
585566
default_runtime = "",
586567
protoc = ":protoc",
587-
py_extra_srcs = [":python_srcs"],
588-
py_libs = ["//external:six"],
568+
py_libs = [
569+
":python_srcs",
570+
"//external:six"
571+
],
589572
srcs_version = "PY2AND3",
590573
visibility = ["//visibility:public"],
591574
)
592575

593-
internal_copied_filegroup(
594-
name = "python_test_srcs",
595-
srcs = glob(
596-
[
597-
"python/google/protobuf/internal/*_test.py",
598-
"python/google/protobuf/internal/test_util.py",
599-
],
600-
),
601-
include = "python",
602-
)
603-
604576
py_proto_library(
605577
name = "python_common_test_protos",
606578
srcs = LITE_TEST_PROTOS + TEST_PROTOS,
@@ -624,7 +596,13 @@ py_proto_library(
624596

625597
py_library(
626598
name = "python_tests",
627-
srcs = [":python_test_srcs"],
599+
srcs = glob(
600+
[
601+
"python/google/protobuf/internal/*_test.py",
602+
"python/google/protobuf/internal/test_util.py",
603+
],
604+
),
605+
imports = ["python"],
628606
srcs_version = "PY2AND3",
629607
deps = [
630608
":protobuf_python",

WORKSPACE

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
new_http_archive(
2-
name = "gmock_archive",
3-
url = "https://googlemock.googlecode.com/files/gmock-1.7.0.zip",
4-
sha256 = "26fcbb5925b74ad5fc8c26b0495dfc96353f4d553492eb97e85a8a6d2f43095b",
5-
build_file = "gmock.BUILD",
2+
name = "gmock_archive",
3+
url = "https://googlemock.googlecode.com/files/gmock-1.7.0.zip",
4+
sha256 = "26fcbb5925b74ad5fc8c26b0495dfc96353f4d553492eb97e85a8a6d2f43095b",
5+
build_file = "gmock.BUILD",
66
)
77

88
new_http_archive(
9-
name = "six_archive",
10-
url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55",
11-
sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
12-
build_file = "six.BUILD",
9+
name = "six_archive",
10+
url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55",
11+
sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
12+
build_file = "six.BUILD",
1313
)
1414

1515
bind(
16-
name = "gtest",
17-
actual = "@gmock_archive//:gtest",
16+
name = "python_headers",
17+
actual = "//util/python:python_headers",
1818
)
1919

2020
bind(
21-
name = "gtest_main",
22-
actual = "@gmock_archive//:gtest_main",
21+
name = "gtest",
22+
actual = "@gmock_archive//:gtest",
2323
)
2424

2525
bind(
26-
name = "six",
27-
actual = "@six_archive//:six",
26+
name = "gtest_main",
27+
actual = "@gmock_archive//:gtest_main",
28+
)
29+
30+
bind(
31+
name = "six",
32+
actual = "@six_archive//:six",
2833
)

protobuf.bzl

+6-44
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ def cc_proto_library(
117117
deps=[],
118118
cc_libs=[],
119119
include=None,
120-
protoc="//google/protobuf:protoc",
120+
protoc="//:protoc",
121121
internal_bootstrap_hack=False,
122122
use_grpc_plugin=False,
123-
default_runtime="//google/protobuf:protobuf",
123+
default_runtime="//:protobuf",
124124
**kargs):
125125
"""Bazel rule to create a C++ protobuf library from proto source files
126126
@@ -199,44 +199,15 @@ def cc_proto_library(
199199
includes=includes,
200200
**kargs)
201201

202-
def internal_copied_filegroup(
203-
name,
204-
srcs,
205-
include,
206-
**kargs):
207-
"""Bazel rule to fix sources file to workaround with python path issues.
208-
209-
Args:
210-
name: the name of the internal_copied_filegroup rule, which will be the
211-
name of the generated filegroup.
212-
srcs: the source files to be copied.
213-
include: the expected import root of the source.
214-
**kargs: extra arguments that will be passed into the filegroup.
215-
"""
216-
outs = [_RelativeOutputPath(s, include) for s in srcs]
217-
218-
native.genrule(
219-
name=name+"_genrule",
220-
srcs=srcs,
221-
outs=outs,
222-
cmd=" && ".join(["cp $(location %s) $(location %s)" %
223-
(s, _RelativeOutputPath(s, include))
224-
for s in srcs]))
225-
226-
native.filegroup(
227-
name=name,
228-
srcs=outs,
229-
**kargs)
230-
231202
def py_proto_library(
232203
name,
233204
srcs=[],
234205
deps=[],
235206
py_libs=[],
236207
py_extra_srcs=[],
237208
include=None,
238-
default_runtime="//google/protobuf:protobuf_python",
239-
protoc="//google/protobuf:protoc",
209+
default_runtime="//:protobuf_python",
210+
protoc="//:protoc",
240211
**kargs):
241212
"""Bazel rule to create a Python protobuf library from proto source files
242213
@@ -276,22 +247,14 @@ def py_proto_library(
276247
visibility=["//visibility:public"],
277248
)
278249

279-
if include != None:
280-
# Copy the output files to the desired location to make the import work.
281-
internal_copied_filegroup_name=name + "_internal_copied_filegroup"
282-
internal_copied_filegroup(
283-
name=internal_copied_filegroup_name,
284-
srcs=outs,
285-
include=include)
286-
outs=[internal_copied_filegroup_name]
287-
288250
if default_runtime and not default_runtime in py_libs + deps:
289251
py_libs += [default_runtime]
290252

291253
native.py_library(
292254
name=name,
293255
srcs=outs+py_extra_srcs,
294256
deps=py_libs+deps,
257+
imports=includes,
295258
**kargs)
296259

297260
def internal_protobuf_py_tests(
@@ -308,8 +271,7 @@ def internal_protobuf_py_tests(
308271
309272
"""
310273
for m in modules:
311-
s = _RelativeOutputPath(
312-
"python/google/protobuf/internal/%s.py" % m, "python")
274+
s = "python/google/protobuf/internal/%s.py" % m
313275
native.py_test(
314276
name="py_%s" % m,
315277
srcs=[s],

util/python/BUILD

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
# This is a placeholder for python headers. Projects needing to use
22
# fast cpp protos in protobuf's python interface should build with
33
# --define=use_fast_cpp_protos=true, and in addition, provide
4-
# //util/python:python_headers dependency that in turn provides Python.h.
4+
# //external:python_headers dependency that in turn provides Python.h.
5+
#
6+
# Projects that include protobuf using a Bazel external repository will need to
7+
# add a workspace rule to their WORKSPACE files to add an external workspace
8+
# that includes the Python headers. For example, the protobuf WORKSPACE file
9+
# includes the following local_repository rule that points to this directory:
10+
#
11+
# new_local_repository(
12+
# name = "python",
13+
# path = __workspace_dir__ + "/util/python",
14+
# )
515
cc_library(
616
name = "python_headers",
717
visibility = ["//visibility:public"],

0 commit comments

Comments
 (0)