diff --git a/BUILD.bazel b/BUILD.bazel index 6f360e0828..e8a26c5709 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,17 +1,14 @@ # Bazel (https://bazel.build/) BUILD file for Protobuf. load("@bazel_skylib//rules:common_settings.bzl", "string_flag") -load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library","cc_test") +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "cc_test") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") -load("@rules_python//python:defs.bzl", "py_library") load("@rules_java//java:defs.bzl", "java_binary", "java_lite_proto_library", "java_proto_library") load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS") load( ":protobuf.bzl", "adapt_proto_library", - "internal_copied_filegroup", - "internal_protobuf_py_tests", "py_proto_library", ) @@ -538,9 +535,15 @@ RELATIVE_TEST_PROTOS = [ TEST_PROTOS = ["src/" + s for s in RELATIVE_TEST_PROTOS] +filegroup( + name = "test_proto_srcs", + srcs = TEST_PROTOS, + visibility = ["//:__subpackages__"], +) + proto_library( name = "test_protos", - srcs = TEST_PROTOS, + srcs = [":test_proto_srcs"], strip_import_prefix = "src", visibility = ["//:__subpackages__"], deps = [ @@ -819,264 +822,40 @@ alias( # Python support ################################################################################ -py_library( +alias( + name = "protobuf_python", + actual = "//python:protobuf_python", + visibility = ["//visibility:public"], +) + +alias( name = "python_srcs", - srcs = glob( - [ - "python/google/protobuf/**/*.py", - ], - ), - imports = ["python"], - srcs_version = "PY2AND3", + actual = "//python:python_srcs", visibility = ["@upb//:__subpackages__"], ) -py_library( +alias( name = "python_test_srcs", - srcs = glob( - [ - "python/google/protobuf/internal/*_test.py", - "python/google/protobuf/internal/test_util.py", - ], - ), - imports = ["python"], - srcs_version = "PY3", + actual = "//python:python_test_srcs", visibility = ["@upb//:__subpackages__"], ) -cc_binary( - name = "python/google/protobuf/internal/_api_implementation.so", - srcs = ["python/google/protobuf/internal/api_implementation.cc"], - copts = COPTS + [ - "-DPYTHON_PROTO2_CPP_IMPL_V2", - ], - linkshared = 1, - linkstatic = 1, - tags = [ - # Exclude this target from wildcard expansion (//...) because it may - # not even be buildable. It will be built if it is needed according - # to :use_fast_cpp_protos. - # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes - "manual", - ], - deps = select({ - "//conditions:default": [], - ":use_fast_cpp_protos": ["//external:python_headers"], - }), -) - -cc_binary( - name = "python/google/protobuf/pyext/_message.so", - srcs = glob([ - "python/google/protobuf/pyext/*.cc", - "python/google/protobuf/pyext/*.h", - ]), - copts = COPTS + [ - "-DGOOGLE_PROTOBUF_HAS_ONEOF=1", - ] + select({ - "//conditions:default": [], - ":allow_oversize_protos": ["-DPROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS=1"], - }), - includes = [ - "python/", - "src/", - ], - linkshared = 1, - linkstatic = 1, - tags = [ - # Exclude this target from wildcard expansion (//...) because it may - # not even be buildable. It will be built if it is needed according - # to :use_fast_cpp_protos. - # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes - "manual", - ], - deps = [ - ":protobuf", - ":proto_api", - ] + select({ - "//conditions:default": [], - ":use_fast_cpp_protos": ["//external:python_headers"], - }), -) - -config_setting( - name = "use_fast_cpp_protos", - values = { - "define": "use_fast_cpp_protos=true", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -config_setting( - name = "allow_oversize_protos", - values = { - "define": "allow_oversize_protos=true", - }, - visibility = [ - # Public, but Protobuf only visibility. - "//:__subpackages__", - ], -) - -# Copy the builtin proto files from src/google/protobuf to -# python/google/protobuf. This way, the generated Python sources will be in the -# same directory as the Python runtime sources. This is necessary for the -# modules to be imported correctly since they are all part of the same Python -# package. -internal_copied_filegroup( - name = "protos_python", - srcs = [ - "src/google/protobuf/any.proto", - "src/google/protobuf/api.proto", - "src/google/protobuf/compiler/plugin.proto", - "src/google/protobuf/descriptor.proto", - "src/google/protobuf/duration.proto", - "src/google/protobuf/empty.proto", - "src/google/protobuf/field_mask.proto", - "src/google/protobuf/source_context.proto", - "src/google/protobuf/struct.proto", - "src/google/protobuf/timestamp.proto", - "src/google/protobuf/type.proto", - "src/google/protobuf/wrappers.proto", - ], - dest = "python", - strip_prefix = "src", -) - -py_proto_library( +alias( name = "well_known_types_py_pb2", - srcs = [ - "python/google/protobuf/any.proto", - "python/google/protobuf/api.proto", - "python/google/protobuf/compiler/plugin.proto", - "python/google/protobuf/descriptor.proto", - "python/google/protobuf/duration.proto", - "python/google/protobuf/empty.proto", - "python/google/protobuf/field_mask.proto", - "python/google/protobuf/source_context.proto", - "python/google/protobuf/struct.proto", - "python/google/protobuf/timestamp.proto", - "python/google/protobuf/type.proto", - "python/google/protobuf/wrappers.proto", - ], - include = "python", - default_runtime = "", - protoc = ":protoc", - srcs_version = "PY2AND3", + actual = "//python:well_known_types_py_pb2", visibility = ["@upb//:__subpackages__"], ) -py_library( - name = "protobuf_python", - data = select({ - "//conditions:default": [], - ":use_fast_cpp_protos": [ - ":python/google/protobuf/internal/_api_implementation.so", - ":python/google/protobuf/pyext/_message.so", - ], - }), - deps = [ - ":python_srcs", - ":well_known_types_py_pb2", - ], -) - -# Copy the test proto files from src/google/protobuf to -# python/google/protobuf. This way, the generated Python sources will be in the -# same directory as the Python runtime sources. This is necessary for the -# modules to be imported correctly by the tests since they are all part of the -# same Python package. -internal_copied_filegroup( - name = "protos_python_test", - srcs = LITE_TEST_PROTOS + TEST_PROTOS, - dest = "python", - strip_prefix = "src", -) - -# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in -# which case we can simply add :protos_python_test in srcs. -COPIED_LITE_TEST_PROTOS = ["python/" + s for s in RELATIVE_LITE_TEST_PROTOS] - -COPIED_TEST_PROTOS = ["python/" + s for s in RELATIVE_TEST_PROTOS] - -py_proto_library( +alias( name = "python_common_test_protos", - srcs = COPIED_LITE_TEST_PROTOS + COPIED_TEST_PROTOS, - include = "python", - default_runtime = "", - protoc = ":protoc", - srcs_version = "PY2AND3", + actual = "//python:python_common_test_protos", visibility = ["//visibility:public"], - deps = [":well_known_types_py_pb2"], ) -py_proto_library( +alias( name = "python_specific_test_protos", - srcs = glob([ - "python/google/protobuf/internal/*.proto", - "python/google/protobuf/internal/import_test_package/*.proto", - ]), - include = "python", - default_runtime = ":protobuf_python", - protoc = ":protoc", - srcs_version = "PY2AND3", + actual = "//python:python_specific_test_protos", visibility = ["//visibility:public"], - deps = [":python_common_test_protos"], -) - -py_library( - name = "python_tests", - srcs = glob( - [ - "python/google/protobuf/internal/*_test.py", - "python/google/protobuf/internal/test_util.py", - "python/google/protobuf/internal/import_test_package/__init__.py", - ], - ), - imports = ["python"], - srcs_version = "PY2AND3", - deps = [ - ":protobuf_python", - ":python_common_test_protos", - ":python_specific_test_protos", - ], -) - -internal_protobuf_py_tests( - name = "python_tests_batch", - data = glob([ - "src/google/protobuf/**/*", - ]), - modules = [ - "descriptor_database_test", - "descriptor_pool_test", - "descriptor_test", - "generator_test", - "json_format_test", - "message_factory_test", - "message_test", - "proto_builder_test", - "reflection_test", - "service_reflection_test", - "symbol_database_test", - "text_encoding_test", - "text_format_test", - "unknown_fields_test", - "wire_format_test", - ], - deps = [":python_tests"], -) - -cc_library( - name = "proto_api", - hdrs = ["python/google/protobuf/proto_api.h"], - visibility = ["//visibility:public"], - deps = [ - "//external:python_headers", - ], ) proto_lang_toolchain( @@ -1122,25 +901,21 @@ genrule( name = "generated_protos", srcs = ["src/google/protobuf/unittest_import.proto"], outs = ["unittest_gen_import.proto"], - cmd = "cat $(SRCS) | sed 's|google/|src/google/|' > $(OUTS)", + cmd = "cat $(SRCS) > $(OUTS)", ) proto_library( name = "generated_protos_proto", - srcs = [ - "src/google/protobuf/unittest_import_public.proto", - "unittest_gen_import.proto", - ], + srcs = [":generated_protos"], + deps = [":generic_test_protos"], ) py_proto_library( name = "generated_protos_py", - srcs = [ - "src/google/protobuf/unittest_import_public.proto", - "unittest_gen_import.proto", - ], + srcs = [":generated_protos"], default_runtime = "", protoc = ":protoc", + deps = ["//python:python_common_test_protos"], ) ################################################################################ @@ -1361,29 +1136,3 @@ pkg_files( ], visibility = ["//pkg:__pkg__"], ) - -# Python runtime -pkg_files( - name = "python_dist_files", - srcs = glob([ - "python/google/**/*.proto", - "python/google/**/*.py", - "python/google/protobuf/internal/*.cc", - "python/google/protobuf/pyext/*.cc", - "python/google/protobuf/pyext/*.h", - ]) + [ - "python/MANIFEST.in", - "python/README.md", - "python/google/protobuf/proto_api.h", - "python/google/protobuf/pyext/README", - "python/google/protobuf/python_protobuf.h", - "python/mox.py", - "python/release.sh", - "python/setup.cfg", - "python/setup.py", - "python/stubout.py", - "python/tox.ini", - ], - strip_prefix = strip_prefix.from_root(""), - visibility = ["//pkg:__pkg__"], -) diff --git a/Makefile.am b/Makefile.am index 22c85a4059..7f064294b6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -993,6 +993,7 @@ php_EXTRA_DIST= \ # Note: please keep this in sync with the python_dist_files rule in BUILD.bazel. python_EXTRA_DIST= \ + python/BUILD.bazel \ python/MANIFEST.in \ python/google/__init__.py \ python/google/protobuf/__init__.py \ @@ -1107,6 +1108,7 @@ python_EXTRA_DIST= \ python/google/protobuf/text_format.py \ python/google/protobuf/unknown_fields.py \ python/google/protobuf/util/__init__.py \ + python/internal.bzl \ python/release.sh \ python/mox.py \ python/setup.cfg \ diff --git a/kokoro/common/check_missing_dist_files.sh b/kokoro/common/check_missing_dist_files.sh index 0bb26ad34b..db4d92fc11 100755 --- a/kokoro/common/check_missing_dist_files.sh +++ b/kokoro/common/check_missing_dist_files.sh @@ -50,6 +50,6 @@ fi for (( i=0 ; i < ${#MISSING_FILES[@]} ; i++ )); do echo " ${MISSING_FILES[i]}" done - echo -e "\nAdd them to the `pkg_files` rule in corresponding BUILD.bazel.\n" + echo -e "\nAdd them to the 'pkg_files' rule in corresponding BUILD.bazel.\n" ) >&2 exit 1 diff --git a/kokoro/linux/bazel_distcheck/build.sh b/kokoro/linux/bazel_distcheck/build.sh index 4eb6e11264..740a4aba87 100755 --- a/kokoro/linux/bazel_distcheck/build.sh +++ b/kokoro/linux/bazel_distcheck/build.sh @@ -18,9 +18,14 @@ TEST_TARGETS=( //build_defs:all //conformance:all //java:tests + //python:all //:protobuf_test + @com_google_protobuf_examples//... ) +CONTAINER_NAME=gcr.io/protobuf-build/bazel/linux +CONTAINER_VERSION=5.1.1-e41ccfa1648716433276ebe077c665796550fcbb + use_bazel.sh 5.0.0 || true bazel version @@ -65,20 +70,17 @@ tar -C ${DIST_WORKSPACE} --strip-components=1 -axf ${DIST_ARCHIVE} cd ${DIST_WORKSPACE} FAILED=false -date -bazel fetch --distdir=${TMP_DISTDIR} "${BUILD_ONLY_TARGETS[@]}" "${TEST_TARGETS[@]}" - -date -bazel build --distdir=${TMP_DISTDIR} -k \ - "${BUILD_ONLY_TARGETS[@]}" || FAILED=true - -date -bazel test --distdir=${TMP_DISTDIR} --test_output=errors -k \ - "${TEST_TARGETS[@]}" || FAILED=true +until docker pull gcr.io/protobuf-build/bazel/linux:${CONTAINER_VERSION}; do + sleep 10 +done date -cd examples -bazel build --distdir=${TMP_DISTDIR} //... || FAILED=true +docker run --rm \ + -v ${DIST_WORKSPACE}:/workspace \ + -v ${TMP_DISTDIR}:${TMP_DISTDIR} \ + ${CONTAINER_NAME}:${CONTAINER_VERSION} \ + test --distdir=${TMP_DISTDIR} --test_output=errors -k \ + "${BUILD_ONLY_TARGETS[@]}" "${TEST_TARGETS[@]}" || FAILED=true if ${FAILED}; then echo FAILED diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index 0de27d3a27..e4899445cc 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -238,7 +238,7 @@ pkg_filegroup( name = "python_srcs", srcs = [ ":dist_common", - "//:python_dist_files", + "//python:dist_files", ], ) @@ -342,7 +342,7 @@ gen_automake_file_lists( "//:objectivec_dist_files": "dist_objectivec", "//objectivec:dist_files": "dist_objectivec2", "//php:dist_files": "dist_php", - "//:python_dist_files": "dist_python", + "//python:dist_files": "dist_python", "//ruby:dist_files": "dist_ruby", }, ) @@ -360,6 +360,7 @@ cc_dist_library( deps = [ "//:protobuf_lite", ], + tags = ["manual"], ) cc_dist_library( @@ -375,6 +376,7 @@ cc_dist_library( "//:protobuf", "//:protobuf_lite", ], + tags = ["manual"], ) ################################################################################ diff --git a/protobuf.bzl b/protobuf.bzl index 1fbd747efc..7981c50f03 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -58,21 +58,6 @@ def _PyOuts(srcs, use_grpc_plugin = False): ret += [s[:-len(".proto")] + "_pb2_grpc.py" for s in srcs] return ret -def _RelativeOutputPath(path, include, dest = ""): - if include == None: - return path - - if not path.startswith(include): - fail("Include path %s isn't part of the path %s." % (include, path)) - - if include and include[-1] != "/": - include = include + "/" - if dest and dest[-1] != "/": - dest = dest + "/" - - path = path[len(include):] - return dest + path - ProtoGenInfo = provider( fields = ["srcs", "import_flags", "deps"], ) @@ -469,41 +454,6 @@ internal_gen_kt_protos = rule( }, ) -def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): - """Macro to copy files to a different directory and then create a filegroup. - - This is used by the //:protobuf_python py_proto_library target to work around - an issue caused by Python source files that are part of the same Python - package being in separate directories. - - Args: - srcs: The source files to copy and add to the filegroup. - strip_prefix: Path to the root of the files to copy. - dest: The directory to copy the source files into. - **kwargs: extra arguments that will be passesd to the filegroup. - """ - outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs] - - native.genrule( - name = name + "_genrule", - srcs = srcs, - outs = outs, - cmd_bash = " && ".join( - ["cp $(location %s) $(location %s)" % - (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs], - ), - cmd_bat = " && ".join( - ["@copy /Y $(location %s) $(location %s) >NUL" % - (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs], - ), - ) - - native.filegroup( - name = name, - srcs = outs, - **kwargs - ) - def py_proto_library( name, srcs = [], @@ -571,28 +521,6 @@ def py_proto_library( **kargs ) -def internal_protobuf_py_tests( - name, - modules = [], - **kargs): - """Bazel rules to create batch tests for protobuf internal. - - Args: - name: the name of the rule. - modules: a list of modules for tests. The macro will create a py_test for - each of the parameter with the source "google/protobuf/%s.py" - kargs: extra parameters that will be passed into the py_test. - - """ - for m in modules: - s = "python/google/protobuf/internal/%s.py" % m - py_test( - name = "py_%s" % m, - srcs = [s], - main = s, - **kargs - ) - def check_protobuf_required_bazel_version(): """For WORKSPACE files, to check the installed version of bazel. diff --git a/python/BUILD.bazel b/python/BUILD.bazel new file mode 100644 index 0000000000..6316febca7 --- /dev/null +++ b/python/BUILD.bazel @@ -0,0 +1,351 @@ +# Protobuf Python runtime +# +# See also code generation logic under /src/google/protobuf/compiler/python. +# +# Most users should depend upon public aliases in the root: +# //:protobuf_python +# //:well_known_types_py_pb2 + +load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@rules_python//python:defs.bzl", "py_library") +load("//:protobuf.bzl", "py_proto_library") +load("//build_defs:cpp_opts.bzl", "COPTS") +load(":internal.bzl", "internal_copy_files") + +py_library( + name = "protobuf_python", + data = select({ + "//conditions:default": [], + ":use_fast_cpp_protos": [ + ":google/protobuf/internal/_api_implementation.so", + ":google/protobuf/pyext/_message.so", + ], + }), + visibility = ["//:__pkg__"], + deps = [ + ":python_srcs", + ":well_known_types_py_pb2", + ], +) + +config_setting( + name = "use_fast_cpp_protos", + values = { + "define": "use_fast_cpp_protos=true", + }, +) + +py_proto_library( + name = "well_known_types_py_pb2", + srcs = [":copied_wkt_proto_files"], + include = ".", + default_runtime = "", + protoc = "//:protoc", + srcs_version = "PY2AND3", + visibility = [ + "//:__pkg__", + "@upb//:__subpackages__", + ], +) + +internal_copy_files( + name = "copied_wkt_proto_files", + srcs = [ + "//:built_in_runtime_protos", + "//:well_known_type_protos", + ], + strip_prefix = "src", +) + +cc_binary( + name = "google/protobuf/internal/_api_implementation.so", + srcs = ["google/protobuf/internal/api_implementation.cc"], + copts = COPTS + [ + "-DPYTHON_PROTO2_CPP_IMPL_V2", + ], + linkshared = 1, + linkstatic = 1, + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], + deps = select({ + "//conditions:default": [], + ":use_fast_cpp_protos": ["//external:python_headers"], + }), +) + +config_setting( + name = "allow_oversize_protos", + values = { + "define": "allow_oversize_protos=true", + }, +) + +cc_binary( + name = "google/protobuf/pyext/_message.so", + srcs = glob([ + "google/protobuf/pyext/*.cc", + "google/protobuf/pyext/*.h", + ]), + copts = COPTS + [ + "-DGOOGLE_PROTOBUF_HAS_ONEOF=1", + ] + select({ + "//conditions:default": [], + ":allow_oversize_protos": ["-DPROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS=1"], + }), + includes = ["."], + linkshared = 1, + linkstatic = 1, + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], + deps = [ + ":proto_api", + "//:protobuf", + ] + select({ + "//conditions:default": [], + ":use_fast_cpp_protos": ["//external:python_headers"], + }), +) + +py_library( + name = "python_srcs", + srcs = glob( + [ + "google/protobuf/**/*.py", + ], + exclude = [ + "google/protobuf/internal/*_test.py", + "google/protobuf/internal/test_util.py", + "google/protobuf/internal/import_test_package/__init__.py", + ], + ), + imports = ["python"], + srcs_version = "PY2AND3", + visibility = [ + "//:__pkg__", + "@upb//:__subpackages__", + ], +) + +py_library( + name = "python_test_srcs", + srcs = glob([ + "google/protobuf/internal/*_test.py", + ]) + [ + "google/protobuf/internal/test_util.py", + "google/protobuf/internal/import_test_package/__init__.py", + ], + imports = ["python"], + srcs_version = "PY3", + visibility = [ + "//:__pkg__", + "@upb//:__subpackages__", + ], +) + +################################################################################ +# Tests +################################################################################ + +internal_copy_files( + name = "copied_test_proto_files", + srcs = ["//:test_proto_srcs"], + strip_prefix = "src", +) + +py_proto_library( + name = "python_common_test_protos", + srcs = [":copied_test_proto_files"], + include = ".", + default_runtime = "", + protoc = "//:protoc", + srcs_version = "PY2AND3", + visibility = ["//:__pkg__"], + deps = [":well_known_types_py_pb2"], +) + +py_proto_library( + name = "python_specific_test_protos", + srcs = glob([ + "google/protobuf/internal/*.proto", + "google/protobuf/internal/import_test_package/*.proto", + ]), + include = ".", + default_runtime = ":protobuf_python", + protoc = "//:protoc", + srcs_version = "PY2AND3", + visibility = ["//:__pkg__"], + deps = [":python_common_test_protos"], +) + +py_library( + name = "python_test_lib", + srcs = [ + "google/protobuf/internal/import_test_package/__init__.py", + "google/protobuf/internal/test_util.py", + ], + imports = ["python"], + srcs_version = "PY2AND3", + deps = [ + ":protobuf_python", + ":python_common_test_protos", + ":python_specific_test_protos", + ], +) + +py_test( + name = "descriptor_database_test", + srcs = ["google/protobuf/internal/descriptor_database_test.py"], + deps = [":python_test_lib"], +) + +py_test( + name = "descriptor_pool_test", + srcs = ["google/protobuf/internal/descriptor_pool_test.py"], + deps = [":python_test_lib"], +) + +py_test( + name = "descriptor_test", + srcs = ["google/protobuf/internal/descriptor_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "generator_test", + srcs = ["google/protobuf/internal/generator_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "json_format_test", + srcs = ["google/protobuf/internal/json_format_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "message_factory_test", + srcs = ["google/protobuf/internal/message_factory_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "message_test", + srcs = ["google/protobuf/internal/message_test.py"], + data = glob(["testdata/golden_pickle_*"]) + [ + "//:testdata", + ], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "proto_builder_test", + srcs = ["google/protobuf/internal/proto_builder_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "reflection_test", + srcs = ["google/protobuf/internal/reflection_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "service_reflection_test", + srcs = ["google/protobuf/internal/service_reflection_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "symbol_database_test", + srcs = ["google/protobuf/internal/symbol_database_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "text_encoding_test", + srcs = ["google/protobuf/internal/text_encoding_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "text_format_test", + srcs = ["google/protobuf/internal/text_format_test.py"], + data = ["//:testdata"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "unknown_fields_test", + srcs = ["google/protobuf/internal/unknown_fields_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +py_test( + name = "wire_format_test", + srcs = ["google/protobuf/internal/wire_format_test.py"], + imports = ["."], + deps = [":python_test_lib"], +) + +cc_library( + name = "proto_api", + hdrs = ["python/google/protobuf/proto_api.h"], + visibility = ["//visibility:public"], + deps = [ + "//external:python_headers", + ], +) + +################################################################################ +# Distribution files +################################################################################ + +pkg_files( + name = "dist_files", + srcs = glob([ + "google/**/*.proto", + "google/**/*.py", + "google/protobuf/internal/*.cc", + "google/protobuf/pyext/*.cc", + "google/protobuf/pyext/*.h", + ]) + [ + "BUILD.bazel", + "MANIFEST.in", + "README.md", + "google/protobuf/proto_api.h", + "google/protobuf/pyext/README", + "google/protobuf/python_protobuf.h", + "internal.bzl", + "mox.py", + "release.sh", + "setup.cfg", + "setup.py", + "stubout.py", + "tox.ini", + ], + strip_prefix = strip_prefix.from_root(""), + visibility = ["//pkg:__pkg__"], +) diff --git a/python/internal.bzl b/python/internal.bzl new file mode 100644 index 0000000000..a33a6a649e --- /dev/null +++ b/python/internal.bzl @@ -0,0 +1,106 @@ +# Internal helpers for building the Python protobuf runtime. + +def _internal_copy_files_impl(ctx): + strip_prefix = ctx.attr.strip_prefix + if strip_prefix[-1] != "/": + strip_prefix += "/" + + src_dests = [] + for src in ctx.files.srcs: + if src.short_path[:len(strip_prefix)] != strip_prefix: + fail("Source does not start with %s: %s" % + (strip_prefix, src.short_path)) + dest = ctx.actions.declare_file(src.short_path[len(strip_prefix):]) + src_dests.append([src, dest]) + + if ctx.attr.is_windows: + bat_file = ctx.actions.declare_file(ctx.label.name + "_copy.bat") + ctx.actions.write( + output = bat_file, + content = "\r\n".join([ + '@copy /Y "{}" "{}" >NUL'.format( + src.path.replace("/", "\\"), + dest.path.replace("/", "\\"), + ) + for src, dest in src_dests + ]) + "\r\n", + ) + ctx.actions.run( + inputs = ctx.files.srcs, + tools = [bat_file], + outputs = [dest for src, dest in src_dests], + executable = "cmd.exe", + arguments = ["/C", bat_file.path.replace("/", "\\")], + mnemonic = "InternalCopyFile", + progress_message = "Copying files", + use_default_shell_env = True, + ) + + else: + sh_file = ctx.actions.declare_file(ctx.label.name + "_copy.sh") + ctx.actions.write( + output = sh_file, + content = "\n".join([ + 'cp -f "{}" "{}"'.format(src.path, dest.path) + for src, dest in src_dests + ]), + ) + ctx.actions.run( + inputs = ctx.files.srcs, + tools = [sh_file], + outputs = [dest for src, dest in src_dests], + executable = "bash", + arguments = [sh_file.path], + mnemonic = "InternalCopyFile", + progress_message = "Copying files", + use_default_shell_env = True, + ) + + return [ + DefaultInfo(files = depset([dest for src, dest in src_dests])), + ] + +internal_copy_files_impl = rule( + doc = """ +Implementation for internal_copy_files macro. + +This rule implements file copying, including a compatibility mode for Windows. +""", + implementation = _internal_copy_files_impl, + attrs = { + "srcs": attr.label_list(allow_files = True, providers = [DefaultInfo]), + "strip_prefix": attr.string(), + "is_windows": attr.bool(), + }, +) + +def internal_copy_files(name, srcs, strip_prefix): + """Copies common proto files to the python tree. + + In order for Python imports to work, generated proto interfaces under + the google.protobuf package need to be in the same directory as other + source files. This rule copies the .proto files themselves, e.g. with + strip_prefix = 'src', 'src/google/protobuf/blah.proto' could be copied + to '/google/protobuf/blah.proto'. + + (An alternative might be to implement a separate rule to generate + Python code in a different location for the sources. However, this + would be strange behavior that doesn't match any other language's proto + library generation.) + + Args: + name: the name for the rule. + srcs: the sources. + strip_prefix: the prefix to remove from each of the paths in 'srcs'. The + remainder will be used to construct the output path. + + """ + internal_copy_files_impl( + name = name, + srcs = srcs, + strip_prefix = strip_prefix, + is_windows = select({ + "@bazel_tools//src/conditions:host_windows": True, + "//conditions:default": False, + }), + )