Merge branch 'main' into pse/readonlyspan-proposal-repeated-field

pull/16772/head
Adam Cozzette 3 months ago
commit dcb862aac6
  1. 3
      .bazelignore
  2. 5
      .bazelrc
  3. 77
      .bcr/metadata.template.json
  4. 13
      .bcr/presubmit.yml
  5. 2
      .github/BUILD.bazel
  6. 4
      .github/dependabot.yml
  7. 75
      .github/scripts/validate_yaml.py
  8. 9
      .github/scripts/validate_yaml_test.sh
  9. 3
      .github/workflows/janitor.yml
  10. 2
      .github/workflows/scorecard.yml
  11. 19
      .github/workflows/staleness_check.yml
  12. 34
      .github/workflows/test_bazel.yml
  13. 256
      .github/workflows/test_cpp.yml
  14. 10
      .github/workflows/test_csharp.yml
  15. 101
      .github/workflows/test_java.yml
  16. 53
      .github/workflows/test_objectivec.yml
  17. 79
      .github/workflows/test_php.yml
  18. 26
      .github/workflows/test_php_ext.yml
  19. 39
      .github/workflows/test_python.yml
  20. 25
      .github/workflows/test_release_branches.yml
  21. 72
      .github/workflows/test_ruby.yml
  22. 122
      .github/workflows/test_runner.yml
  23. 33
      .github/workflows/test_rust.yml
  24. 127
      .github/workflows/test_upb.yml
  25. 25
      .github/workflows/test_yaml.yml
  26. 11
      .gitmodules
  27. 2
      .readthedocs.yml
  28. 80
      BUILD.bazel
  29. 56
      CMakeLists.txt
  30. 354
      Cargo.bazel.lock
  31. 8
      Cargo.lock
  32. 113
      MODULE.bazel
  33. 48
      Protobuf-C++.podspec
  34. 23
      Protobuf.podspec
  35. 89
      WORKSPACE
  36. 45
      WORKSPACE.bzlmod
  37. 24
      bazel/BUILD.bazel
  38. 9
      bazel/cc_proto_library.bzl
  39. 22
      bazel/common/BUILD
  40. 355
      bazel/common/proto_common.bzl
  41. 6
      bazel/common/proto_info.bzl
  42. 25
      bazel/common/proto_lang_toolchain_info.bzl
  43. 15
      bazel/java_lite_proto_library.bzl
  44. 15
      bazel/java_proto_library.bzl
  45. 211
      bazel/private/BUILD
  46. 42
      bazel/private/BUILD.bazel
  47. 198
      bazel/private/bazel_cc_proto_library.bzl
  48. 164
      bazel/private/bazel_java_proto_library_rule.bzl
  49. 356
      bazel/private/bazel_proto_library_rule.bzl
  50. 6
      bazel/private/cc_proto_aspect.bzl
  51. 143
      bazel/private/cc_proto_support.bzl
  52. 178
      bazel/private/java_lite_proto_library.bzl
  53. 62
      bazel/private/java_proto_support.bzl
  54. 4
      bazel/private/native.bzl
  55. 35
      bazel/private/native_bool_flag.bzl
  56. 59
      bazel/private/proto_bazel_features.bzl
  57. 186
      bazel/private/proto_info.bzl
  58. 155
      bazel/private/proto_lang_toolchain_rule.bzl
  59. 14
      bazel/private/proto_toolchain_rule.bzl
  60. 49
      bazel/private/toolchain_helpers.bzl
  61. 85
      bazel/private/toolchains/BUILD.bazel
  62. 135
      bazel/private/upb_proto_library_internal/aspect.bzl
  63. 35
      bazel/private/upb_proto_library_internal/cc_library_func.bzl
  64. 21
      bazel/proto_library.bzl
  65. 17
      bazel/py_proto_library.bzl
  66. 5
      bazel/tests/BUILD
  67. 368
      bazel/tests/proto_common_compile_tests.bzl
  68. 136
      bazel/tests/testdata/BUILD
  69. 57
      bazel/tests/testdata/compile_rule.bzl
  70. 18
      bazel/toolchains/BUILD
  71. 17
      bazel/toolchains/proto_lang_toolchain.bzl
  72. 10
      bazel/toolchains/proto_toolchain.bzl
  73. 5
      bazel/upb_c_proto_library.bzl
  74. 3
      bazel/upb_minitable_proto_library.bzl
  75. 4
      bazel/upb_proto_reflection_library.bzl
  76. 7
      benchmarks/BUILD
  77. 2
      benchmarks/BUILD.googleapis
  78. 8
      benchmarks/build_defs.bzl
  79. 42
      benchmarks/descriptor_sv.proto
  80. 5
      build_defs/cpp_opts.bzl
  81. 7
      build_defs/internal_shell.bzl
  82. 16
      build_defs/java_opts.bzl
  83. 61
      build_defs/kotlin_opts.bzl
  84. 5
      ci/Linux.bazelrc
  85. 4
      ci/Windows.bazelrc
  86. 9
      ci/common.bazelrc
  87. 7
      ci/macOS.bazelrc
  88. 25
      cmake/BUILD.bazel
  89. 26
      cmake/README.md
  90. 50
      cmake/abseil-cpp.cmake
  91. 55
      cmake/conformance.cmake
  92. 34
      cmake/dependencies.cmake
  93. 143
      cmake/dependencies_generator.py
  94. 62
      cmake/gtest.cmake
  95. 19
      cmake/install.cmake
  96. 1
      cmake/libprotobuf-lite.cmake
  97. 9
      cmake/protobuf-config-version.cmake.in
  98. 17
      cmake/protobuf-configure-target.cmake
  99. 11
      cmake/protobuf-generate.cmake
  100. 17
      cmake/tests.cmake
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,4 +1 @@
# These are fetched as external repositories.
third_party/abseil-cpp
third_party/googletest
_build/

@ -1,5 +1,8 @@
build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
# TODO: ErrorProne's SelfAssertions are violated in protobuf's test
build --javacopt=-Xep:SelfAssertion:WARN
build:dbg --compilation_mode=dbg
build:opt --compilation_mode=opt
@ -22,6 +25,8 @@ build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1
# Workaround for the fact that Bazel links with $CC, not $CXX
# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748
build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
# Abseil passes nullptr to memcmp with 0 size
build:ubsan --copt=-fno-sanitize=nonnull-attribute
# TODO: migrate all dependencies from WORKSPACE to MODULE.bazel
# https://github.com/protocolbuffers/protobuf/issues/14313

@ -1,6 +1,11 @@
{
"homepage": "https://github.com/protocolbuffers/protobuf",
"maintainers": [
{
"email": "protobuf-packages@google.com",
"github": "protobuf-team-bot",
"name": "Protobuf Team"
},
{
"email": "sandyzhang@google.com",
"github": "zhangskz",
@ -15,6 +20,78 @@
"email": "gberg@google.com",
"github": "googleberg",
"name": "Jerry Berg"
},
{
"email": "acozzette@google.com",
"github": "acozzette",
"name": "Adam Cozzette",
"do_not_notify": true
},
{
"email": "deannagarcia@google.com",
"github": "deannagarcia",
"name": "Deanna Garcia",
"do_not_notify": true
},
{
"email": "esrauch@google.com",
"github": "esrauchg",
"name": "Em Rauch",
"do_not_notify": true
},
{
"email": "haberman@google.com",
"github": "haberman",
"name": "Josh Haberman",
"do_not_notify": true
},
{
"email": "hongshin@google.com",
"github": "honglooker",
"name": "Hong Shin",
"do_not_notify": true
},
{
"email": "jatl@google.com",
"github": "JasonLunn",
"name": "Jason Lunn",
"do_not_notify": true
},
{
"email": "jieluo@google.com",
"github": "anandolee",
"name": "Jie Luo",
"do_not_notify": true
},
{
"email": "salo@google.com",
"github": "salo",
"name": "Eric Salo",
"do_not_notify": true
},
{
"email": "sbenza@google.com",
"github": "sbenza",
"name": "Samuel Benzaquen",
"do_not_notify": true
},
{
"email": "shaod@google.com",
"github": "shaod2",
"name": "Dennis Shao",
"do_not_notify": true
},
{
"email": "theodorerose@google.com",
"github": "theodorerose",
"name": "Theodore Rose",
"do_not_notify": true
},
{
"email": "tonyliaoss@google.com",
"github": "tonyliaoss",
"name": "Tony Liao",
"do_not_notify": true
}
],
"repository": ["github:protocolbuffers/protobuf"],

@ -1,13 +1,20 @@
matrix:
platform: ["debian10", "macos", "ubuntu2004", "windows"]
bazel: [7.x]
tasks:
verify_targets:
name: "Verify build targets"
platform: ${{ platform }}
bazel: ${{ bazel }}
build_flags:
- '--host_cxxopt=-std=c++17'
- '--cxxopt=-std=c++17'
build_targets:
- '@protobuf//:protobuf'
- '@protobuf//:protobuf_lite'
- '@protobuf//:protobuf_python'
- '@protobuf//:protobuf_java'
- '@protobuf//:protoc'
- '@protobuf//:test_messages_proto2_cc_proto'
- '@protobuf//:test_messages_proto3_cc_proto'
@ -15,11 +22,15 @@ tasks:
bcr_test_module:
module_path: "examples"
matrix:
platform: ["debian10", "macos", "ubuntu2004", "windows"]
bazel: [7.x]
tasks:
run_test_module:
name: "Run test module"
platform: ${{ platform }}
bazel: ${{ bazel }}
build_flags:
- '--host_cxxopt=-std=c++17'
- '--cxxopt=-std=c++17'
build_targets:
- "//..."

@ -1,5 +1,5 @@
# This information is extracted from the MacOS runner specs located at:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
# https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md
#
# When updating, also ensure the "xcode_destination" entries in
# `.github/workflows/test_objectivec.yml` are supported for the given versions

@ -4,5 +4,5 @@ updates:
directory: "/"
schedule:
interval: "weekly"
# Allow up to 3 opened pull requests for github-actions versions
open-pull-requests-limit: 3
# Don't allow non-security PRs to be opened.
open-pull-requests-limit: 0

@ -0,0 +1,75 @@
"""Validate the YAML files for GitHub Actions workflows.
TODO: b/359303016 - convert to use unittest
"""
import os
import re
import yaml
# Ensure every job is in the list of blocking jobs.
with open(
os.path.join(os.path.dirname(__file__), '../workflows/test_runner.yml'), 'r'
) as f:
data = yaml.safe_load(f)
# List of all YAML files that are used by jobs in the test_runner.yml file.
yaml_files = []
# Get a list of all jobs in the test_runner, except for the blocking job and
# the tag removal job, which is not always run.
all_jobs = list(data['jobs'].keys())
all_jobs.remove('all-blocking-tests')
all_jobs.remove('remove-tag')
passed = True
blocking_jobs = data['jobs']['all-blocking-tests']['needs']
for job in all_jobs:
if 'uses' in data['jobs'][job]:
yaml_files.append(
os.path.join(
os.path.dirname(__file__),
'../workflows',
os.path.basename(data['jobs'][job]['uses']),
)
)
if job not in blocking_jobs:
passed = False
raise ValueError('Job %s is not in the list of blocking jobs.' % job)
print('PASSED: All jobs are in the list of blocking jobs.')
# Ensure every job with a continuous prefix conditions every step on whether we
# are in a continuous run.
for file in yaml_files:
with open(file, 'r') as f:
data = yaml.safe_load(f)
jobs = data['jobs']
for job in jobs:
if 'steps' not in jobs[job]:
continue
continuous_condition = 'inputs.continuous-prefix' in jobs[job]['name']
steps = jobs[job]['steps']
for step in steps:
if 'name' in step:
name = step['name']
elif 'with' in step and 'name' in step['with']:
name = step['with']['name']
else:
raise ValueError(
'Step in job %s from file %s does not have a name.' % (job, file)
)
if continuous_condition and 'continuous-run' not in step.get('if', ''):
raise ValueError(
'Step %s in job %s from file %s does not check the continuous-run'
' condition' % (name, job, file)
)
if not continuous_condition and 'continuous-run' in step.get('if', ''):
raise ValueError(
'Step %s in job %s from file %s checks the continuous-run'
' condition but the job does not contain the continuous-prefix'
% (name, job, file)
)
print('PASSED: All steps in all jobs check the continuous-run condition.')

@ -0,0 +1,9 @@
#!/bin/bash
source googletest.sh || exit 1
script=${TEST_SRCDIR}/google3/third_party/protobuf/github/validate_yaml
$script || die "Failed to execute $script"
echo "PASS"

@ -45,7 +45,8 @@ jobs:
This issue is labeled `inactive` because the last activity was over
90 days ago.
90 days ago. This issue will be closed and archived after 14
additional days without activity.
close-issue-message: >
We triage inactive PRs and issues in order to make it easier to find
active work. If this issue should remain active or becomes active

@ -47,7 +47,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: SARIF file
path: results.sarif

@ -6,6 +6,11 @@ on:
- cron: 0 10 * * *
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: false
description: "The SHA key for the commit we want to run over"
@ -15,20 +20,14 @@ on:
permissions: {}
jobs:
test:
strategy:
fail-fast: false
matrix:
branch: [main, 22.x, 23.x, 24.x, 25.x, 26.x]
os: [{ name: Linux, value: ubuntu-latest}]
name: Test staleness ${{ matrix.os.name }} ${{ github.head_ref && 'PR' || matrix.branch }}
runs-on: ${{ matrix.os.value }}
name: Test staleness
runs-on: ubuntu-latest
if: ${{ github.event.repository.full_name == 'protocolbuffers/protobuf' }}
steps:
- name: Checkout ${{ github.head_ref && 'PR' || matrix.branch }}
- name: Checkout
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout || github.head_ref || matrix.branch }}
ref: ${{ inputs.safe-checkout || github.head_ref || github.ref }}
- name: Mark runs associated with commits
if: ${{ github.event_name != 'schedule' && github.event_name != 'workflow_dispatch' }}

@ -3,10 +3,20 @@ name: Bazel Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -17,40 +27,46 @@ jobs:
fail-fast: false
matrix:
runner: [ ubuntu, windows, macos ]
bazelversion: [ '7.1.1' ]
bzlmod: [true, false ]
bazelversion: [ '7.1.2' ]
bzlmod: [ true, false ]
toolchain_resolution: [ "" ]
include:
- runner: ubuntu
bazelversion: '6.4.0'
bzlmod: true
# Not running Bazel 6 with bzlmod, because it doesn't support use_repo_rule in rules_jvm_external
bzlmod: false
- runner: ubuntu
bazelversion: '6.4.0'
bzlmod: false
toolchain_resolution: --incompatible_enable_proto_toolchain_resolution=true
- runner: ubuntu
bzlmod: true
toolchain_resolution: --incompatible_enable_proto_toolchain_resolution=true
runs-on: ${{ matrix.runner }}-latest
name: Examples ${{ matrix.runner }} ${{ matrix.bazelversion }}${{ matrix.bzlmod && ' (bzlmod)' || '' }}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Examples ${{ matrix.runner }} ${{ matrix.bazelversion }}${{ matrix.bzlmod && ' (bzlmod)' || '' }} ${{ matrix.toolchain_resolution && ' (toolchain resolution)' || '' }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Windows startup flags
if: runner.os == 'Windows'
if: ${{ runner.os == 'Windows' && (!matrix.continuous-only || inputs.continuous-run) }}
working-directory: examples
shell: bash
run: echo "startup --output_user_root=C:/ --windows_enable_symlinks" >> .bazelrc
- name: Configure Bazel version
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
working-directory: examples
shell: bash
run: echo "${{ matrix.bazelversion }}" > .bazelversion
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
# TODO Silence this until we have a fix.
if: runner.os != 'Windows' || matrix.bzlmod
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: examples
version: ${{ matrix.bazelversion }}
bash: cd examples && bazel build //... $BAZEL_FLAGS --enable_bzlmod=${{ matrix.bzlmod }}
bash: cd examples && bazel build //... $BAZEL_FLAGS --enable_bzlmod=${{ matrix.bzlmod }} ${{ matrix.toolchain_resolution }}

@ -3,10 +3,21 @@ name: C++ Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -18,41 +29,52 @@ jobs:
matrix:
config:
- { name: Optimized, flags: --config=opt }
- { name: Debug, flags: --config=dbg }
- { name: ASAN, flags: --config=asan, runner: ubuntu-20-large }
- { name: MSAN, flags: --config=docker-msan, runner: ubuntu-20-large }
- { name: TSAN, flags: --config=tsan, runner: ubuntu-20-large }
- { name: UBSAN, flags: --config=ubsan }
- { name: No-RTTI, flags: --cxxopt=-fno-rtti }
- { name: Debug, flags: --config=dbg, continuous-only: true }
- { name: ASAN, flags: --config=asan, runner: ubuntu-22-4core }
- { name: MSAN, flags: --config=docker-msan, runner: ubuntu-22-4core, continuous-only: true }
- { name: TSAN, flags: --config=tsan, runner: ubuntu-22-4core, continuous-only: true }
- { name: UBSAN, flags: --config=ubsan, runner: ubuntu-22-4core, continuous-only: true,}
- { name: No-RTTI, flags: --cxxopt=-fno-rtti, continuous-only: true }
include:
# Set defaults
- image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize@sha256:04cd765285bc52cbbf51d66c8c66d8603579cf0f19cc42df26b09d2c270541fb
- targets: //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/...
- image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:6.4.0-27cf7b86212020d7e552bc13b1e084abb971da75
- targets: //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/... //conformance:conformance_framework_tests
# Override cases with custom images
- config: { name: "Bazel7" }
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.1-75f2a85ece6526cc3d54087018c0f1097d78d42b"
- config: { name: "Bazel7", flags: --noenable_bzlmod }
cache_key: Bazel7
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.2-cf84e92285ca133b9c8104ad7b14d70e953cbb8e"
targets: "//src/... //third_party/utf8_range/..."
# TODO: remove -Wno-unreachable-code" when dropping C++14
- config: { name: "Bazel7 with Bzlmod", flags: --enable_bzlmod --enable_workspace --per_file_copt=.*/absl/strings/string_view.h@-Wno-unreachable-code --cxxopt="-Wno-self-assign-overloaded" }
cache_key: Bazel7bzlmod
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.2-cf84e92285ca133b9c8104ad7b14d70e953cbb8e"
targets: "//src/... //third_party/utf8_range/..."
- config: { name: "TCMalloc" }
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc@sha256:bd39119d74b8a3fad4ae335d4cf5294e70384676331b7e19949459fc7a8d8328"
cache_key: TcMalloc
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc:6.4.0-27cf7b86212020d7e552bc13b1e084abb971da75"
targets: "//src/... //third_party/utf8_range/..."
- config: { name: "aarch64" }
cache_key: TcMalloc
targets: "//src/... //src/google/protobuf/compiler:protoc_aarch64_test //third_party/utf8_range/..."
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:aarch64-63dd26c0c7a808d92673a3e52e848189d4ab0f17"
name: Linux ${{ matrix.config.name }}
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:6.4.0-aarch64-08714ed7a713068c8418003a2d95f423d4b1eac9"
name: ${{ matrix.config.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.config.name }}
runs-on: ${{ matrix.config.runner || 'ubuntu-latest' }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: ${{ matrix.image }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: cpp_linux/${{ matrix.config.name }}
bazel-cache: cpp_linux/${{ matrix.cache_key }}
bazel: test ${{ matrix.targets }} ${{ matrix.config.flags }}
exclude-targets: ${{ matrix.exclude-targets }}
linux-gcc:
strategy:
@ -69,10 +91,10 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:${{ matrix.version }}-6.3.0-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:6.4.0-${{ matrix.version }}-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: cpp_linux/gcc-${{ matrix.version }}
bazel: test //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/...
bazel: test //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/... //conformance:conformance_framework_tests
linux-release:
strategy:
@ -80,18 +102,17 @@ jobs:
matrix:
arch: [x86_64, aarch64]
name: Linux Release ${{ matrix.arch}}
runs-on: ubuntu-latest
runs-on: ubuntu-20-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Cross compile protoc for ${{ matrix.arch }}
id: cross-compile
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-${{ matrix.arch }}
- name: Setup sccache
@ -102,14 +123,14 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:${{ matrix.arch }}-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:6.4.0-${{ matrix.arch }}-08714ed7a713068c8418003a2d95f423d4b1eac9
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
entrypoint: bash
command: >
-c "set -ex;
sccache -z;
cmake . -DWITH_PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }}
-Dprotobuf_BUILD_LIBUPB=OFF -Dprotobuf_BUILD_CONFORMANCE=ON -DCMAKE_CXX_STANDARD=14
-Dprotobuf_BUILD_LIBUPB=OFF -Dprotobuf_BUILD_CONFORMANCE=ON -DCMAKE_CXX_STANDARD=17
-Dprotobuf_WITH_ZLIB=OFF ${{ env.SCCACHE_CMAKE_FLAGS }};
cmake --build . --parallel 20;
ctest --parallel 20;
@ -120,101 +141,125 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
include:
- flags: -Dprotobuf_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=14
- flags: -Dprotobuf_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=17
- name: Ninja
flags: -G Ninja -DCMAKE_CXX_STANDARD=14
flags: -G Ninja -DCMAKE_CXX_STANDARD=17
continuous-only: true
- name: Shared
flags: -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=14
- name: C++17
flags: -DCMAKE_CXX_STANDARD=17
# TODO Re-enable this.
#- name: C++20
# flags: -DCMAKE_CXX_STANDARD=20
flags: -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=17
continuous-only: true
- name: C++20
flags: -DCMAKE_CXX_STANDARD=20
- name: Package
flags: -DCMAKE_CXX_STANDARD=17 -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON
- name: Fetch
flags: -DCMAKE_CXX_STANDARD=17 -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON
name: Linux CMake ${{ matrix.name}}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux CMake ${{ matrix.name}}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Setup sccache
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/sccache@v3
with:
cache-prefix: linux-cmake
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.13.3-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.16.9-d9624f2aa83cba3eaf906f751d75b36aacb9aa82
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/test.sh ${{ matrix.flags}} ${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_BUILD_TESTS=ON -Dprotobuf_USE_EXTERNAL_GTEST=ON
-Dprotobuf_ABSL_PROVIDER=package
-Dprotobuf_BUILD_TESTS=ON ${{ matrix.package_flags }}
linux-cmake-install:
name: Linux CMake Install
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
type: [package, fetch]
include:
# Set defaults
- type: package
name: Install
flags: -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON
- type: fetch
name: Install (Fetch)
flags: -Dprotobuf_FORCE_FETCH_DEPENDENCIES=ON
continuous-only: true
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }}Linux CMake ${{ matrix.name }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Setup sccache
uses: protocolbuffers/protobuf-ci/sccache@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
cache-prefix: linux-cmake-install
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- name: Run tests
uses: protocolbuffers/protobuf-ci/docker@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.13.3-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.16.9-d9624f2aa83cba3eaf906f751d75b36aacb9aa82
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/install.sh -DCMAKE_CXX_STANDARD=14 ${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_USE_EXTERNAL_GTEST=ON -Dprotobuf_ABSL_PROVIDER=package
/install.sh -DCMAKE_CXX_STANDARD=17 ${{ env.SCCACHE_CMAKE_FLAGS }}
${{ matrix.flags }}
-Dprotobuf_BUILD_SHARED_LIBS=ON \&\&
/test.sh
${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_REMOVE_INSTALLED_HEADERS=ON
-Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF
-Dprotobuf_BUILD_CONFORMANCE=ON
-DCMAKE_CXX_STANDARD=14
-Dprotobuf_USE_EXTERNAL_GTEST=ON -Dprotobuf_ABSL_PROVIDER=package
-DCMAKE_CXX_STANDARD=17
${{ matrix.flags }}
# This test should always be skipped on presubmit
linux-cmake-examples:
name: Linux CMake Examples
name: ${{ inputs.continuous-prefix }} Linux CMake Examples
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Setup sccache
if: ${{ inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/sccache@v3
with:
cache-prefix: linux-cmake-examples
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- name: Run tests
if: ${{ inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.13.3-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.16.9-d9624f2aa83cba3eaf906f751d75b36aacb9aa82
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/install.sh -DCMAKE_CXX_STANDARD=14 ${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_USE_EXTERNAL_GTEST=ON -Dprotobuf_ABSL_PROVIDER=package
/install.sh -DCMAKE_CXX_STANDARD=17 ${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_LOCAL_DEPENDENCIES_ONLY=OFF
-Dprotobuf_BUILD_EXAMPLES=OFF \&\&
mkdir examples/build \&\&
cd examples/build \&\&
cmake .. -DCMAKE_CXX_STANDARD=14 \&\&
cmake .. -DCMAKE_CXX_STANDARD=17 \&\&
cmake --build .
linux-cmake-gcc:
@ -222,32 +267,33 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
include:
- name: C++14
flags: -DCMAKE_CXX_STANDARD=14
- name: C++17
flags: -DCMAKE_CXX_STANDARD=17
continuous-only: true
- name: C++20
flags: -DCMAKE_CXX_STANDARD=20
name: Linux CMake GCC ${{ matrix.name }}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux CMake GCC ${{ matrix.name }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Setup sccache
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/sccache@v3
with:
cache-prefix: linux-cmake-gcc
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:12.2-6.3.0-63dd26c0c7a808d92673a3e52e848189d4ab0f17
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:6.4.0-12.2-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
entrypoint: bash
command: >-
@ -259,31 +305,6 @@ jobs:
ctest --verbose --parallel 20;
sccache -s'
linux-cmake-submodules:
name: Linux CMake Submodules
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Setup sccache
uses: protocolbuffers/protobuf-ci/sccache@v3
with:
cache-prefix: linux-cmake-submodules
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
- name: Run tests
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/cmake:3.13.3-63dd26c0c7a808d92673a3e52e848189d4ab0f17
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/test.sh ${{ env.SCCACHE_CMAKE_FLAGS }}
-Dprotobuf_BUILD_CONFORMANCE=ON -Dprotobuf_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=14
linux-cmake-32-bit:
name: Linux CMake 32-bit
runs-on: ubuntu-latest
@ -292,7 +313,6 @@ jobs:
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Setup sccache
uses: protocolbuffers/protobuf-ci/sccache@v3
@ -303,14 +323,14 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:8275360dc5d676f3470872d79087901c0e4153453976bea908a92c82e8d209ea
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:d6028ab408c49932836cdc514116f06886d7f6868a4d430630aa52adc5aee2fc
platform: linux/386
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/bin/bash -cex '
cd /workspace;
sccache -z;
cmake . -DCMAKE_CXX_STANDARD=14 ${{ env.SCCACHE_CMAKE_FLAGS }};
cmake . -DCMAKE_CXX_STANDARD=17 ${{ env.SCCACHE_CMAKE_FLAGS }};
cmake --build . --parallel 20;
ctest --verbose --parallel 20;
sccache -s'
@ -321,54 +341,57 @@ jobs:
matrix:
include:
- name: MacOS Bazel
os: macos-12
cache_key: macos-12
bazel: test //src/... //third_party/utf8_range/...
os: macos-13
cache_key: macos-13
bazel: test //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests
- name: MacOS Bazel 7
os: macos-12
cache_key: macos-12-bazel7
bazel: test //src/... //third_party/utf8_range/...
bazel_version: '7.1.1'
os: macos-13
cache_key: macos-13-bazel7
bazel: test //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests
bazel_version: '7.1.2'
continuous-only: true
- name: MacOS Apple Silicon (build only) Bazel
os: macos-12
cache_key: macos-12-arm
os: macos-13
cache_key: macos-13-arm
# Current github runners are all Intel based, so just build/compile
# for Apple Silicon to detect issues there.
bazel: build --cpu=darwin_arm64 //src/... //third_party/utf8_range/...
bazel: build --cpu=darwin_arm64 //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests
- name: Windows Bazel
os: windows-2022
cache_key: windows-2022
bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance
- name: Windows Bazel 7
- name: Windows Bazel 7
os: windows-2022
cache_key: windows-2022-bazel7
bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance
bazel_version: '7.1.1'
name: ${{ matrix.name }}
bazel_version: '7.1.2'
continuous-only: true
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} ${{ matrix.name }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel: ${{ matrix.bazel }}
bazel-cache: cpp_${{ matrix.cache_key }}
version: ${{ matrix.bazel_version || '6.3.0' }}
version: ${{ matrix.bazel_version || '6.4.0' }}
non-linux-cmake:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
include:
# TODO: investigate and fix
# - name: MacOS CMake
# os: macos-12
# flags: -DCMAKE_CXX_STANDARD=14
# cache-prefix: macos-cmake
- name: MacOS CMake
os: macos-13
cache-prefix: macos-cmake
continuous-only: true
- name: Windows CMake
os: windows-2022
flags: >-
@ -387,6 +410,7 @@ jobs:
cache-prefix: windows-2019-cmake
# windows-2019 has python3.7 installed, which is incompatible with the latest gcloud
python-version: '3.9'
continuous-only: true
- name: Windows CMake 32-bit
os: windows-2022
flags: >-
@ -394,6 +418,7 @@ jobs:
vsversion: '2022'
windows-arch: 'win32'
cache-prefix: windows-2022-win32-cmake
continuous-only: true
- name: Windows CMake Shared
os: windows-2022
flags: >-
@ -403,24 +428,26 @@ jobs:
cache-prefix: windows-2022-cmake
- name: Windows CMake Install
os: windows-2022
install-flags: -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_TESTS=OFF
install-flags: >-
-G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF
flags: >-
-G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF
-Dprotobuf_REMOVE_INSTALLED_HEADERS=ON
-Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF
vsversion: '2022'
cache-prefix: windows-2022-cmake
name: ${{ matrix.name }}
continuous-only: true
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} ${{ matrix.name }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
submodules: recursive
- name: Setup MSVC
if: ${{ runner.os == 'Windows' }}
if: ${{ runner.os == 'Windows' && (!matrix.continuous-only || inputs.continuous-run) }}
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
with:
arch: ${{ matrix.windows-arch || 'x64' }}
@ -428,16 +455,17 @@ jobs:
# Workaround for incompatibility between gcloud and windows-2019 runners.
- name: Install Python
if: ${{ matrix.python-version }}
if: ${{ matrix.python-version && (!matrix.continuous-only || inputs.continuous-run) }}
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
with:
python-version: ${{ matrix.python-version }}
- name: Use custom python for gcloud
if: ${{ matrix.python-version }}
if: ${{ matrix.python-version && (!matrix.continuous-only || inputs.continuous-run) }}
run: echo "CLOUDSDK_PYTHON=${Python3_ROOT_DIR}\\python3" >> $GITHUB_ENV
shell: bash
- name: Setup sccache
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/sccache@v3
with:
cache-prefix: ${{ matrix.cache-prefix }}
@ -445,42 +473,50 @@ jobs:
# Install phase.
- name: Configure CMake for install
if: matrix.install-flags
if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }}
uses: protocolbuffers/protobuf-ci/bash@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: cmake . ${{ matrix.install-flags }} ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_ALLOW_CCACHE=ON
command: >-
cmake . -DCMAKE_CXX_STANDARD=17 ${{ matrix.install-flags }}
${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_ALLOW_CCACHE=ON
- name: Build for install
if: matrix.install-flags
if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }}
shell: bash
run: VERBOSE=1 cmake --build . --parallel 20
- name: Install
if: matrix.install-flags
if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }}
shell: bash
run: cmake --build . --target install
- name: Report and clear sccache stats
if: matrix.install-flags
if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }}
shell: bash
run: sccache -s && sccache -z
- name: Clear CMake cache
if: matrix.install-flags
if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }}
shell: bash
run: cmake --build . --target clean && rm CMakeCache.txt
- name: Configure CMake
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bash@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: cmake . ${{ matrix.flags }} ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_ALLOW_CCACHE=ON
command: >-
cmake . -DCMAKE_CXX_STANDARD=17 ${{ matrix.flags }}
${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_ALLOW_CCACHE=ON
- name: Build
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
shell: bash
run: VERBOSE=1 cmake --build . --parallel 20
- name: Test
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
shell: bash
run: ctest --verbose --parallel 20 -C Debug
- name: Report sccache stats
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
shell: bash
run: sccache -s

@ -12,9 +12,11 @@ permissions:
contents: read
jobs:
# All C# jobs are currently run on presubmit
# If you wish to add continuous-only jobs you will need to import test-type above
linux:
name: Linux
runs-on: ubuntu-latest
runs-on: ubuntu-22-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -25,7 +27,7 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:3.1.415-6.0.100-66964dc8b07b6d1fc73a5cc14e59e84c1c534cea
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:6.4.0-3.1.415-6.0.100-08714ed7a713068c8418003a2d95f423d4b1eac9
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
entrypoint: /bin/bash
command: >-
@ -36,12 +38,12 @@ jobs:
dotnet test -c Release -f net6.0 src/Google.Protobuf.Test/Google.Protobuf.Test.csproj"
- name: Clear bazel between docker instances
run: sudo rm -rf _build
run: sudo rm -rf _build .repository-cache
- name: Run conformance tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:3.1.415-6.0.100-66964dc8b07b6d1fc73a5cc14e59e84c1c534cea
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:6.4.0-3.1.415-6.0.100-08714ed7a713068c8418003a2d95f423d4b1eac9
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: csharp_linux
bazel: test //csharp:conformance_test --action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_HOME=/home/bazel

@ -3,10 +3,21 @@ name: Java Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -18,38 +29,51 @@ jobs:
matrix:
include:
- name: OpenJDK 8
version: '8'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
cache_key: '8'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:6.4.0-8-27cf7b86212020d7e552bc13b1e084abb971da75
# TODO: b/318555165 - enable the layering check. Currently it does
# not work correctly with the toolchain in this Docker image.
targets: //java/... //java/internal:java_version --features=-layering_check
targets: //java/... //java/internal:java_version //compatibility/... --features=-layering_check
- name: OpenJDK 11
version: '11'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:11-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
targets: //java/... //java/internal:java_version
cache_key: '11'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:6.4.0-11-27cf7b86212020d7e552bc13b1e084abb971da75
targets: //java/... //java/internal:java_version //compatibility/...
continuous-only: true
- name: OpenJDK 17
version: '17'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:17-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
targets: //java/... //java/internal:java_version
cache_key: '17'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:6.4.0-17-27cf7b86212020d7e552bc13b1e084abb971da75
targets: //java/... //java/internal:java_version //compatibility/...
- name: Bazel7
cache_key: 'bazel7nobzlmod'
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.2-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
targets: //java/... //java/internal:java_version //compatibility/...
flags: --noenable_bzlmod
- name: Bazel7 with Bzlmod
cache_key: 'bazel7bzlmod'
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.2-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
targets: //java/... //java/internal:java_version //compatibility/...
flags: --enable_bzlmod --enable_workspace
- name: aarch64
version: 'aarch64'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:aarch64-63dd26c0c7a808d92673a3e52e848189d4ab0f17
targets: //java/... //src/google/protobuf/compiler:protoc_aarch64_test
cache_key: 'aarch64'
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:6.4.0-aarch64-08714ed7a713068c8418003a2d95f423d4b1eac9
targets: //java/... //compatibility/... //src/google/protobuf/compiler:protoc_aarch64_test
name: Linux ${{ matrix.name }}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.name }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
image: ${{ matrix.image }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: java_linux/${{ matrix.version }}
bazel: test ${{ matrix.targets }} --test_env=KOKORO_JAVA_VERSION
bazel-cache: java_linux/${{ matrix.cache_key }}
bazel: test ${{ matrix.targets }} ${{ matrix.flags }} --test_env=KOKORO_JAVA_VERSION
# TODO restore this test (or a better one) when gRPC has rebuilt with 26.x
# linkage-monitor:
@ -69,52 +93,31 @@ jobs:
# # TODO: b/318555165 - enable the layering check. Currently it does
# # not work correctly with the toolchain in this Docker image.
# bazel: test --test_output=all //java:linkage_monitor --spawn_strategy=standalone --features=-layering_check
protobuf-bom:
name: Protobuf Maven BOM
runs-on: ubuntu-latest
runs-on: ubuntu-22-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Build protoc
id: build-protoc
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-x86_64
- name: Move protoc into place and clean up
run: |
mv ${{ steps.build-protoc.outputs.protoc }} protoc
sudo rm -rf _build
- name: Install snapshot version locally (not using generated pom.xml)
run: |
mvn -e -B -Dhttps.protocols=TLSv1.2 install -Dmaven.test.skip=true
working-directory: java
- name: Generate pom.xml files from the template
- name: Generate maven artifacts with bazel and install using maven
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:11-1fdbb997433cb22c1e49ef75ad374a8d6bb88702
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:6.4.0-11-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: java_linux/11
# protobuf-java and protobuf-java-util are the member of the BOM
bash: |
bazel build //java/core:core_mvn-pom //java/util:util_mvn-pom
cp bazel-bin/java/core/core_mvn-pom.xml .
cp bazel-bin/java/util/util_mvn-pom.xml .
- name: Copy the generated pom.xml files to the local Maven repository
shell: bash
run: |
LOCAL_MAVEN_GROUP_DIR="${HOME}/.m2/repository/com/google/protobuf"
VERSION=$(grep "<version>" core_mvn-pom.xml | sed "s/<version>\(.*\)<\/version>/\1/" | xargs)
cp core_mvn-pom.xml ${LOCAL_MAVEN_GROUP_DIR}/protobuf-java/${VERSION}/protobuf-java-${VERSION}.pom
cp util_mvn-pom.xml ${LOCAL_MAVEN_GROUP_DIR}/protobuf-java-util/${VERSION}/protobuf-java-util-${VERSION}.pom
set -ex
bazel build //java:release $BAZEL_FLAGS
mvn install:install-file -Dfile=java/bom/pom.xml -DpomFile=java/bom/pom.xml
mvn install:install-file -Dfile=java/pom.xml -DpomFile=java/pom.xml
mvn install:install-file -Dfile=bazel-bin/java/core/core_mvn-project.jar -DpomFile=bazel-bin/java/core/core_mvn-pom.xml
mvn install:install-file -Dfile=bazel-bin/java/core/lite_mvn-project.jar -DpomFile=bazel-bin/java/core/lite_mvn-pom.xml
mvn install:install-file -Dfile=bazel-bin/java/kotlin-lite/kotlin-lite_mvn-project.jar -DpomFile=bazel-bin/java/kotlin-lite/kotlin-lite_mvn-pom.xml
mvn install:install-file -Dfile=bazel-bin/java/kotlin/kotlin_mvn-project.jar -DpomFile=bazel-bin/java/kotlin/kotlin_mvn-pom.xml
mvn install:install-file -Dfile=bazel-bin/java/util/util_mvn-project.jar -DpomFile=bazel-bin/java/util/util_mvn-pom.xml
- name: Clean up
run: |
sudo rm -rf _build
- name: Validate Protobuf BOM
uses: googleapis/java-cloud-bom/tests/validate-bom@fd56f04bb0bc581776a74031591f0b3bc5e7920a # v26.13.0
with:
bom-path: java/bom/pom.xml

@ -3,10 +3,21 @@ name: Objective-C Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -25,26 +36,33 @@ jobs:
destination: "platform=macOS"
xc_project: "ProtocolBuffers_OSX.xcodeproj"
- platform: "iOS"
destination: "platform=iOS Simulator,name=iPhone 13,OS=latest"
destination: "platform=iOS Simulator,name=iPhone 14,OS=latest"
xc_project: "ProtocolBuffers_iOS.xcodeproj"
# We run presubmits on all "Debug" entries, but not on "Release" entries
- xc_config: "Debug"
- xc_config: "Release"
continuous-only: true
name: Xcode ${{ matrix.platform}} ${{ matrix.xc_config }}
runs-on: macos-12
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Xcode ${{ matrix.platform}} ${{ matrix.xc_config }}
runs-on: macos-13
env:
DEVELOPER_DIR: /Applications/Xcode_14.1.app/Contents/Developer
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Setup ccache
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/ccache@v3
with:
cache-prefix: objectivec_${{ matrix.platform }}_${{ matrix.xc_config }}
support-modules: true
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bash@v3
env:
CC: ${{ github.workspace }}/ci/clang_wrapper
@ -57,10 +75,10 @@ jobs:
-scheme ProtocolBuffers \
-configuration ${{ matrix.xc_config }} \
-destination "${{ matrix.destination }}" \
test \
| xcpretty
test
- name: Report ccache stats
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
shell: bash
run: ccache -s -v
@ -68,24 +86,29 @@ jobs:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
PLATFORM: ["ios", "macos", "tvos", "watchos", "visionos"]
# Disabling visionOS for now: https://github.com/actions/runner-images/issues/10559
PLATFORM: ["ios", "macos", "tvos", "watchos"]
CONFIGURATION: ["Debug", "Release"]
include:
- OS: macos-12
- OS: macos-13
XCODE: "14.1"
- OS: macos-14
PLATFORM: "visionos"
XCODE: "15.2"
name: CocoaPods ${{ matrix.PLATFORM }} ${{ matrix.CONFIGURATION }}
# We run presubmits on all "Debug" entries, but not on "Release" entries
- CONFIGURATION: "Debug"
- CONFIGURATION: "Release"
continuous-only: true
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} CocoaPods ${{ matrix.PLATFORM }} ${{ matrix.CONFIGURATION }}
runs-on: ${{ matrix.OS }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Xcode version
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: sudo xcode-select -switch /Applications/Xcode_${{ matrix.XCODE }}.app
- name: Pod lib lint
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
@ -105,6 +128,7 @@ jobs:
- name: Optimized
flags: --config=opt
bazel_action: test
continuous-only: true
- name: Debug
flags: --config=dbg
bazel_action: test
@ -113,6 +137,7 @@ jobs:
- name: Apple_Silicon_Optimized
flags: --config=opt --cpu=darwin_arm64
bazel_action: build
continuous-only: true
- name: Apple_Silicon_Debug
flags: --config=dbg --cpu=darwin_arm64
bazel_action: build
@ -121,14 +146,16 @@ jobs:
include:
- platform: "macOS"
bazel_targets: //objectivec/...
name: Bazel ${{ matrix.platform }} ${{ matrix.config.name }}
runs-on: macos-12
name: ${{ matrix.config.continuous-only && inputs.continuous-prefix || '' }} Bazel ${{ matrix.platform }} ${{ matrix.config.name }}
runs-on: macos-13
steps:
- name: Checkout pending changes
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: bazel ${{ matrix.config.bazel_action }}
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}

@ -4,10 +4,21 @@ name: PHP Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -26,40 +37,55 @@ jobs:
version: 8.1.14-dbg
version-short: "8.1"
command: composer test \&\& composer test_c
continuous-only: true
- name: 8.1 Memory Leak
version: 8.1.14-dbg
version-short: "8.1"
# Run specialized memory leak & multirequest tests.
command: composer test_c \&\& tests/multirequest.sh \&\& tests/memory_leak_test.sh
continuous-only: true
- name: 8.1 Valgrind
version: 8.1.14-dbg
version-short: "8.1"
command: composer test_valgrind
continuous-only: true
- name: 8.3 Optimized
version: "8.3.1"
version-short: "8.3"
command: composer test \&\& composer test_c
name: Linux ${{ matrix.name}}
runs-on: ubuntu-latest
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.name}}
runs-on: ubuntu-22-4core
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Setup composer
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/composer-setup@v3
with:
cache-prefix: php-${{ matrix.version-short }}
directory: php
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php:${{ matrix.version }}-66964dc8b07b6d1fc73a5cc14e59e84c1c534cea
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php:6.4.0-${{ matrix.version }}-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
extra-flags: -e COMPOSER_HOME=/workspace/composer-cache
command: ${{ matrix.command }}
- name: Run conformance tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php:6.4.0-${{ matrix.version }}-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: php_linux/${{ matrix.version }}
bazel: test //php:conformance_test //php:conformance_test_c --action_env=PATH --test_env=PATH
linux-32bit:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
@ -73,34 +99,42 @@ jobs:
include:
- suffix: '-zts'
suffix_name: ' Thread Safe'
continuous-only: true
- test: 'test_c'
test_name: ' Extension'
continuous-only: true
- suffix: ''
test: 'test'
name: Linux 32-bit ${{ matrix.version}}${{ matrix.suffix_name }}${{ matrix.test_name }}
runs-on: ubuntu-latest
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux 32-bit ${{ matrix.version}}${{ matrix.suffix_name }}${{ matrix.test_name }}
runs-on: ubuntu-22-4core
env:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:836f2cedcfe351d9a30055076630408e61994fc7d783e8333a99570968990eeb
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/32bit@sha256:429f924aec315704b4233adcbe4b29006116f27769db98acd176b9eb69c31299
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Cross compile protoc for i386
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
id: cross-compile
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-i386
- name: Setup composer
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/composer-setup@v3
with:
cache-prefix: php-${{ matrix.version }}
directory: php
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: ${{ env.image }}
@ -116,7 +150,7 @@ jobs:
linux-aarch64:
name: Linux aarch64
runs-on: ubuntu-latest
runs-on: ubuntu-22-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -127,7 +161,7 @@ jobs:
id: cross-compile
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-aarch64
@ -151,41 +185,57 @@ jobs:
composer test;
composer test_c'
- name: Run conformance tests
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: php_linux/${{ matrix.version }}
bazel: test //php:conformance_test //php:conformance_test_c --action_env=PATH --test_env=PATH
macos:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
version: ['8.2', '8.3']
include:
- version: '8.3'
name: MacOS PHP ${{ matrix.version }}
runs-on: macos-12
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} MacOS PHP ${{ matrix.version }}
# noop
runs-on: macos-13
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Uninstall problematic libgd
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: brew uninstall --ignore-dependencies gd
- name: Install dependencies
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: brew install coreutils gd
- name: Pin PHP version
uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # 2.30.2
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # 2.31.1
with:
php-version: ${{ matrix.version }}
- name: Check PHP version
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: php --version | grep ${{ matrix.version }} || (echo "Invalid PHP version - $(php --version)" && exit 1)
- name: Setup composer
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/composer-setup@v3
with:
cache-prefix: php-${{ matrix.version }}
directory: php
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bash@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
@ -198,8 +248,9 @@ jobs:
popd
- name: Run conformance tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: php_macos/${{ matrix.version }}
bazel: test //php:conformance_test_c --action_env=PATH --test_env=PATH
bazel: test //php:conformance_test //php:conformance_test_c --action_env=PATH --test_env=PATH

@ -3,10 +3,21 @@ name: PHP Extension Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read # to fetch code (actions/checkout)
@ -31,7 +42,7 @@ jobs:
bazel build //php:release $BAZEL_FLAGS;
cp bazel-bin/php/protobuf-*.tgz .
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: protobuf-php-release
path: protobuf-*.tgz
@ -41,15 +52,22 @@ jobs:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
version: ["8.1", "8.2", "8.3"]
name: Build ${{ matrix.version }}
include:
- version: "8.1"
continuous-only: true
- version: "8.2"
continuous-only: true
- version: "8.3"
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Build ${{ matrix.version }}
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #4.1.8
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
name: protobuf-php-release
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php-extension:${{ matrix.version }}-a48f26c08d9a803dd0177dda63563f6ea6f7b2d4

@ -3,10 +3,21 @@ name: Python Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -17,8 +28,7 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
type: [ Pure, C++]
# TODO: b/309627662 - Add coverage for Python 3.12.
version: ["3.8", "3.9", "3.10", "3.11"]
version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
include:
- type: Pure
targets: //python/... //python:python_version_test
@ -32,18 +42,28 @@ jobs:
# TODO Enable this once conformance tests are fixed.
flags: --define=use_fast_cpp_protos=true --test_tag_filters=-conformance
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:aarch64-63dd26c0c7a808d92673a3e52e848189d4ab0f17
- version: "3.9"
- version: "3.10"
continuous-only: true
- version: "3.11"
continuous-only: true
- version: "3.12"
continuous-only: true
- version: "3.13"
name: Linux ${{ matrix.type }} ${{ matrix.version }}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.type }} ${{ matrix.version }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/python:{0}-63dd26c0c7a808d92673a3e52e848189d4ab0f17', matrix.version) }}
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/python:7.1.2-{0}-d9624f2aa83cba3eaf906f751d75b36aacb9aa82', matrix.version) }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: python_linux/${{ matrix.type }}_${{ matrix.version }}
bazel: test ${{ matrix.targets }} ${{ matrix.flags }} --test_env=KOKORO_PYTHON_VERSION
@ -55,17 +75,18 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
type: [ Pure, C++]
# TODO Consider expanding this set of versions.
version: [ "3.12" ]
version: [ "3.12", "3.13" ]
include:
- type: Pure
targets: //python/... //python:python_version_test
- type: C++
targets: //python/... //python:python_version_test
flags: --define=use_fast_cpp_protos=true
- version: "3.13"
continuous-only: true
name: MacOS ${{ matrix.type }} ${{ matrix.version }}
runs-on: macos-12
runs-on: macos-13
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -73,7 +94,7 @@ jobs:
ref: ${{ inputs.safe-checkout }}
- name: Pin Python version
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f #v5.1.1
with:
python-version: ${{ matrix.version }}
cache: pip
@ -97,5 +118,5 @@ jobs:
bazel: >-
test ${{ matrix.targets }} ${{ matrix.flags }}
--test_env=KOKORO_PYTHON_VERSION=${{ matrix.version }}
--macos_minimum_os=10.9
--macos_minimum_os=11.0
exclude-targets: -//python/pb_unit_tests/...

@ -0,0 +1,25 @@
name: Release Branch Tests
on:
schedule:
# Run daily at 10 AM UTC (2 AM PDT)
- cron: 0 10 * * *
workflow_dispatch:
permissions: {}
jobs:
releases:
strategy:
fail-fast: false
matrix:
branch: [25.x, 28.x, 29.x]
runs-on: ubuntu-latest
permissions:
actions: write
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
name: Run Tests on ${{ matrix.branch }}
steps:
- run: gh workflow run test_runner.yml --ref ${{ matrix.branch }}

@ -3,10 +3,21 @@ name: Ruby Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -20,34 +31,42 @@ jobs:
# Test both FFI and Native implementations on the highest and lowest
# Ruby versions for CRuby and JRuby, but only on Bazel 5.x.
- { name: Ruby 3.0, ruby: ruby-3.0.2, ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { name: Ruby 3.0, ruby: ruby-3.0.2, ffi: FFI }
- { name: Ruby 3.1, ruby: ruby-3.1.0 }
- { name: Ruby 3.2, ruby: ruby-3.2.0 }
- { name: Ruby 3.0, ruby: ruby-3.0.2, ffi: FFI, continuous-only: true }
- { name: Ruby 3.1, ruby: ruby-3.1.0, continuous-only: true }
- { name: Ruby 3.2, ruby: ruby-3.2.0, continuous-only: true }
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: FFI }
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: FFI }
- { name: JRuby 9.4, ruby: jruby-9.4.6.0, ffi: NATIVE }
- { name: JRuby 9.4, ruby: jruby-9.4.6.0, ffi: FFI }
name: Linux ${{ matrix.name }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.name }} ${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:{0}-6.3.0-a6940b1421a71325ef4c7828ec72d404f56bbf30', matrix.ruby) }}
image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:6.4.0-{0}-27cf7b86212020d7e552bc13b1e084abb971da75', matrix.ruby) }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: ruby_linux/${{ matrix.ruby }}_${{ matrix.bazel }}
bazel: test //ruby/... //ruby/tests:ruby_version --test_env=KOKORO_RUBY_VERSION --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }}
# Useful tool for troubleshooting, but the action introduces flakes as well,
# e.g. https://github.com/actions/upload-artifact/issues/569
# - name: Archive log artifacts
# if: ${{ matrix.presubmit || inputs.test-type == 'continuous' }}
# uses: actions/upload-artifact@v4
# with:
# name: test-logs-${{ matrix.ruby }}_${{ matrix.ffi || 'NATIVE' }}
# path: logs
linux-32bit:
name: Linux 32-bit
runs-on: ubuntu-latest
runs-on: ubuntu-20-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -58,7 +77,7 @@ jobs:
id: cross-compile
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-i386
@ -69,7 +88,7 @@ jobs:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/bin/bash -cex '
gem install bundler -v 2.5.6;
gem install bundler -v 2.5.13;
cd /workspace/ruby;
bundle;
PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake;
@ -78,7 +97,7 @@ jobs:
linux-aarch64:
name: Linux aarch64
runs-on: ubuntu-latest
runs-on: ubuntu-20-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -89,7 +108,7 @@ jobs:
id: cross-compile
uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
architecture: linux-aarch64
@ -100,7 +119,7 @@ jobs:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
command: >-
/bin/bash -cex '
gem install bundler -v 2.5.6;
gem install bundler -v 2.5.13;
cd /workspace/ruby;
bundle;
PROTOC=/workspace/${{ steps.cross-compile.outputs.protoc }} rake;
@ -116,37 +135,40 @@ jobs:
# Ruby versions for CRuby, but only on Bazel 5.x.
# Quote versions numbers otherwise 3.0 will render as 3
- { version: "3.0", ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { version: "3.0", ffi: FFI }
- { version: "3.1" }
- { version: "3.2" }
- { version: "3.0", ffi: FFI, continuous-only: true }
- { version: "3.1", continuous-only: true }
- { version: "3.2", continuous-only: true }
- { version: "3.3", ffi: NATIVE }
# TODO Re-enable these once flakes are fixed
#- { version: "3.3", ffi: FFI }
- { version: "3.3", ffi: FFI }
name: MacOS Ruby ${{ matrix.version }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
runs-on: macos-12
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} MacOS Ruby ${{ matrix.version }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
runs-on: macos-13
steps:
- name: Checkout pending changes
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Pin Ruby version
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: ruby/setup-ruby@961f85197f92e4842e3cb92a4f97bd8e010cdbaf # v1.165.0
with:
ruby-version: ${{ matrix.version }}
- name: Validate version
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: ruby --version | grep ${{ matrix.version }} || (echo "Invalid Ruby version - $(ruby --version)" && exit 1)
- name: Run tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel@v3
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: ruby_macos/${{ matrix.version }}
bazel: test //ruby/... --test_env=KOKORO_RUBY_VERSION=${{ matrix.version }} --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }}
# This test should always be skipped on presubmit
test_ruby_gems:
strategy:
fail-fast: false
@ -162,17 +184,19 @@ jobs:
- { name: Ruby 3.3, ruby: ruby-3.3.0, ffi: FFI }
- { name: JRuby 9.4, ruby: jruby-9.4.6.0, ffi: NATIVE }
- { name: JRuby 9.4, ruby: jruby-9.4.6.0, ffi: FFI }
name: Install ${{ matrix.name }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
name: ${{ inputs.continuous-prefix }} Install ${{ matrix.name }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }}
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
if: ${{ inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:${{ matrix.ruby }}-6.3.0-a6940b1421a71325ef4c7828ec72d404f56bbf30
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:6.4.0-${{ matrix.ruby }}-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: ruby_install/${{ matrix.ruby }}_${{ matrix.bazel }}
bash: >

@ -20,8 +20,6 @@ on:
branches:
- main
- '[0-9]+.x'
# The 21.x and 22.x branches still use Kokoro
- '!2[12].x'
# For testing purposes so we can stage this on the `gha` branch.
- gha
@ -30,8 +28,6 @@ on:
branches:
- main
- '[0-9]+.x'
# The 21.x and 22.x branches still use Kokoro
- '!2[12].x'
# For testing purposes so we can stage this on the `gha` branch.
- gha
@ -40,25 +36,23 @@ on:
branches:
- main
- '[0-9]+.x'
# The 21.x branch still use Kokoro
- '!21.x'
# For testing purposes so we can stage this on the `gha` branch.
- gha
types: [labeled, opened, reopened, synchronize]
# manual
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: ${{ contains(fromJSON('["pull_request", "pull_request_target", "workflow_dispatch"]'), github.event_name) }}
cancel-in-progress: ${{ contains(fromJSON('["pull_request", "pull_request_target", "workflow_dispatch", "schedule"]'), github.event_name) }}
jobs:
check-tag:
name: Check for Safety
set-vars:
name: Set Variables
# Avoid running tests twice on PR updates. If the PR is coming from our
# repository, it's safe and we can use `pull_request`. Otherwise, we should
@ -77,6 +71,15 @@ jobs:
# Store the sha for checkout so we can easily use it later. For safe
# events, this will be blank and use the defaults.
checkout-sha: ${{ steps.safe-checkout.outputs.sha }}
# Stores a string to be used as a boolean denoting whether this is a
# continuous run. An empty string denotes that the run is on presubmit,
# otherwise we are in a continuous run. This helps us determine which
# tests to block on.
continuous-run: ${{ steps.set-test-type-vars.outputs.continuous-run }}
# Stores a string that will serve as the prefix for all continuous tests.
# Either way we prepend "(Continuous)" but in the case that we are in
# a presubmit run, we should also mark them "[SKIPPED]"
continuous-prefix: ${{ steps.set-test-type-vars.outputs.continuous-prefix }}
steps:
- name: Check
# Trivially pass for safe PRs, and explicitly error for unsafe ones
@ -93,9 +96,20 @@ jobs:
${{ github.event_name != 'pull_request_target' }} ||
echo "sha=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
- name: Set Test Type Variables
id: set-test-type-vars
run: |
if ([ "${{ github.event_name }}" == 'pull_request' ] || [ "${{ github.event_name }}" == 'pull_request_target' ]) && ${{ !contains(toJson(github.event.pull_request.body), '\n#test-continuous') }}; then
echo "continuous-run=" >> "$GITHUB_OUTPUT"
echo "continuous-prefix=[SKIPPED] (Continuous)" >> "$GITHUB_OUTPUT"
else
echo "continuous-run=continuous" >> "$GITHUB_OUTPUT"
echo "continuous-prefix=(Continuous)" >> "$GITHUB_OUTPUT"
fi
remove-tag:
name: Remove safety tag
needs: [check-tag]
needs: [set-vars]
if: github.event.action == 'labeled'
runs-on: ubuntu-latest
permissions:
@ -106,103 +120,141 @@ jobs:
fail_on_error: true
labels: ':a: safe for tests'
validate-yaml:
name: Validate YAML
needs: [set-vars]
uses: ./.github/workflows/test_yaml.yml
with:
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
# Note: this pattern of passing the head sha is vulnerable to PWN requests for
# pull_request_target events. We carefully limit those workflows to require a
# human stamp before continuing.
bazel:
name: Bazel
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_bazel.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
cpp:
name: C++
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_cpp.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
java:
name: Java
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_java.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
python:
name: Python
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_python.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
ruby:
name: Ruby
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_ruby.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
php:
name: PHP
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_php.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
php-ext:
name: PHP Extension
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_php_ext.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
csharp:
name: C#
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_csharp.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
secrets: inherit
objectivec:
name: Objective-C
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_objectivec.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
rust:
name: Rust
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_rust.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
secrets: inherit
upb:
name: μpb
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/test_upb.yml
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
continuous-prefix: ${{ needs.set-vars.outputs.continuous-prefix }}
secrets: inherit
staleness:
name: Staleness
needs: [check-tag]
needs: [set-vars]
uses: ./.github/workflows/staleness_check.yml
# Staleness tests have scheduled runs during off-hours to avoid race conditions.
if: ${{ github.event_name != 'schedule' }}
with:
safe-checkout: ${{ needs.check-tag.outputs.checkout-sha }}
continuous-run: ${{ needs.set-vars.outputs.continuous-run }}
safe-checkout: ${{ needs.set-vars.outputs.checkout-sha }}
secrets: inherit
# This test depends on all blocking tests and indicates whether they all suceeded.
all-blocking-tests:
name: All Blocking Tests${{ github.event_name == 'pull_request_target' && ' (fork)' || ''}}
needs: [set-vars, validate-yaml, bazel, cpp, java, python, ruby, php, php-ext, csharp, objectivec, rust, upb, staleness]
runs-on: ubuntu-latest
steps:
- name: Check test results
run: "${{ !contains(join(needs.*.result, ' '), 'failure') && !contains(join(needs.*.result, ' '), 'cancelled') }}"
# This workflow must run even if one or more of the dependent workflows
# failed.
if: always()

@ -12,9 +12,30 @@ permissions:
contents: read
jobs:
# This job should be run on presubmit, if any continuous-only tests are added we will need to input test-type above
linux:
name: Linux
runs-on: ubuntu-latest
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
config:
- { name: "No bzlmod", flags: --noenable_bzlmod }
# TODO: b/379846319 - Fix the tests with bzlmod and enable this.
# - { name: "bzlmod", flags: --enable_bzlmod --enable_workspace }
- { name: Optimized, flags: --config=opt }
- { name: ASAN, flags: --config=asan }
include:
- targets: "//rust/... //src/google/protobuf/compiler/rust/..."
- image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.1-97f82260fd504923d8af642d567afb2d83a1959d"
- bazel_cmd: "test"
# Override cases with custom images
- config: { name: Cargo }
image: "us-docker.pkg.dev/protobuf-build/containers/release/linux/rust:6.3.0-1.74.0-8858126dd9480abf91e6ce8d6e41a5cd3c03882c"
bazel_cmd: "run"
targets: "//rust:cargo_test"
name: Linux ${{ matrix.config.name }}
runs-on: ubuntu-22-4core
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
@ -23,10 +44,10 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:7.1.1-97f82260fd504923d8af642d567afb2d83a1959d"
image: ${{ matrix.image }}
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: rust_linux
bazel: >-
test //rust:protobuf_upb_test //rust:protobuf_cpp_test
//rust/test/rust_proto_library_unit_test:rust_upb_aspect_test
//src/google/protobuf/compiler/rust/...
${{ matrix.bazel_cmd }} --crosstool_top=//toolchain:clang_suite --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 --@rules_rust//rust/settings:experimental_use_cc_common_link=True
${{ matrix.targets }} ${{ matrix.config.flags }}

@ -3,10 +3,21 @@ name: μpb Tests
on:
workflow_call:
inputs:
continuous-run:
required: true
description: "Boolean string denoting whether this run is continuous --
empty string for presubmit, non-empty string for continuous."
type: string
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
continuous-prefix:
required: true
description: "The string continuous-only tests should be prefixed with when displaying test
results."
type: string
permissions:
contents: read
@ -17,30 +28,32 @@ jobs:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
config:
- { name: "Bazel 7", bazel_version: "7.1.1" }
- { name: "Bazel 7", bazel_version: "7.1.1", continuous-only: true }
- { name: "Fastbuild" }
- { name: "Optimized", flags: "-c opt" }
- { name: "ASAN", flags: "--config=asan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/...", runner: ubuntu-20-large }
- { name: "UBSAN", flags: "--config=ubsan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/... -//lua/..." }
- { name: "Optimized", flags: "-c opt", continuous-only: true }
- { name: "ASAN", flags: "--config=asan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/...", runner: ubuntu-22-4core }
- { name: "UBSAN", flags: "--config=ubsan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/... -//lua/...", continuous-only: true }
- { name: "32-bit", flags: "--copt=-m32 --linkopt=-m32", exclude-targets: "-//benchmarks:benchmark -//python/..." }
# TODO: Add 32-bit ASAN test
# TODO: Restore the FastTable tests
name: ${{ matrix.config.name }}
name: ${{ matrix.config.continuous-only && inputs.continuous-prefix || '' }} ${{ matrix.config.name }}
runs-on: ${{ matrix.config.runner || 'ubuntu-latest' }}
steps:
- name: Checkout pending changes
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run tests
if: ${{ !matrix.config.continuous-only || inputs.continuous-run }}
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:${{ matrix.config.bazel_version || '6.3.0' }}-75f2a85ece6526cc3d54087018c0f1097d78d42b
image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:${{ matrix.config.bazel_version || '6.4.0' }}-27cf7b86212020d7e552bc13b1e084abb971da75
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: upb-bazel
bazel: test --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 //bazel/... //benchmarks/... //lua/... //protos/... //protos_generator/... //python/... //upb/... //upb_generator/... ${{ matrix.config.flags }}
bazel: test --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 //bazel/... //benchmarks/... //lua/... //python/... //upb/... //upb_generator/... ${{ matrix.config.flags }}
exclude-targets: ${{ matrix.config.exclude-targets }}
linux-gcc:
@ -56,10 +69,13 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:12.2-6.3.0-63dd26c0c7a808d92673a3e52e848189d4ab0f17"
image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:6.4.0-12.2-27cf7b86212020d7e552bc13b1e084abb971da75"
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: "upb-bazel-gcc"
bazel: test --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 -c opt //bazel/... //benchmarks/... //lua/... //protos/... //protos_generator/... //python/... //upb/... //upb_generator/...
bazel: >-
test --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 -c opt
--copt="-Wno-error=maybe-uninitialized" --copt="-Wno-error=attributes"
//bazel/... //benchmarks/... //lua/... //python/... //upb/... //upb_generator/...
windows:
strategy:
@ -71,7 +87,8 @@ jobs:
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
- name: Setup Python
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
with:
cache: pip
cache-dependency-path: 'python/requirements.txt'
@ -80,8 +97,8 @@ jobs:
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: "upb-bazel-windows"
bazel: test --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 //upb/... //upb_generator/... //python/... //protos/... //protos_generator/...
version: 6.3.0
bazel: test --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 //upb/... //upb_generator/... //python/...
version: 6.4.0
exclude-targets: -//python:conformance_test -//upb/reflection:def_builder_test
macos:
@ -92,14 +109,16 @@ jobs:
- { name: "macOS", bazel-command: "test" }
- { name: "macOS ARM (build only)", bazel-command: "build", flags: "--cpu=darwin_arm64" }
name: ${{ matrix.config.name }}
runs-on: macos-12
runs-on: macos-13
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
- name: Setup Python
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
with:
python-version: 3.12
cache: pip
cache-dependency-path: 'python/requirements.txt'
- name: Run tests
@ -107,8 +126,8 @@ jobs:
with:
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: "upb-bazel-macos"
bazel: ${{ matrix.config.bazel-command }} --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 ${{ matrix.config.flags }} //bazel/... //benchmarks/... //lua/... //protos/... //protos_generator/... //python/... //upb/... //upb_generator/...
version: 6.3.0
bazel: ${{ matrix.config.bazel-command }} --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 ${{ matrix.config.flags }} //bazel/... //benchmarks/... //lua/... //python/... //upb/... //upb_generator/...
version: 6.4.0
no-python:
strategy:
@ -123,14 +142,14 @@ jobs:
- name: Run tests
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.3.0-91a0ac83e968068672bc6001a4d474cfd9a50f1d
image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:6.4.0-cf84e92285ca133b9c8104ad7b14d70e953cbb8e
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: "upb-bazel-no-python"
bash: >-
which python3 &&
mv `which python3` /tmp &&
! which python3 &&
bazel test $BAZEL_FLAGS --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 //python/... -- -//python/dist:source_wheel
bazel test $BAZEL_FLAGS --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 //python/... -- -//python/dist:source_wheel -//python:aarch64_test -//python:x86_64_test -//python:google/protobuf/pyext/_message.so -//python:proto_api
build_wheels:
name: Build Wheels
@ -144,25 +163,23 @@ jobs:
- name: Build Wheels
uses: protocolbuffers/protobuf-ci/bazel-docker@v3
with:
image: us-docker.pkg.dev/protobuf-build/release-containers/linux/apple@sha256:b3dc9b75d8e599b0e95ed245d89f44b5a4231112f975da89dd02006a484a58df
image: us-docker.pkg.dev/protobuf-build/release-containers/linux/apple:6.4.0-5be0f4fde927ca702ed4cebe096bfb632d6d9a36
credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }}
bazel-cache: upb-bazel-python
bazel: build --crosstool_top=//toolchain:clang_suite --//toolchain:release=true --symlink_prefix=/ -c dbg //python/dist //python/dist:test_wheel //python/dist:source_wheel
- name: Move Wheels
run: mkdir wheels && find _build/out \( -name 'protobuf*.whl' -o -name 'protobuf-*.tar.gz' \) -exec mv '{}' wheels ';'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: python-wheels
path: wheels/
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: requirements
# Tests shouldn't have access to the whole upb repo, upload the one file we need
path: python/requirements.txt
test_wheels:
name: Test Wheels
needs: build_wheels
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
@ -171,26 +188,28 @@ jobs:
# a single wheel. As a result we can just test the oldest and newest
# supported Python versions and assume this gives us sufficient test
# coverage.
- { os: ubuntu-latest, python-version: "3.8", architecture: x64, type: 'binary' }
- { os: macos-11, python-version: "3.8", architecture: x64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.9", architecture: x64, type: 'binary' }
- { os: macos-13, python-version: "3.9", architecture: x64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.12", architecture: x64, type: 'binary' }
- { os: macos-12, python-version: "3.12", architecture: x64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.8", architecture: x64, type: 'source' }
- { os: macos-11, python-version: "3.8", architecture: x64, type: 'source' }
- { os: ubuntu-latest, python-version: "3.12", architecture: x64, type: 'source' }
- { os: macos-12, python-version: "3.12", architecture: x64, type: 'source' }
- { os: macos-13, python-version: "3.12", architecture: x64, type: 'binary' }
- { os: ubuntu-latest, python-version: "3.12", architecture: x64, type: 'source', continuous-only: true }
- { os: macos-13, python-version: "3.12", architecture: x64, type: 'source', continuous-only: true }
- { os: ubuntu-latest, python-version: "3.13", architecture: x64, type: 'source', continuous-only: true }
- { os: macos-13, python-version: "3.13", architecture: x64, type: 'source', continuous-only: true }
# Windows uses the full API up until Python 3.10.
- { os: windows-2019, python-version: "3.8", architecture: x86, type: 'binary' }
- { os: windows-2019, python-version: "3.9", architecture: x86, type: 'binary' }
- { os: windows-2019, python-version: "3.10", architecture: x86, type: 'binary' }
- { os: windows-2019, python-version: "3.11", architecture: x86, type: 'binary' }
- { os: windows-2019, python-version: "3.12", architecture: x86, type: 'binary' }
- { os: windows-2019, python-version: "3.8", architecture: x64, type: 'binary' }
- { os: windows-2019, python-version: "3.9", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.10", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.11", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.12", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.13", architecture: x86, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.9", architecture: x64, type: 'binary' }
- { os: windows-2019, python-version: "3.10", architecture: x64, type: 'binary' }
- { os: windows-2019, python-version: "3.11", architecture: x64, type: 'binary' }
- { os: windows-2019, python-version: "3.12", architecture: x64, type: 'binary' }
- { os: windows-2019, python-version: "3.10", architecture: x64, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.11", architecture: x64, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.12", architecture: x64, type: 'binary', continuous-only: true }
- { os: windows-2019, python-version: "3.13", architecture: x64, type: 'binary' }
name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Test Wheels Python ${{ matrix.python-version }} ${{ matrix.os }} ${{ matrix.architecture }} ${{ matrix.type }}
needs: build_wheels
runs-on: ${{ matrix.os }}
if: ${{ github.event_name != 'pull_request_target' }}
defaults:
@ -198,20 +217,25 @@ jobs:
shell: bash
steps:
- name: Download Wheels
uses: actions/download-artifact@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #4.1.8
with:
name: python-wheels
path: wheels
- name: Download Requirements
uses: actions/download-artifact@v3
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #4.1.8
with:
name: requirements
path: requirements
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
- name: Setup Python
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- name: Setup Python venv
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: |
python -m pip install --upgrade pip
python -m venv env
@ -221,24 +245,28 @@ jobs:
- name: Install tzdata
run: pip install tzdata
# Only needed on Windows, Linux ships with tzdata.
if: ${{ contains(matrix.os, 'windows') }}
if: ${{ contains(matrix.os, 'windows') && (!matrix.continuous-only || inputs.continuous-run) }}
- name: Install requirements
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: pip install -r requirements/requirements.txt
- name: Install Protobuf Binary Wheel
if: ${{ matrix.type == 'binary' && (!matrix.continuous-only || inputs.continuous-run) }}
run: pip install -vvv --no-index --find-links wheels protobuf
if: ${{ matrix.type == 'binary' }}
- name: Install Protobuf Source Wheel
if: ${{ matrix.type == 'source' && (!matrix.continuous-only || inputs.continuous-run) }}
run: |
cd wheels
tar -xzvf *.tar.gz
cd protobuf-*/
pip install .
if: ${{ matrix.type == 'source' }}
- name: Test that module is importable
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: python -v -c 'from google._upb import _message; assert "google._upb._message.MessageMeta" in str(_message.MessageMeta)'
- name: Install Protobuf Test Wheel
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: pip install -vvv --no-index --find-links wheels protobuftests
- name: Run the unit tests
if: ${{ !matrix.continuous-only || inputs.continuous-run }}
run: |
TESTS=$(pip show -f protobuftests | grep pb_unit_tests.*py$ | sed 's,/,.,g' | sed 's,\\,.,g' | sed -E 's,.py$,,g')
for test in $TESTS; do
@ -251,18 +279,19 @@ jobs:
strategy:
fail-fast: false # Don't cancel all jobs if one fails.
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.9", "3.13"]
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request_target' }}
steps:
- name: Download Wheels
uses: actions/download-artifact@v3
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #4.1.8
with:
name: python-wheels
path: wheels
- name: Delete Binary Wheels
run: find wheels -type f | grep -v none-any | xargs rm
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
- name: Setup Python
uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
with:
python-version: ${{ matrix.python-version }}
- name: Setup Python venv
@ -277,7 +306,7 @@ jobs:
run: pip install -vvv --no-index --find-links wheels protobuf protobuftests
- name: Run the unit tests
run: |
TESTS=$(pip show -f protobuftests | grep _test.py | sed 's,/,.,g' | sed -E 's,.py$,,g')
TESTS=$(pip show -f protobuftests | grep _test.py | grep --invert-match _pybind11_test.py | sed 's,/,.,g' | sed -E 's,.py$,,g')
for test in $TESTS; do
python -m unittest -v $test
done

@ -0,0 +1,25 @@
name: Validate YAML
on:
workflow_call:
inputs:
safe-checkout:
required: true
description: "The SHA key for the commit we want to run over"
type: string
permissions:
contents: read
jobs:
validate-yaml:
name: Validate YAML
runs-on: ubuntu-latest
steps:
- name: Checkout pending changes
uses: protocolbuffers/protobuf-ci/checkout@v3
with:
ref: ${{ inputs.safe-checkout }}
- name: Run python validation script
run: |
python .github/scripts/validate_yaml.py

11
.gitmodules vendored

@ -1,11 +0,0 @@
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest.git
ignore = dirty
[submodule "third_party/abseil-cpp"]
path = third_party/abseil-cpp
url = https://github.com/abseil/abseil-cpp.git
branch = lts_2023_08_02
[submodule "third_party/jsoncpp"]
path = third_party/jsoncpp
url = https://github.com/open-source-parsers/jsoncpp.git

@ -16,7 +16,7 @@ conda:
environment: python/docs/environment.yml
python:
version: 3.7
version: 3.8
install:
- method: setuptools
path: python

@ -1,6 +1,7 @@
# Bazel (https://bazel.build/) BUILD file for Protobuf.
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("@rules_license//rules:license.bzl", "license")
load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
load("//bazel:cc_proto_library.bzl", "cc_proto_library")
load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library")
@ -12,7 +13,21 @@ load(":protobuf.bzl", "internal_objc_proto_library", "internal_php_proto_library
licenses(["notice"])
exports_files(["LICENSE"])
exports_files([
"LICENSE",
"PrivacyInfo.xcprivacy",
])
license(
name = "license",
package_name = "protobuf",
license_text = ":LICENSE",
)
exports_files(
["MODULE.bazel"],
visibility = ["//cmake:__pkg__"],
)
################################################################################
# Well Known Types Proto Library Rules
@ -256,7 +271,7 @@ alias(
alias(
name = "protobuf_nowkt",
actual = "//src/google/protobuf:protobuf_layering_check_legacy",
actual = "//src/google/protobuf",
deprecation = "Use //:protobuf instead",
visibility = ["//visibility:public"],
)
@ -418,6 +433,7 @@ proto_lang_toolchain(
name = "cc_toolchain",
blacklisted_protos = [
"//:compiler_plugin_proto",
"//:cpp_features_proto",
"//:descriptor_proto",
],
command_line = "--cpp_out=$(OUT)",
@ -443,6 +459,16 @@ alias(
visibility = ["//visibility:public"],
)
################################################################################
# Rust support
################################################################################
alias(
name = "protobuf_rust",
actual = "//rust:protobuf",
visibility = ["//visibility:public"],
)
################################################################################
# Test protos
################################################################################
@ -621,53 +647,3 @@ filegroup(
srcs = glob(["**/*.bzl"]),
visibility = ["//visibility:public"],
)
################################################################################
# Packaging rules
################################################################################
# Files included in all source distributions
pkg_files(
name = "common_dist_files",
srcs = glob(
[
"*.bzl",
"cmake/*.cmake",
"cmake/*.in",
"editors/*",
],
allow_empty = True,
) + [
"BUILD.bazel",
"CMakeLists.txt",
"CONTRIBUTORS.txt",
"LICENSE",
"README.md",
"WORKSPACE",
"cmake/README.md",
"generate_descriptor_proto.sh",
"maven_install.json",
"//third_party:BUILD.bazel",
"//third_party:zlib.BUILD",
],
strip_prefix = strip_prefix.from_root(""),
visibility = ["//pkg:__pkg__"],
)
# Additional files for C#
pkg_files(
name = "csharp_dist_files",
srcs = [
"global.json",
],
visibility = ["//pkg:__pkg__"],
)
# Additional files for ObjC
pkg_files(
name = "objectivec_dist_files",
srcs = [
"Protobuf.podspec",
],
visibility = ["//pkg:__pkg__"],
)

@ -35,6 +35,11 @@ option(protobuf_BUILD_LIBUPB "Build libupb" ON)
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "")
option(protobuf_ALLOW_CCACHE "Adjust build flags to allow for ccache support." OFF)
option(protobuf_FORCE_FETCH_DEPENDENCIES "Force all dependencies to be downloaded from GitHub. Local installations will be ignored." OFF)
option(protobuf_LOCAL_DEPENDENCIES_ONLY "Prevent downloading any dependencies from GitHub. If this option is set, the dependency must be available locally as an installed package." OFF)
# We support Unity (Jumbo) builds best-effort.
option(protobuf_USE_UNITY_BUILD "Enable Unity (Jumbo) build for" OFF)
if (BUILD_SHARED_LIBS)
set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
else (BUILD_SHARED_LIBS)
@ -81,7 +86,7 @@ if (protobuf_BUILD_SHARED_LIBS)
endif ()
# Version metadata
set(protobuf_VERSION_STRING "5.28.0")
set(protobuf_VERSION_STRING "5.30.0")
set(protobuf_DESCRIPTION "Protocol Buffers")
set(protobuf_CONTACT "protobuf@googlegroups.com")
@ -103,18 +108,21 @@ string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\3"
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\5"
protobuf_VERSION_PRERELEASE "${protobuf_VERSION_STRING}")
message(STATUS "${protobuf_VERSION_PRERELEASE}")
if (protobuf_FORCE_FETCH_DEPENDENCIES AND protobuf_LOCAL_DEPENDENCIES_ONLY)
message(FATAL_ERROR "Conflicting options protobuf_FORCE_FETCH_DEPENDENCIES and protobuf_LOCAL_DEPENDENCIES_ONLY both set")
endif()
# Package version
set(protobuf_VERSION
"${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}")
if(protobuf_VERSION_PRERELEASE)
message(STATUS "${protobuf_VERSION_PRERELEASE}")
set(protobuf_VERSION "${protobuf_VERSION}.${protobuf_VERSION_PRERELEASE}")
else()
set(protobuf_VERSION "${protobuf_VERSION}.0")
endif()
message(STATUS "${protobuf_VERSION}")
message(STATUS "protobuf version: ${protobuf_VERSION}")
if(protobuf_VERBOSE)
message(STATUS "Configuration script parsing status [")
@ -150,14 +158,6 @@ file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map)
find_package(Threads REQUIRED)
# We can install dependencies from submodules if we're running
# CMake v3.13 or newer.
if(CMAKE_VERSION VERSION_LESS 3.13)
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE OFF)
else()
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE ON)
endif()
set(_protobuf_FIND_ZLIB)
if (protobuf_WITH_ZLIB)
find_package(ZLIB)
@ -203,31 +203,11 @@ if (protobuf_BUILD_SHARED_LIBS)
set(protobuf_SHARED_OR_STATIC "SHARED")
else (protobuf_BUILD_SHARED_LIBS)
set(protobuf_SHARED_OR_STATIC "STATIC")
# The CMAKE_<LANG>_FLAGS(_<BUILD_TYPE>)? is meant to be user controlled.
# Prior to CMake 3.15, the MSVC runtime library was pushed into the same flags
# making programmatic control difficult. Prefer the functionality in newer
# CMake versions when available.
if(${CMAKE_VERSION} VERSION_GREATER 3.15 OR ${CMAKE_VERSION} VERSION_EQUAL 3.15)
if (protobuf_MSVC_STATIC_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
endif()
set(ABSL_MSVC_STATIC_RUNTIME ON)
if (protobuf_MSVC_STATIC_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
else()
# In case we are building static libraries, link also the runtime library statically
# so that MSVCR*.DLL is not required at runtime.
# https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
# This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
if (MSVC AND protobuf_MSVC_STATIC_RUNTIME)
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif (MSVC AND protobuf_MSVC_STATIC_RUNTIME)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
endif()
endif (protobuf_BUILD_SHARED_LIBS)
@ -286,12 +266,6 @@ include_directories(
${protobuf_BINARY_DIR}/src
${protobuf_SOURCE_DIR}/src)
set(protobuf_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library")
set_property(CACHE protobuf_ABSL_PROVIDER PROPERTY STRINGS "module" "package")
set(protobuf_JSONCPP_PROVIDER "module" CACHE STRING "Provider of jsoncpp library")
set_property(CACHE protobuf_JSONCPP_PROVIDER PROPERTY STRINGS "module" "package")
if (protobuf_BUILD_TESTS)
include(${protobuf_SOURCE_DIR}/cmake/gtest.cmake)
endif (protobuf_BUILD_TESTS)

@ -1,9 +1,10 @@
{
"checksum": "8863e5b8f3da7cf4502f68bea0d455dec4834bf25ff070caaa58a8e1c5ea1a3d",
"checksum": "89c489aa74f633247650bf28b86db6ec53c041968fd91758693748f553ef102c",
"crates": {
"aho-corasick 1.1.2": {
"name": "aho-corasick",
"version": "1.1.2",
"package_url": "https://github.com/BurntSushi/aho-corasick",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/aho-corasick/1.1.2/download",
@ -15,9 +16,12 @@
"Library": {
"crate_name": "aho_corasick",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -46,11 +50,17 @@
"edition": "2021",
"version": "1.1.2"
},
"license": "Unlicense OR MIT"
"license": "Unlicense OR MIT",
"license_ids": [
"MIT",
"Unlicense"
],
"license_file": "LICENSE-MIT"
},
"autocfg 1.1.0": {
"name": "autocfg",
"version": "1.1.0",
"package_url": "https://github.com/cuviper/autocfg",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/autocfg/1.1.0/download",
@ -62,9 +72,12 @@
"Library": {
"crate_name": "autocfg",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -76,20 +89,29 @@
"edition": "2015",
"version": "1.1.0"
},
"license": "Apache-2.0 OR MIT"
"license": "Apache-2.0 OR MIT",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"direct-cargo-bazel-deps 0.0.1": {
"name": "direct-cargo-bazel-deps",
"version": "0.0.1",
"package_url": null,
"repository": null,
"targets": [
{
"Library": {
"crate_name": "direct_cargo_bazel_deps",
"crate_root": ".direct_cargo_bazel_deps.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -101,7 +123,7 @@
"deps": {
"common": [
{
"id": "googletest 0.11.0",
"id": "googletest 0.12.0",
"target": "googletest"
}
],
@ -119,16 +141,19 @@
},
"version": "0.0.1"
},
"license": null
"license": null,
"license_ids": [],
"license_file": null
},
"googletest 0.11.0": {
"googletest 0.12.0": {
"name": "googletest",
"version": "0.11.0",
"version": "0.12.0",
"package_url": "https://github.com/google/googletest-rust",
"repository": {
"Git": {
"remote": "https://github.com/google/googletest-rust",
"commitish": {
"Rev": "471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f"
"Rev": "b407f3b5774defb8917d714bfb7af485e117d621"
},
"strip_prefix": "googletest"
}
@ -138,9 +163,12 @@
"Library": {
"crate_name": "googletest",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -166,7 +194,7 @@
"proc_macro_deps": {
"common": [
{
"id": "googletest_macro 0.11.0",
"id": "googletest_macro 0.12.0",
"target": "googletest_macro"
},
{
@ -176,18 +204,23 @@
],
"selects": {}
},
"version": "0.11.0"
"version": "0.12.0"
},
"license": "Apache-2.0"
"license": "Apache-2.0",
"license_ids": [
"Apache-2.0"
],
"license_file": "LICENSE"
},
"googletest_macro 0.11.0": {
"googletest_macro 0.12.0": {
"name": "googletest_macro",
"version": "0.11.0",
"version": "0.12.0",
"package_url": "https://github.com/google/googletest-rust",
"repository": {
"Git": {
"remote": "https://github.com/google/googletest-rust",
"commitish": {
"Rev": "471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f"
"Rev": "b407f3b5774defb8917d714bfb7af485e117d621"
},
"strip_prefix": "googletest_macro"
}
@ -197,9 +230,12 @@
"ProcMacro": {
"crate_name": "googletest_macro",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -222,13 +258,18 @@
"selects": {}
},
"edition": "2021",
"version": "0.11.0"
"version": "0.12.0"
},
"license": "Apache-2.0"
"license": "Apache-2.0",
"license_ids": [
"Apache-2.0"
],
"license_file": "LICENSE"
},
"memchr 2.6.4": {
"name": "memchr",
"version": "2.6.4",
"package_url": "https://github.com/BurntSushi/memchr",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/memchr/2.6.4/download",
@ -240,9 +281,12 @@
"Library": {
"crate_name": "memchr",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -262,11 +306,17 @@
"edition": "2021",
"version": "2.6.4"
},
"license": "Unlicense OR MIT"
"license": "Unlicense OR MIT",
"license_ids": [
"MIT",
"Unlicense"
],
"license_file": "LICENSE-MIT"
},
"num-traits 0.2.17": {
"name": "num-traits",
"version": "0.2.17",
"package_url": "https://github.com/rust-num/num-traits",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/num-traits/0.2.17/download",
@ -278,18 +328,24 @@
"Library": {
"crate_name": "num_traits",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
},
{
"BuildScript": {
"crate_name": "build_script_build",
"crate_root": "build.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -318,6 +374,9 @@
"version": "0.2.17"
},
"build_script_attrs": {
"compile_data_glob": [
"**"
],
"data_glob": [
"**"
],
@ -331,11 +390,17 @@
"selects": {}
}
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"paste 1.0.14": {
"name": "paste",
"version": "1.0.14",
"package_url": "https://github.com/dtolnay/paste",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/paste/1.0.14/download",
@ -347,18 +412,24 @@
"ProcMacro": {
"crate_name": "paste",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
},
{
"BuildScript": {
"crate_name": "build_script_build",
"crate_root": "build.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -380,15 +451,24 @@
"version": "1.0.14"
},
"build_script_attrs": {
"compile_data_glob": [
"**"
],
"data_glob": [
"**"
]
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"proc-macro2 1.0.69": {
"name": "proc-macro2",
"version": "1.0.69",
"package_url": "https://github.com/dtolnay/proc-macro2",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/proc-macro2/1.0.69/download",
@ -400,18 +480,24 @@
"Library": {
"crate_name": "proc_macro2",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
},
{
"BuildScript": {
"crate_name": "build_script_build",
"crate_root": "build.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -443,15 +529,24 @@
"version": "1.0.69"
},
"build_script_attrs": {
"compile_data_glob": [
"**"
],
"data_glob": [
"**"
]
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"quote 1.0.33": {
"name": "quote",
"version": "1.0.33",
"package_url": "https://github.com/dtolnay/quote",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/quote/1.0.33/download",
@ -463,9 +558,12 @@
"Library": {
"crate_name": "quote",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -493,11 +591,17 @@
"edition": "2018",
"version": "1.0.33"
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"regex 1.10.0": {
"name": "regex",
"version": "1.10.0",
"package_url": "https://github.com/rust-lang/regex",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/regex/1.10.0/download",
@ -509,9 +613,12 @@
"Library": {
"crate_name": "regex",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -566,11 +673,17 @@
"edition": "2021",
"version": "1.10.0"
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"regex-automata 0.4.1": {
"name": "regex-automata",
"version": "0.4.1",
"package_url": "https://github.com/rust-lang/regex/tree/master/regex-automata",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/regex-automata/0.4.1/download",
@ -582,9 +695,12 @@
"Library": {
"crate_name": "regex_automata",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -640,11 +756,17 @@
"edition": "2021",
"version": "0.4.1"
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"regex-syntax 0.8.1": {
"name": "regex-syntax",
"version": "0.8.1",
"package_url": "https://github.com/rust-lang/regex/tree/master/regex-syntax",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/regex-syntax/0.8.1/download",
@ -656,9 +778,12 @@
"Library": {
"crate_name": "regex_syntax",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -685,11 +810,17 @@
"edition": "2021",
"version": "0.8.1"
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"rustversion 1.0.14": {
"name": "rustversion",
"version": "1.0.14",
"package_url": "https://github.com/dtolnay/rustversion",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/rustversion/1.0.14/download",
@ -701,18 +832,24 @@
"ProcMacro": {
"crate_name": "rustversion",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
},
{
"BuildScript": {
"crate_name": "build_script_build",
"crate_root": "build/build.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -734,15 +871,24 @@
"version": "1.0.14"
},
"build_script_attrs": {
"compile_data_glob": [
"**"
],
"data_glob": [
"**"
]
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"syn 2.0.43": {
"name": "syn",
"version": "2.0.43",
"package_url": "https://github.com/dtolnay/syn",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/syn/2.0.43/download",
@ -754,9 +900,12 @@
"Library": {
"crate_name": "syn",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -798,11 +947,17 @@
"edition": "2021",
"version": "2.0.43"
},
"license": "MIT OR Apache-2.0"
"license": "MIT OR Apache-2.0",
"license_ids": [
"Apache-2.0",
"MIT"
],
"license_file": "LICENSE-APACHE"
},
"unicode-ident 1.0.12": {
"name": "unicode-ident",
"version": "1.0.12",
"package_url": "https://github.com/dtolnay/unicode-ident",
"repository": {
"Http": {
"url": "https://static.crates.io/crates/unicode-ident/1.0.12/download",
@ -814,9 +969,12 @@
"Library": {
"crate_name": "unicode_ident",
"crate_root": "src/lib.rs",
"srcs": [
"**/*.rs"
]
"srcs": {
"allow_empty": true,
"include": [
"**/*.rs"
]
}
}
}
],
@ -828,7 +986,13 @@
"edition": "2018",
"version": "1.0.12"
},
"license": "(MIT OR Apache-2.0) AND Unicode-DFS-2016"
"license": "(MIT OR Apache-2.0) AND Unicode-DFS-2016",
"license_ids": [
"Apache-2.0",
"MIT",
"Unicode-DFS-2016"
],
"license_file": "LICENSE-APACHE"
}
},
"binary_crates": [],
@ -857,6 +1021,12 @@
"aarch64-unknown-linux-gnu": [
"aarch64-unknown-linux-gnu"
],
"aarch64-unknown-nixos-gnu": [
"aarch64-unknown-nixos-gnu"
],
"aarch64-unknown-nto-qnx710": [
"aarch64-unknown-nto-qnx710"
],
"arm-unknown-linux-gnueabi": [
"arm-unknown-linux-gnueabi"
],
@ -926,8 +1096,16 @@
"x86_64-unknown-linux-gnu": [
"x86_64-unknown-linux-gnu"
],
"x86_64-unknown-nixos-gnu": [
"x86_64-unknown-nixos-gnu"
],
"x86_64-unknown-none": [
"x86_64-unknown-none"
]
}
},
"direct_deps": [
"googletest 0.12.0",
"paste 1.0.14"
],
"direct_dev_deps": []
}

8
Cargo.lock generated

@ -27,8 +27,8 @@ dependencies = [
[[package]]
name = "googletest"
version = "0.11.0"
source = "git+https://github.com/google/googletest-rust?rev=471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f#471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f"
version = "0.12.0"
source = "git+https://github.com/google/googletest-rust?rev=b407f3b5774defb8917d714bfb7af485e117d621#b407f3b5774defb8917d714bfb7af485e117d621"
dependencies = [
"googletest_macro",
"num-traits",
@ -38,8 +38,8 @@ dependencies = [
[[package]]
name = "googletest_macro"
version = "0.11.0"
source = "git+https://github.com/google/googletest-rust?rev=471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f#471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f"
version = "0.12.0"
source = "git+https://github.com/google/googletest-rust?rev=b407f3b5774defb8917d714bfb7af485e117d621#b407f3b5774defb8917d714bfb7af485e117d621"
dependencies = [
"quote",
"syn",

@ -1,10 +1,9 @@
# TODO: migrate all dependencies from WORKSPACE to MODULE.bazel
# https://github.com/protocolbuffers/protobuf/issues/14313
PROTOBUF_VERSION = "28.0-dev"
module(
name = "protobuf",
version = PROTOBUF_VERSION,
version = "30.0-dev", # Automatically updated on release
compatibility_level = 1,
repo_name = "com_google_protobuf",
)
@ -13,16 +12,104 @@ module(
# Bzlmod follows MVS:
# https://bazel.build/versions/6.0.0/build/bzlmod#version-resolution
# Thus the highest version in their module graph is resolved.
bazel_dep(name = "abseil-cpp", version = "20230802.0.bcr.1", repo_name = "com_google_absl")
bazel_dep(name = "bazel_skylib", version = "1.4.1")
bazel_dep(name = "jsoncpp", version = "1.9.5")
bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "rules_java", version = "5.3.5")
bazel_dep(name = "rules_jvm_external", version = "5.1")
bazel_dep(name = "rules_pkg", version = "0.7.0")
bazel_dep(name = "rules_python", version = "0.10.2")
bazel_dep(name = "abseil-cpp", version = "20240722.0", repo_name = "com_google_absl")
bazel_dep(name = "bazel_skylib", version = "1.7.0")
bazel_dep(name = "jsoncpp", version = "1.9.6")
bazel_dep(name = "rules_cc", version = "0.0.16")
bazel_dep(name = "rules_fuzzing", version = "0.5.2")
bazel_dep(name = "rules_java", version = "8.3.2")
bazel_dep(name = "rules_jvm_external", version = "6.3")
bazel_dep(name = "rules_kotlin", version = "1.9.6")
bazel_dep(name = "rules_license", version = "1.0.0")
bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_python", version = "0.28.0")
bazel_dep(name = "rules_rust", version = "0.51.0")
bazel_dep(name = "platforms", version = "0.0.8")
bazel_dep(name = "zlib", version = "1.2.11")
bazel_dep(name = "zlib", version = "1.3.1")
bazel_dep(name = "bazel_features", version = "1.17.0", repo_name = "proto_bazel_features")
bazel_dep(
name = "rules_shell",
version = "0.2.0",
)
# Proto toolchains
register_toolchains("//bazel/private/toolchains:all")
SUPPORTED_PYTHON_VERSIONS = [
"3.9",
"3.10",
"3.11",
"3.12",
]
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
[
python.toolchain(
is_default = python_version == SUPPORTED_PYTHON_VERSIONS[-1],
python_version = python_version,
)
for python_version in SUPPORTED_PYTHON_VERSIONS
]
use_repo(
python,
system_python = "python_{}".format(SUPPORTED_PYTHON_VERSIONS[-1].replace(".", "_")),
)
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
[
pip.parse(
hub_name = "pip_deps",
python_version = python_version,
requirements_lock = "//python:requirements.txt",
)
for python_version in SUPPORTED_PYTHON_VERSIONS
]
use_repo(pip, "pip_deps")
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
crate.spec(
package = "googletest",
version = ">0.0.0",
)
crate.spec(
package = "paste",
version = ">=1",
)
crate.from_specs()
use_repo(crate, crate_index = "crates")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
name = "protobuf_maven",
artifacts = [
"com.google.caliper:caliper:1.0-beta-3",
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.code.gson:gson:2.8.9",
"com.google.errorprone:error_prone_annotations:2.5.1",
"com.google.j2objc:j2objc-annotations:2.8",
"com.google.guava:guava:32.0.1-jre",
"com.google.guava:guava-testlib:32.0.1-jre",
"com.google.truth:truth:1.1.2",
"junit:junit:4.13.2",
"org.mockito:mockito-core:4.3.1",
"biz.aQute.bnd:biz.aQute.bndlib:6.4.0",
"info.picocli:picocli:4.6.3",
],
repositories = [
"https://repo1.maven.org/maven2",
"https://repo.maven.apache.org/maven2",
],
)
use_repo(maven, "protobuf_maven")
# Development dependencies
bazel_dep(name = "googletest", version = "1.14.0", dev_dependency = True, repo_name = "com_google_googletest")
bazel_dep(name = "rules_buf", version = "0.3.0", dev_dependency = True)
bazel_dep(name = "rules_testing", version = "0.6.0", dev_dependency = True)
# TODO: remove after toolchain types are moved to protobuf
bazel_dep(name = "rules_proto", version = "4.0.0")
# rules_proto are needed for @com_google_protobuf_v25.0 used in //compatibility/... tests
bazel_dep(name = "rules_proto", version = "4.0.0", dev_dependency = True)

@ -1,48 +0,0 @@
Pod::Spec.new do |s|
s.name = 'Protobuf-C++'
s.version = '5.28.0'
s.summary = 'Protocol Buffers v3 runtime library for C++.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'BSD-3-Clause'
s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
# Ensure developers won't hit CocoaPods/CocoaPods#11402 with the resource
# bundle for the privacy manifest.
s.cocoapods_version = '>= 1.12.0'
s.source = { :git => 'https://github.com/google/protobuf.git',
:tag => "v#{s.version}" }
s.source_files = 'src/google/protobuf/*.{h,cc,inc}',
'src/google/protobuf/stubs/*.{h,cc}',
'src/google/protobuf/io/*.{h,cc}',
'src/google/protobuf/util/*.{h,cc}'
# Excluding all the tests in the directories above
s.exclude_files = 'src/google/**/*_test.{h,cc,inc}',
'src/google/**/*_unittest.{h,cc}',
'src/google/protobuf/test_util*.{h,cc}',
'src/google/protobuf/map_lite_test_util.{h,cc}',
'src/google/protobuf/map_test_util*.{h,cc,inc}',
'src/google/protobuf/reflection_tester.{h,cc}'
s.resource_bundle = {
"Protobuf-C++_Privacy" => "PrivacyInfo.xcprivacy"
}
s.header_mappings_dir = 'src'
s.ios.deployment_target = '12.0'
s.osx.deployment_target = '10.13'
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'
s.pod_target_xcconfig = {
# Do not let src/google/protobuf/stubs/time.h override system API
'USE_HEADERMAP' => 'NO',
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
'HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)/src"'
}
end

@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.28.0'
s.version = '4.30.0'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = 'BSD-3-Clause'
@ -18,21 +18,14 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/protocolbuffers/protobuf.git',
:tag => "v#{s.version}" }
s.source_files = 'objectivec/*.{h,m}',
'objectivec/google/protobuf/Any.pbobjc.h',
'objectivec/google/protobuf/Api.pbobjc.h',
'objectivec/google/protobuf/Duration.pbobjc.h',
'objectivec/google/protobuf/Empty.pbobjc.h',
'objectivec/google/protobuf/FieldMask.pbobjc.h',
'objectivec/google/protobuf/SourceContext.pbobjc.h',
'objectivec/google/protobuf/Struct.pbobjc.h',
'objectivec/google/protobuf/Timestamp.pbobjc.h',
'objectivec/google/protobuf/Type.pbobjc.h',
'objectivec/google/protobuf/Wrappers.pbobjc.h'
s.source_files = 'objectivec/*.{h,m,swift}'
# The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be
# left out, as it's an umbrella implementation file.
s.exclude_files = 'objectivec/GPBProtocolBuffers.m'
# Now that there is a Swift source file, set a version.
s.swift_version = '5.0'
s.resource_bundle = {
"Protobuf_Privacy" => "PrivacyInfo.xcprivacy"
}
@ -41,8 +34,10 @@ Pod::Spec.new do |s|
s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
s.ios.deployment_target = '10.0'
s.osx.deployment_target = '10.12'
s.ios.deployment_target = '15.0'
s.osx.deployment_target = '11.0'
# The following are best-effort / community supported, and are not covered by
# our official support policies: https://protobuf.dev/support/version-support/
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '6.0'
s.visionos.deployment_target = '1.0'

@ -5,10 +5,6 @@ workspace(name = "com_google_protobuf")
# buildifier: disable=duplicated-name
local_repository(name = "com_google_protobuf", path = ".")
# Second self-reference that makes it possible to load proto rules from @protobuf.
# buildifier: disable=duplicated-name
local_repository(name = "protobuf", path = ".")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
local_repository(
@ -25,6 +21,10 @@ load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
load("@rules_python//python/pip_install:repositories.bzl", "pip_install_dependencies")
pip_install_dependencies()
# Bazel platform rules.
http_archive(
name = "platforms",
@ -37,10 +37,10 @@ http_archive(
http_archive(
name = "com_google_googletest",
sha256 = "730215d76eace9dd49bf74ce044e8daa065d175f1ac891cc1d6bb184ef94e565",
strip_prefix = "googletest-f53219cdcb7b084ef57414efea92ee5b71989558",
sha256 = "7315acb6bf10e99f332c8a43f00d5fbb1ee6ca48c52f6b936991b216c586aaad",
strip_prefix = "googletest-1.15.0",
urls = [
"https://github.com/google/googletest/archive/f53219cdcb7b084ef57414efea92ee5b71989558.tar.gz" # 2023-03-16
"https://github.com/google/googletest/releases/download/v1.15.0/googletest-1.15.0.tar.gz" # 2024-07-15
],
)
@ -59,6 +59,7 @@ rules_jvm_external_setup()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
name = "protobuf_maven",
artifacts = PROTOBUF_MAVEN_ARTIFACTS,
# For updating instructions, see:
# https://github.com/bazelbuild/rules_jvm_external#updating-maven_installjson
@ -69,7 +70,7 @@ maven_install(
],
)
load("@maven//:defs.bzl", "pinned_maven_install")
load("@protobuf_maven//:defs.bzl", "pinned_maven_install")
pinned_maven_install()
@ -90,26 +91,32 @@ load("@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependen
apple_support_dependencies()
load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
rules_java_dependencies()
rules_java_toolchains()
load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies")
rules_cc_dependencies()
# For `kt_jvm_library`
load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
kotlin_repositories()
load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
kt_register_toolchains()
http_archive(
name = "rules_ruby",
urls = [
"https://github.com/protocolbuffers/rules_ruby/archive/b7f3e9756f3c45527be27bc38840d5a1ba690436.zip"
"https://github.com/protocolbuffers/rules_ruby/archive/588d9dd40487277e2560ece09fe310d7c0ecb4a6.zip"
],
strip_prefix = "rules_ruby-b7f3e9756f3c45527be27bc38840d5a1ba690436",
sha256 = "347927fd8de6132099fcdc58e8f7eab7bde4eb2fd424546b9cd4f1c6f8f8bad8",
strip_prefix = "rules_ruby-588d9dd40487277e2560ece09fe310d7c0ecb4a6",
integrity = "sha256-Lh/xxR6WsKJnS92sYkpJDBtdS6DNrCbi0kuUxBffG6E=",
)
load("@rules_ruby//ruby:defs.bzl", "ruby_runtime")
@ -177,9 +184,9 @@ install_deps()
http_archive(
name = "rules_fuzzing",
sha256 = "ff52ef4845ab00e95d29c02a9e32e9eff4e0a4c9c8a6bcf8407a2f19eb3f9190",
strip_prefix = "rules_fuzzing-0.4.1",
urls = ["https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.4.1/rules_fuzzing-0.4.1.zip"],
sha256 = "77206c54b71f4dd5335123a6ff2a8ea688eca5378d34b4838114dff71652cf26",
strip_prefix = "rules_fuzzing-0.5.1",
urls = ["https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.5.1/rules_fuzzing-0.5.1.zip"],
patches = ["//third_party:rules_fuzzing.patch"],
patch_args = ["-p1"],
)
@ -198,8 +205,8 @@ fuzzing_py_deps_install_deps()
http_archive(
name = "rules_rust",
sha256 = "9ecd0f2144f0a24e6bc71ebcc50a1ee5128cedeceb32187004532c9710cb2334",
urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.29.1/rules_rust-v0.29.1.tar.gz"],
integrity = "sha256-BCrPtzRpstGEj+FI2Bw0IsYepHqeGQDxyew29R6OcZM=",
urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.51.0/rules_rust-v0.51.0.tar.gz"],
)
load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")
@ -216,7 +223,7 @@ crates_repository(
packages = {
"googletest": crate.spec(
git = "https://github.com/google/googletest-rust",
rev = "471d4a2a8e8bc74f6d7d9c8eecb4d4e3157b2a9f",
rev = "b407f3b5774defb8917d714bfb7af485e117d621",
),
"paste": crate.spec(
version = ">=1",
@ -226,3 +233,47 @@ crates_repository(
load("@crate_index//:defs.bzl", "crate_repositories")
crate_repositories()
# For testing runtime against old gencode from a previous major version.
http_archive(
name = "com_google_protobuf_v25.0",
strip_prefix = "protobuf-25.0",
url = "https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protobuf-25.0.tar.gz",
)
# Needed as a dependency of @com_google_protobuf_v25.0
load("@com_google_protobuf_v25.0//:protobuf_deps.bzl", protobuf_v25_deps="protobuf_deps")
protobuf_v25_deps()
# Needed for testing only
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_testing",
sha256 = "02c62574631876a4e3b02a1820cb51167bb9cdcdea2381b2fa9d9b8b11c407c4",
strip_prefix = "rules_testing-0.6.0",
url = "https://github.com/bazelbuild/rules_testing/releases/download/v0.6.0/rules_testing-v0.6.0.tar.gz",
)
# For checking breaking changes to well-known types from the previous release version.
load("//:protobuf_version.bzl", "PROTOBUF_PREVIOUS_RELEASE")
http_archive(
name = "com_google_protobuf_previous_release",
strip_prefix = "protobuf-" + PROTOBUF_PREVIOUS_RELEASE,
url = "https://github.com/protocolbuffers/protobuf/releases/download/v{0}/protobuf-{0}.tar.gz".format(PROTOBUF_PREVIOUS_RELEASE),
)
http_archive(
name = "rules_buf",
integrity = "sha256-Hr64Q/CaYr0E3ptAjEOgdZd1yc+cBjp7OG1wzuf3DIs=",
strip_prefix = "rules_buf-0.3.0",
urls = [
"https://github.com/bufbuild/rules_buf/archive/refs/tags/v0.3.0.zip",
],
)
load("@rules_buf//buf:repositories.bzl", "rules_buf_dependencies", "rules_buf_toolchains")
rules_buf_dependencies()
rules_buf_toolchains(version = "v1.32.1")

@ -0,0 +1,45 @@
# This is a WORKSPACE file used by bzlmod in combination with MODULE.bazel.
# It's used for a gradual migration and it should be empty.
# Don't remove this file. If the file doesn't exist, bzlmod falls back to WORKSPACE file.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# TODO: either replace rules_ruby with a maintained version on BCR
# or use bzlmod extensions to depend on this specific repo
http_archive(
name = "rules_ruby",
urls = [
"https://github.com/protocolbuffers/rules_ruby/archive/588d9dd40487277e2560ece09fe310d7c0ecb4a6.zip"
],
strip_prefix = "rules_ruby-588d9dd40487277e2560ece09fe310d7c0ecb4a6",
integrity = "sha256-Lh/xxR6WsKJnS92sYkpJDBtdS6DNrCbi0kuUxBffG6E=",
)
load("@rules_ruby//ruby:defs.bzl", "ruby_runtime")
ruby_runtime("system_ruby")
register_toolchains("@system_ruby//:toolchain")
# Following are just needed to run conformance tests, not really needed to support them via MODULE.bazel
# For testing runtime against old gencode from a previous major version.
http_archive(
name = "com_google_protobuf_v25.0",
strip_prefix = "protobuf-25.0",
url = "https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protobuf-25.0.tar.gz",
)
# Needed as a dependency of @com_google_protobuf_v25.0
load("@com_google_protobuf_v25.0//:protobuf_deps.bzl", protobuf_v25_deps="protobuf_deps")
protobuf_v25_deps()
# Needed for checking breaking changes from the previous release version.
load("//:protobuf_version.bzl", "PROTOBUF_PREVIOUS_RELEASE")
http_archive(
name = "com_google_protobuf_previous_release",
strip_prefix = "protobuf-" + PROTOBUF_PREVIOUS_RELEASE,
url = "https://github.com/protocolbuffers/protobuf/releases/download/v{0}/protobuf-{0}.tar.gz".format(PROTOBUF_PREVIOUS_RELEASE),
)

@ -13,24 +13,31 @@ bzl_library(
name = "proto_library_bzl",
srcs = ["proto_library.bzl"],
visibility = ["//visibility:public"],
deps = [
"//bazel/private:bazel_proto_library_rule_bzl",
"@proto_bazel_features//:features",
],
)
bzl_library(
name = "cc_proto_library_bzl",
srcs = ["cc_proto_library.bzl"],
visibility = ["//visibility:public"],
deps = ["//bazel/private:bazel_cc_proto_library_bzl"],
)
bzl_library(
name = "java_proto_library_bzl",
srcs = ["java_proto_library.bzl"],
visibility = ["//visibility:public"],
deps = ["//bazel/private:bazel_java_proto_library_rule_bzl"],
)
bzl_library(
name = "java_lite_proto_library_bzl",
srcs = ["java_lite_proto_library.bzl"],
visibility = ["//visibility:public"],
deps = ["//bazel/private:java_lite_proto_library_bzl"],
)
bzl_library(
@ -40,6 +47,7 @@ bzl_library(
deps = [
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"//bazel/private:toolchain_helpers_bzl",
"@rules_python//python:py_info_bzl",
],
)
@ -55,3 +63,19 @@ bzl_library(
visibility = ["//visibility:public"],
deps = ["//bazel/private:upb_proto_library_internal_bzl"],
)
# The data in this target is exposed in //bazel/private:for_bazel_tests
filegroup(
name = "for_bazel_tests",
testonly = True,
srcs = [
"BUILD.bazel",
":cc_proto_library_bzl",
":java_lite_proto_library_bzl",
":proto_library_bzl",
":py_proto_library_bzl",
"//bazel/common:for_bazel_tests",
"//bazel/toolchains:for_bazel_tests",
],
visibility = ["//bazel/private:__pkg__"],
)

@ -1,3 +1,10 @@
"""cc_proto_library rule"""
cc_proto_library = native.cc_proto_library
load("//bazel/private:bazel_cc_proto_library.bzl", _cc_proto_library = "cc_proto_library") # buildifier: disable=bzl-visibility
def cc_proto_library(**kwattrs):
# Only use Starlark rules when they are removed from Bazel
if not hasattr(native, "cc_proto_library"):
_cc_proto_library(**kwattrs)
else:
native.cc_proto_library(**kwattrs) # buildifier: disable=native-cc-proto

@ -1,5 +1,7 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
package(default_applicable_licenses = ["//:license"])
bzl_library(
name = "proto_common_bzl",
srcs = [
@ -7,7 +9,10 @@ bzl_library(
],
visibility = ["//visibility:public"],
deps = [
":proto_lang_toolchain_info_bzl",
"//bazel/private:native_bzl",
"//bazel/private:toolchain_helpers_bzl",
"@proto_bazel_features//:features",
],
)
@ -18,7 +23,8 @@ bzl_library(
],
visibility = ["//visibility:public"],
deps = [
"//bazel/private:native_bzl",
"//bazel/private:proto_info_bzl",
"@proto_bazel_features//:features",
],
)
@ -29,6 +35,18 @@ bzl_library(
],
visibility = ["//visibility:public"],
deps = [
":proto_common.bzl",
"//bazel/private:native_bzl",
],
)
filegroup(
name = "for_bazel_tests",
testonly = True,
srcs = [
"BUILD",
"proto_common_bzl",
"proto_info_bzl",
"proto_lang_toolchain_info_bzl",
],
visibility = ["//bazel:__pkg__"],
)

@ -1,5 +1,356 @@
"""proto_common"""
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Definition of proto_common module, together with bazel providers for proto rules."""
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo")
load("//bazel/private:native.bzl", "native_proto_common")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
proto_common = native_proto_common
def _import_virtual_proto_path(path):
"""Imports all paths for virtual imports.
They're of the form:
'bazel-out/k8-fastbuild/bin/external/foo/e/_virtual_imports/e' or
'bazel-out/foo/k8-fastbuild/bin/e/_virtual_imports/e'"""
if path.count("/") > 4:
return "-I%s" % path
return None
def _import_repo_proto_path(path):
"""Imports all paths for generated files in external repositories.
They are of the form:
'bazel-out/k8-fastbuild/bin/external/foo' or
'bazel-out/foo/k8-fastbuild/bin'"""
path_count = path.count("/")
if path_count > 2 and path_count <= 4:
return "-I%s" % path
return None
def _import_main_output_proto_path(path):
"""Imports all paths for generated files or source files in external repositories.
They're of the form:
'bazel-out/k8-fastbuild/bin'
'external/foo'
'../foo'
"""
if path.count("/") <= 2 and path != ".":
return "-I%s" % path
return None
def _remove_repo(file):
"""Removes `../repo/` prefix from path, e.g. `../repo/package/path -> package/path`"""
short_path = file.short_path
workspace_root = file.owner.workspace_root
if workspace_root:
if workspace_root.startswith("external/"):
workspace_root = "../" + workspace_root.removeprefix("external/")
return short_path.removeprefix(workspace_root + "/")
return short_path
def _get_import_path(proto_file):
"""Returns the import path of a .proto file
This is the path as used for the file that can be used in an `import` statement in another
.proto file.
Args:
proto_file: (File) The .proto file
Returns:
(str) import path
"""
repo_path = _remove_repo(proto_file)
index = repo_path.find("_virtual_imports/")
if index >= 0:
index = repo_path.find("/", index + len("_virtual_imports/"))
repo_path = repo_path[index + 1:]
return repo_path
def _output_directory(proto_info, root):
proto_source_root = proto_info.proto_source_root
if proto_source_root.startswith(root.path):
#TODO: remove this branch when bin_dir is removed from proto_source_root
proto_source_root = proto_source_root.removeprefix(root.path).removeprefix("/")
if proto_source_root == "" or proto_source_root == ".":
return root.path
return root.path + "/" + proto_source_root
def _check_collocated(label, proto_info, proto_lang_toolchain_info):
"""Checks if lang_proto_library is collocated with proto_library.
Exceptions are allowed by an allowlist defined on `proto_lang_toolchain` and
on an allowlist defined on `proto_library`'s `allow_exports` attribute.
If checks are not successful the function fails.
Args:
label: (Label) The label of lang_proto_library
proto_info: (ProtoInfo) The ProtoInfo from the proto_library dependency.
proto_lang_toolchain_info: (ProtoLangToolchainInfo) The proto lang toolchain info.
Obtained from a `proto_lang_toolchain` target.
"""
_PackageSpecificationInfo = bazel_features.globals.PackageSpecificationInfo
if not _PackageSpecificationInfo:
if proto_lang_toolchain_info.allowlist_different_package or getattr(proto_info, "allow_exports", None):
fail("Allowlist checks not supported before Bazel 6.4.0")
return
if (proto_info.direct_descriptor_set.owner.package != label.package and
proto_lang_toolchain_info.allowlist_different_package):
if not proto_lang_toolchain_info.allowlist_different_package[_PackageSpecificationInfo].contains(label):
fail(("lang_proto_library '%s' may only be created in the same package " +
"as proto_library '%s'") % (label, proto_info.direct_descriptor_set.owner))
if (proto_info.direct_descriptor_set.owner.package != label.package and
hasattr(proto_info, "allow_exports")):
if not proto_info.allow_exports[_PackageSpecificationInfo].contains(label):
fail(("lang_proto_library '%s' may only be created in the same package " +
"as proto_library '%s'") % (label, proto_info.direct_descriptor_set.owner))
def _compile(
actions,
proto_info,
proto_lang_toolchain_info,
generated_files,
plugin_output = None,
additional_args = None,
additional_tools = [],
additional_inputs = depset(),
additional_proto_lang_toolchain_info = None,
resource_set = None,
experimental_exec_group = None,
experimental_progress_message = None,
experimental_output_files = "legacy"):
"""Creates proto compile action for compiling *.proto files to language specific sources.
Args:
actions: (ActionFactory) Obtained by ctx.actions, used to register the actions.
proto_info: (ProtoInfo) The ProtoInfo from proto_library to generate the sources for.
proto_lang_toolchain_info: (ProtoLangToolchainInfo) The proto lang toolchain info.
Obtained from a `proto_lang_toolchain` target or constructed ad-hoc..
generated_files: (list[File]) The output files generated by the proto compiler.
Callee needs to declare files using `ctx.actions.declare_file`.
See also: `proto_common.declare_generated_files`.
plugin_output: (File|str) Deprecated: Set `proto_lang_toolchain.output_files`
and remove the parameter.
For backwards compatibility, when the proto_lang_toolchain isn't updated
the value is used.
additional_args: (Args) Additional arguments to add to the action.
Accepts a ctx.actions.args() object that is added at the beginning
of the command line.
additional_tools: (list[File]) Additional tools to add to the action.
additional_inputs: (Depset[File]) Additional input files to add to the action.
resource_set: (func) A callback function that is passed to the created action.
See `ctx.actions.run`, `resource_set` parameter for full definition of
the callback.
experimental_exec_group: (str) Sets `exec_group` on proto compile action.
Avoid using this parameter.
experimental_progress_message: Overrides progress_message from the toolchain.
Don't use this parameter. It's only intended for the transition.
experimental_output_files: (str) Overwrites output_files from the toolchain.
Don't use this parameter. It's only intended for the transition.
"""
if type(generated_files) != type([]):
fail("generated_files is expected to be a list of Files")
if not generated_files:
return # nothing to do
if experimental_output_files not in ["single", "multiple", "legacy"]:
fail('experimental_output_files expected to be one of ["single", "multiple", "legacy"]')
args = actions.args()
args.use_param_file(param_file_arg = "@%s")
args.set_param_file_format("multiline")
tools = list(additional_tools)
if experimental_output_files != "legacy":
output_files = experimental_output_files
else:
output_files = getattr(proto_lang_toolchain_info, "output_files", "legacy")
if output_files != "legacy":
if proto_lang_toolchain_info.out_replacement_format_flag:
if output_files == "single":
if len(generated_files) > 1:
fail("generated_files only expected a single file")
plugin_output = generated_files[0]
else:
plugin_output = _output_directory(proto_info, generated_files[0].root)
if plugin_output:
args.add(plugin_output, format = proto_lang_toolchain_info.out_replacement_format_flag)
if proto_lang_toolchain_info.plugin:
tools.append(proto_lang_toolchain_info.plugin)
args.add(proto_lang_toolchain_info.plugin.executable, format = proto_lang_toolchain_info.plugin_format_flag)
# Protoc searches for .protos -I paths in order they are given and then
# uses the path within the directory as the package.
# This requires ordering the paths from most specific (longest) to least
# specific ones, so that no path in the list is a prefix of any of the
# following paths in the list.
# For example: 'bazel-out/k8-fastbuild/bin/external/foo' needs to be listed
# before 'bazel-out/k8-fastbuild/bin'. If not, protoc will discover file under
# the shorter path and use 'external/foo/...' as its package path.
args.add_all(proto_info.transitive_proto_path, map_each = _import_virtual_proto_path)
args.add_all(proto_info.transitive_proto_path, map_each = _import_repo_proto_path)
args.add_all(proto_info.transitive_proto_path, map_each = _import_main_output_proto_path)
args.add("-I.") # Needs to come last
args.add_all(proto_lang_toolchain_info.protoc_opts)
args.add_all(proto_info.direct_sources)
if additional_args:
additional_args.use_param_file(param_file_arg = "@%s")
additional_args.set_param_file_format("multiline")
actions.run(
mnemonic = proto_lang_toolchain_info.mnemonic,
progress_message = experimental_progress_message if experimental_progress_message else proto_lang_toolchain_info.progress_message,
executable = proto_lang_toolchain_info.proto_compiler,
arguments = [args, additional_args] if additional_args else [args],
inputs = depset(transitive = [proto_info.transitive_sources, additional_inputs]),
outputs = generated_files,
tools = tools,
use_default_shell_env = True,
resource_set = resource_set,
exec_group = experimental_exec_group,
toolchain = _toolchain_type(proto_lang_toolchain_info),
)
_BAZEL_TOOLS_PREFIX = "external/bazel_tools/"
def _experimental_filter_sources(proto_info, proto_lang_toolchain_info):
if not proto_info.direct_sources:
return [], []
# Collect a set of provided protos
provided_proto_sources = proto_lang_toolchain_info.provided_proto_sources
provided_paths = {}
for src in provided_proto_sources:
path = src.path
# For listed protos bundled with the Bazel tools repository, their exec paths start
# with external/bazel_tools/. This prefix needs to be removed first, because the protos in
# user repositories will not have that prefix.
if path.startswith(_BAZEL_TOOLS_PREFIX):
provided_paths[path[len(_BAZEL_TOOLS_PREFIX):]] = None
else:
provided_paths[path] = None
# Filter proto files
proto_files = proto_info._direct_proto_sources
excluded = []
included = []
for proto_file in proto_files:
if proto_file.path in provided_paths:
excluded.append(proto_file)
else:
included.append(proto_file)
return included, excluded
def _experimental_should_generate_code(
proto_info,
proto_lang_toolchain_info,
rule_name,
target_label):
"""Checks if the code should be generated for the given proto_library.
The code shouldn't be generated only when the toolchain already provides it
to the language through its runtime dependency.
It fails when the proto_library contains mixed proto files, that should and
shouldn't generate code.
Args:
proto_info: (ProtoInfo) The ProtoInfo from proto_library to check the generation for.
proto_lang_toolchain_info: (ProtoLangToolchainInfo) The proto lang toolchain info.
Obtained from a `proto_lang_toolchain` target or constructed ad-hoc.
rule_name: (str) Name of the rule used in the failure message.
target_label: (Label) The label of the target used in the failure message.
Returns:
(bool) True when the code should be generated.
"""
included, excluded = _experimental_filter_sources(proto_info, proto_lang_toolchain_info)
if included and excluded:
fail(("The 'srcs' attribute of '%s' contains protos for which '%s' " +
"shouldn't generate code (%s), in addition to protos for which it should (%s).\n" +
"Separate '%s' into 2 proto_library rules.") % (
target_label,
rule_name,
", ".join([f.short_path for f in excluded]),
", ".join([f.short_path for f in included]),
target_label,
))
return bool(included)
def _declare_generated_files(
actions,
proto_info,
extension,
name_mapper = None):
"""Declares generated files with a specific extension.
Use this in lang_proto_library-es when protocol compiler generates files
that correspond to .proto file names.
The function removes ".proto" extension with given one (e.g. ".pb.cc") and
declares new output files.
Args:
actions: (ActionFactory) Obtained by ctx.actions, used to declare the files.
proto_info: (ProtoInfo) The ProtoInfo to declare the files for.
extension: (str) The extension to use for generated files.
name_mapper: (str->str) A function mapped over the base filename without
the extension. Used it to replace characters in the name that
cause problems in a specific programming language.
Returns:
(list[File]) The list of declared files.
"""
proto_sources = proto_info.direct_sources
outputs = []
for src in proto_sources:
basename_no_ext = src.basename[:-(len(src.extension) + 1)]
if name_mapper:
basename_no_ext = name_mapper(basename_no_ext)
# Note that two proto_library rules can have the same source file, so this is actually a
# shared action. NB: This can probably result in action conflicts if the proto_library rules
# are not the same.
outputs.append(actions.declare_file(basename_no_ext + extension, sibling = src))
return outputs
def _toolchain_type(proto_lang_toolchain_info):
if toolchains.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION:
return getattr(proto_lang_toolchain_info, "toolchain_type", None)
else:
return None
proto_common = struct(
compile = _compile,
declare_generated_files = _declare_generated_files,
check_collocated = _check_collocated,
experimental_should_generate_code = _experimental_should_generate_code,
experimental_filter_sources = _experimental_filter_sources,
get_import_path = _get_import_path,
ProtoLangToolchainInfo = ProtoLangToolchainInfo,
INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION = toolchains.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION,
INCOMPATIBLE_PASS_TOOLCHAIN_TYPE = (
getattr(native_proto_common, "INCOMPATIBLE_PASS_TOOLCHAIN_TYPE", False) or
not hasattr(native_proto_common, "ProtoLangToolchainInfo")
),
)

@ -1,5 +1,7 @@
"""ProtoInfo"""
load("//bazel/private:native.bzl", "NativeProtoInfo")
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/private:proto_info.bzl", _ProtoInfo = "ProtoInfo") # buildifier: disable=bzl-visibility
ProtoInfo = NativeProtoInfo
# This resolves to Starlark ProtoInfo in Bazel 8 or with --incompatible_enable_autoload flag
ProtoInfo = getattr(bazel_features.globals, "ProtoInfo", None) or _ProtoInfo

@ -1,5 +1,26 @@
"""ProtoLangToolchainInfo"""
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/private:native.bzl", "native_proto_common") # buildifier: disable=bzl-visibility
ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
# Use Starlark implementation only if native_proto_common.ProtoLangToolchainInfo doesn't exist
ProtoLangToolchainInfo = getattr(native_proto_common, "ProtoLangToolchainInfo", provider(
doc = """Specifies how to generate language-specific code from .proto files.
Used by LANG_proto_library rules.""",
fields = dict(
out_replacement_format_flag = """(str) Format string used when passing output to the plugin
used by proto compiler.""",
output_files = """("single","multiple","legacy") Format out_replacement_format_flag with
a path to single file or a directory in case of multiple files.""",
plugin_format_flag = "(str) Format string used when passing plugin to proto compiler.",
plugin = "(FilesToRunProvider) Proto compiler plugin.",
runtime = "(Target) Runtime.",
provided_proto_sources = "(list[File]) Proto sources provided by the toolchain.",
proto_compiler = "(FilesToRunProvider) Proto compiler.",
protoc_opts = "(list[str]) Options to pass to proto compiler.",
progress_message = "(str) Progress message to set on the proto compiler action.",
mnemonic = "(str) Mnemonic to set on the proto compiler action.",
allowlist_different_package = """(Target) Allowlist to create lang_proto_library in a
different package than proto_library""",
toolchain_type = """(Label) Toolchain type that was used to obtain this info""",
),
))

@ -1,3 +1,16 @@
# Copyright (c) 2009-2024, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""java_lite_proto_library rule"""
java_lite_proto_library = native.java_lite_proto_library
load("//bazel/private:java_lite_proto_library.bzl", _java_lite_proto_library = "java_lite_proto_library") # buildifier: disable=bzl-visibility
def java_lite_proto_library(**kwattrs):
# Only use Starlark rules when they are removed from Bazel
if not hasattr(native, "java_lite_proto_library"):
_java_lite_proto_library(**kwattrs)
else:
native.java_lite_proto_library(**kwattrs)

@ -1,3 +1,16 @@
# Copyright (c) 2009-2024, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""java_proto_library rule"""
java_proto_library = native.java_proto_library
load("//bazel/private:bazel_java_proto_library_rule.bzl", _java_proto_library = "java_proto_library") # buildifier: disable=bzl-visibility
def java_proto_library(**kwattrs):
# Only use Starlark rules when they are removed from Bazel
if not hasattr(native, "java_proto_library"):
_java_proto_library(**kwattrs)
else:
native.java_proto_library(**kwattrs)

@ -0,0 +1,211 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":native_bool_flag.bzl", "native_bool_flag")
package(default_applicable_licenses = ["//:license"])
toolchain_type(
name = "proto_toolchain_type",
visibility = ["//visibility:public"],
)
toolchain_type(
name = "cc_toolchain_type",
visibility = ["//visibility:public"],
)
toolchain_type(
name = "java_toolchain_type",
visibility = ["//visibility:public"],
)
toolchain_type(
name = "javalite_toolchain_type",
visibility = ["//visibility:public"],
)
toolchain_type(
name = "python_toolchain_type",
visibility = ["//visibility:public"],
)
bzl_library(
name = "upb_proto_library_internal_bzl",
srcs = [
"upb_proto_library_internal/aspect.bzl",
"upb_proto_library_internal/cc_library_func.bzl",
"upb_proto_library_internal/copts.bzl",
"upb_proto_library_internal/rule.bzl",
],
visibility = ["//bazel:__pkg__"],
deps = [
"//bazel/common:proto_common_bzl",
"@bazel_skylib//lib:paths",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
],
)
bzl_library(
name = "native_bzl",
srcs = [
"native.bzl",
],
visibility = ["//bazel:__subpackages__"],
)
bzl_library(
name = "proto_info_bzl",
srcs = ["proto_info.bzl"],
visibility = ["//bazel:__subpackages__"],
)
bzl_library(
name = "bazel_proto_library_rule_bzl",
srcs = [
"bazel_proto_library_rule.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"@bazel_skylib//lib:paths",
"@bazel_skylib//rules:common_settings",
"@proto_bazel_features//:features",
],
)
bzl_library(
name = "bazel_java_proto_library_rule_bzl",
srcs = [
"bazel_java_proto_library_rule.bzl",
"java_proto_support.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"@rules_java//java/common",
],
)
bzl_library(
name = "java_lite_proto_library_bzl",
srcs = [
"java_lite_proto_library.bzl",
"java_proto_support.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"@rules_java//java/common",
],
)
bzl_library(
name = "bazel_cc_proto_library_bzl",
srcs = [
"bazel_cc_proto_library.bzl",
"cc_proto_support.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"@proto_bazel_features//:features",
"@rules_cc//cc:find_cc_toolchain_bzl",
],
)
bzl_library(
name = "proto_toolchain_rule_bzl",
srcs = [
"proto_toolchain_rule.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_lang_toolchain_info_bzl",
],
)
bzl_library(
name = "proto_lang_toolchain_rule_bzl",
srcs = [
"proto_lang_toolchain_rule.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":toolchain_helpers_bzl",
"//bazel/common:proto_common_bzl",
"//bazel/common:proto_info_bzl",
"//bazel/common:proto_lang_toolchain_info_bzl",
"@proto_bazel_features//:features",
],
)
bzl_library(
name = "cc_proto_aspect_bzl",
srcs = ["cc_proto_aspect.bzl"],
deps = [
":bazel_cc_proto_library_bzl",
],
)
bzl_library(
name = "toolchain_helpers_bzl",
srcs = [
"toolchain_helpers.bzl",
],
visibility = ["//bazel:__subpackages__"],
deps = [
":native_bzl",
"//bazel/common:proto_lang_toolchain_info_bzl",
],
)
native_bool_flag(
name = "experimental_proto_descriptor_sets_include_source_info",
flag = "experimental_proto_descriptor_sets_include_source_info",
match_value = "true",
visibility = ["//bazel:__subpackages__"],
)
native_bool_flag(
name = "strict_proto_deps",
flag = "strict_proto_deps",
match_value = "off",
result = False,
visibility = ["//bazel:__subpackages__"],
)
native_bool_flag(
name = "strict_public_imports",
flag = "strict_public_imports",
match_value = "off",
result = False,
visibility = ["//bazel:__subpackages__"],
)
bzl_library(
name = "native_bool_flag_bzl",
srcs = ["native_bool_flag.bzl"],
visibility = ["//visibility:private"],
deps = ["@bazel_skylib//rules:common_settings"],
)
filegroup(
name = "for_bazel_tests",
testonly = True,
srcs = [
"BUILD",
":native_bool_flag_bzl",
"//bazel:for_bazel_tests",
"//bazel/private/toolchains:for_bazel_tests",
],
visibility = ["//visibility:public"],
)

@ -1,42 +0,0 @@
# Copyright (c) 2009-2021, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
licenses(["notice"])
bzl_library(
name = "upb_proto_library_internal_bzl",
srcs = [
"upb_proto_library_internal/aspect.bzl",
"upb_proto_library_internal/cc_library_func.bzl",
"upb_proto_library_internal/copts.bzl",
"upb_proto_library_internal/rule.bzl",
],
visibility = ["//bazel:__pkg__"],
deps = [
"//bazel/common:proto_common_bzl",
"@bazel_skylib//lib:paths",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
],
)
bzl_library(
name = "native_bzl",
srcs = [
"native.bzl",
],
visibility = ["//bazel:__subpackages__"],
)
bzl_library(
name = "proto_toolchain_rule_bzl",
srcs = [
"proto_toolchain_rule.bzl",
],
visibility = ["//bazel:__subpackages__"],
)

@ -0,0 +1,198 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Bazel's implementation of cc_proto_library"""
load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:cc_proto_support.bzl", "cc_proto_compile_and_link")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
_CC_PROTO_TOOLCHAIN = Label("//bazel/private:cc_toolchain_type")
_ProtoCcFilesInfo = provider(fields = ["files"], doc = "Provide cc proto files.")
_ProtoCcHeaderInfo = provider(fields = ["headers"], doc = "Provide cc proto headers.")
def _get_output_files(actions, proto_info, suffixes):
result = []
for suffix in suffixes:
result.extend(proto_common.declare_generated_files(
actions = actions,
proto_info = proto_info,
extension = suffix,
))
return result
# TODO: Make this code actually work.
def _get_strip_include_prefix(ctx, proto_info):
proto_root = proto_info.proto_source_root
if proto_root == "." or proto_root == ctx.label.workspace_root:
return ""
strip_include_prefix = ""
if proto_root.startswith(ctx.bin_dir.path):
proto_root = proto_root[len(ctx.bin_dir.path) + 1:]
elif proto_root.startswith(ctx.genfiles_dir.path):
proto_root = proto_root[len(ctx.genfiles_dir.path) + 1:]
if proto_root.startswith(ctx.label.workspace_root):
proto_root = proto_root[len(ctx.label.workspace_root):]
strip_include_prefix = "//" + proto_root
return strip_include_prefix
def _aspect_impl(target, ctx):
proto_info = target[ProtoInfo]
proto_configuration = ctx.fragments.proto
sources = []
headers = []
textual_hdrs = []
proto_toolchain = toolchains.find_toolchain(ctx, "_aspect_cc_proto_toolchain", _CC_PROTO_TOOLCHAIN)
should_generate_code = proto_common.experimental_should_generate_code(proto_info, proto_toolchain, "cc_proto_library", target.label)
if should_generate_code:
if len(proto_info.direct_sources) != 0:
# Bazel 7 didn't expose cc_proto_library_source_suffixes used by Kythe
# gradually falling back to .pb.cc
if type(proto_configuration.cc_proto_library_source_suffixes) == "builtin_function_or_method":
source_suffixes = [".pb.cc"]
header_suffixes = [".pb.h"]
else:
source_suffixes = proto_configuration.cc_proto_library_source_suffixes
header_suffixes = proto_configuration.cc_proto_library_header_suffixes
sources = _get_output_files(ctx.actions, proto_info, source_suffixes)
headers = _get_output_files(ctx.actions, proto_info, header_suffixes)
header_provider = _ProtoCcHeaderInfo(headers = depset(headers))
else:
# If this proto_library doesn't have sources, it provides the combined headers of all its
# direct dependencies. Thus, if a direct dependency does have sources, the generated files
# are also provided by this library. If a direct dependency does not have sources, it will
# do the same thing, so that effectively this library looks through all source-less
# proto_libraries and provides all generated headers of the proto_libraries with sources
# that it depends on.
transitive_headers = []
for dep in getattr(ctx.rule.attr, "deps", []):
if _ProtoCcHeaderInfo in dep:
textual_hdrs.extend(dep[_ProtoCcHeaderInfo].headers.to_list())
transitive_headers.append(dep[_ProtoCcHeaderInfo].headers)
header_provider = _ProtoCcHeaderInfo(headers = depset(transitive = transitive_headers))
else: # shouldn't generate code
header_provider = _ProtoCcHeaderInfo(headers = depset())
proto_common.compile(
actions = ctx.actions,
proto_info = proto_info,
proto_lang_toolchain_info = proto_toolchain,
generated_files = sources + headers,
experimental_output_files = "multiple",
)
deps = []
if proto_toolchain.runtime:
deps = [proto_toolchain.runtime]
deps.extend(getattr(ctx.rule.attr, "deps", []))
cc_info, libraries, temps = cc_proto_compile_and_link(
ctx = ctx,
deps = deps,
sources = sources,
headers = headers,
textual_hdrs = textual_hdrs,
strip_include_prefix = _get_strip_include_prefix(ctx, proto_info),
)
return [
cc_info,
_ProtoCcFilesInfo(files = depset(sources + headers + libraries)),
OutputGroupInfo(temp_files_INTERNAL_ = temps),
header_provider,
]
cc_proto_aspect = aspect(
implementation = _aspect_impl,
attr_aspects = ["deps"],
fragments = ["cpp", "proto"],
required_providers = [ProtoInfo],
provides = [CcInfo],
attrs = toolchains.if_legacy_toolchain({"_aspect_cc_proto_toolchain": attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_cc"),
)}),
toolchains = use_cc_toolchain() + toolchains.use_toolchain(_CC_PROTO_TOOLCHAIN),
)
def _cc_proto_library_impl(ctx):
if len(ctx.attr.deps) != 1:
fail(
"'deps' attribute must contain exactly one label " +
"(we didn't name it 'dep' for consistency). " +
"The main use-case for multiple deps is to create a rule that contains several " +
"other targets. This makes dependency bloat more likely. It also makes it harder" +
"to remove unused deps.",
attr = "deps",
)
dep = ctx.attr.deps[0]
proto_toolchain = toolchains.find_toolchain(ctx, "_aspect_cc_proto_toolchain", _CC_PROTO_TOOLCHAIN)
proto_common.check_collocated(ctx.label, dep[ProtoInfo], proto_toolchain)
return [DefaultInfo(files = dep[_ProtoCcFilesInfo].files), dep[CcInfo], dep[OutputGroupInfo]]
cc_proto_library = rule(
implementation = _cc_proto_library_impl,
doc = """
<p>
<code>cc_proto_library</code> generates C++ code from <code>.proto</code> files.
</p>
<p>
<code>deps</code> must point to <a href="protocol-buffer.html#proto_library"><code>proto_library
</code></a> rules.
</p>
<p>
Example:
</p>
<pre>
<code class="lang-starlark">
cc_library(
name = "lib",
deps = [":foo_cc_proto"],
)
cc_proto_library(
name = "foo_cc_proto",
deps = [":foo_proto"],
)
proto_library(
name = "foo_proto",
)
</code>
</pre>
""",
attrs = {
"deps": attr.label_list(
aspects = [cc_proto_aspect],
allow_rules = ["proto_library"],
allow_files = False,
doc = """
The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
rules to generate C++ code for.""",
),
} | toolchains.if_legacy_toolchain({
"_aspect_cc_proto_toolchain": attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_cc"),
),
}),
provides = [CcInfo],
toolchains = toolchains.use_toolchain(_CC_PROTO_TOOLCHAIN),
)

@ -0,0 +1,164 @@
# Copyright (c) 2009-2024, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""The implementation of the `java_proto_library` rule and its aspect."""
load("@rules_java//java/common:java_info.bzl", "JavaInfo")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:java_proto_support.bzl", "JavaProtoAspectInfo", "java_compile_for_protos", "java_info_merge_for_protos")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
_JAVA_PROTO_TOOLCHAIN = Label("//bazel/private:java_toolchain_type")
def _filter_provider(provider, *attrs):
return [dep[provider] for attr in attrs for dep in attr if provider in dep]
def _bazel_java_proto_aspect_impl(target, ctx):
"""Generates and compiles Java code for a proto_library.
The function runs protobuf compiler on the `proto_library` target using
`proto_lang_toolchain` specified by `--proto_toolchain_for_java` flag.
This generates a source jar.
After that the source jar is compiled, respecting `deps` and `exports` of
the `proto_library`.
Args:
target: (Target) The `proto_library` target (any target providing `ProtoInfo`.
ctx: (RuleContext) The rule context.
Returns:
([JavaInfo, JavaProtoAspectInfo]) A JavaInfo describing compiled Java
version of`proto_library` and `JavaProtoAspectInfo` with all source and
runtime jars.
"""
proto_toolchain_info = toolchains.find_toolchain(ctx, "_aspect_java_proto_toolchain", _JAVA_PROTO_TOOLCHAIN)
source_jar = None
if proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain_info, "java_proto_library", target.label):
# Generate source jar using proto compiler.
source_jar = ctx.actions.declare_file(ctx.label.name + "-speed-src.jar")
proto_common.compile(
ctx.actions,
target[ProtoInfo],
proto_toolchain_info,
[source_jar],
experimental_output_files = "single",
)
# Compile Java sources (or just merge if there aren't any)
deps = _filter_provider(JavaInfo, ctx.rule.attr.deps)
exports = _filter_provider(JavaInfo, ctx.rule.attr.exports)
if source_jar and proto_toolchain_info.runtime:
deps.append(proto_toolchain_info.runtime[JavaInfo])
java_info, jars = java_compile_for_protos(
ctx,
"-speed.jar",
source_jar,
deps,
exports,
)
transitive_jars = [dep[JavaProtoAspectInfo].jars for dep in ctx.rule.attr.deps if JavaProtoAspectInfo in dep]
return [
java_info,
JavaProtoAspectInfo(jars = depset(jars, transitive = transitive_jars)),
]
bazel_java_proto_aspect = aspect(
implementation = _bazel_java_proto_aspect_impl,
attrs = toolchains.if_legacy_toolchain({
"_aspect_java_proto_toolchain": attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java"),
),
}),
toolchains = ["@bazel_tools//tools/jdk:toolchain_type"] + toolchains.use_toolchain(_JAVA_PROTO_TOOLCHAIN),
attr_aspects = ["deps", "exports"],
required_providers = [ProtoInfo],
provides = [JavaInfo, JavaProtoAspectInfo],
fragments = ["java"],
)
def bazel_java_proto_library_rule(ctx):
"""Merges results of `java_proto_aspect` in `deps`.
Args:
ctx: (RuleContext) The rule context.
Returns:
([JavaInfo, DefaultInfo, OutputGroupInfo])
"""
proto_toolchain = toolchains.find_toolchain(ctx, "_aspect_java_proto_toolchain", _JAVA_PROTO_TOOLCHAIN)
for dep in ctx.attr.deps:
proto_common.check_collocated(ctx.label, dep[ProtoInfo], proto_toolchain)
java_info = java_info_merge_for_protos([dep[JavaInfo] for dep in ctx.attr.deps], merge_java_outputs = False)
transitive_src_and_runtime_jars = depset(transitive = [dep[JavaProtoAspectInfo].jars for dep in ctx.attr.deps])
transitive_runtime_jars = depset(transitive = [java_info.transitive_runtime_jars])
return [
java_info,
DefaultInfo(
files = transitive_src_and_runtime_jars,
runfiles = ctx.runfiles(transitive_files = transitive_runtime_jars),
),
OutputGroupInfo(default = depset()),
]
java_proto_library = rule(
implementation = bazel_java_proto_library_rule,
doc = """
<p>
<code>java_proto_library</code> generates Java code from <code>.proto</code> files.
</p>
<p>
<code>deps</code> must point to <a href="protocol-buffer.html#proto_library"><code>proto_library
</code></a> rules.
</p>
<p>
Example:
</p>
<pre class="code">
<code class="lang-starlark">
java_library(
name = "lib",
runtime_deps = [":foo_java_proto"],
)
java_proto_library(
name = "foo_java_proto",
deps = [":foo_proto"],
)
proto_library(
name = "foo_proto",
)
</code>
</pre>
""",
attrs = {
"deps": attr.label_list(
providers = [ProtoInfo],
aspects = [bazel_java_proto_aspect],
doc = """
The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
rules to generate Java code for.
""",
),
# buildifier: disable=attr-license (calling attr.license())
"licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
} | toolchains.if_legacy_toolchain({
"_aspect_java_proto_toolchain": attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java"),
),
}), # buildifier: disable=attr-licenses (attribute called licenses)
provides = [JavaInfo],
toolchains = toolchains.use_toolchain(_JAVA_PROTO_TOOLCHAIN),
)

@ -0,0 +1,356 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""
Implementation of proto_library rule.
"""
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
STRICT_DEPS_FLAG_TEMPLATE = (
#
"--direct_dependencies_violation_msg=" +
"%%s is imported, but %s doesn't directly depend on a proto_library that 'srcs' it."
)
def _check_srcs_package(target_package, srcs):
"""Check that .proto files in sources are from the same package.
This is done to avoid clashes with the generated sources."""
#TODO: this does not work with filegroups that contain files that are not in the package
for src in srcs:
if target_package != src.label.package:
fail("Proto source with label '%s' must be in same package as consuming rule." % src.label)
def _get_import_prefix(ctx):
"""Gets and verifies import_prefix attribute if it is declared."""
import_prefix = ctx.attr.import_prefix
if not paths.is_normalized(import_prefix):
fail("should be normalized (without uplevel references or '.' path segments)", attr = "import_prefix")
if paths.is_absolute(import_prefix):
fail("should be a relative path", attr = "import_prefix")
return import_prefix
def _get_strip_import_prefix(ctx):
"""Gets and verifies strip_import_prefix."""
strip_import_prefix = ctx.attr.strip_import_prefix
if not paths.is_normalized(strip_import_prefix):
fail("should be normalized (without uplevel references or '.' path segments)", attr = "strip_import_prefix")
if paths.is_absolute(strip_import_prefix):
strip_import_prefix = strip_import_prefix[1:]
else: # Relative to current package
strip_import_prefix = _join(ctx.label.package, strip_import_prefix)
return strip_import_prefix.removesuffix("/")
def _proto_library_impl(ctx):
# Verifies attributes.
_check_srcs_package(ctx.label.package, ctx.attr.srcs)
srcs = ctx.files.srcs
deps = [dep[ProtoInfo] for dep in ctx.attr.deps]
exports = [dep[ProtoInfo] for dep in ctx.attr.exports]
import_prefix = _get_import_prefix(ctx)
strip_import_prefix = _get_strip_import_prefix(ctx)
check_for_reexport = deps + exports if not srcs else exports
_PackageSpecificationInfo = bazel_features.globals.PackageSpecificationInfo
for proto in check_for_reexport:
if getattr(proto, "allow_exports", None):
if not _PackageSpecificationInfo:
fail("Allowlist checks not supported before Bazel 6.4.0")
if not proto.allow_exports[_PackageSpecificationInfo].contains(ctx.label):
fail("proto_library '%s' can't be reexported in package '//%s'" % (proto.direct_descriptor_set.owner, ctx.label.package))
proto_path, virtual_srcs = _process_srcs(ctx, srcs, import_prefix, strip_import_prefix)
descriptor_set = ctx.actions.declare_file(ctx.label.name + "-descriptor-set.proto.bin")
proto_info = ProtoInfo(
srcs = virtual_srcs,
deps = deps,
descriptor_set = descriptor_set,
proto_path = proto_path,
workspace_root = ctx.label.workspace_root,
bin_dir = ctx.bin_dir.path,
allow_exports = ctx.attr.allow_exports,
)
_write_descriptor_set(ctx, proto_info, deps, exports, descriptor_set)
# We assume that the proto sources will not have conflicting artifacts
# with the same root relative path
data_runfiles = ctx.runfiles(
files = [proto_info.direct_descriptor_set],
transitive_files = depset(transitive = [proto_info.transitive_sources]),
)
return [
proto_info,
DefaultInfo(
files = depset([proto_info.direct_descriptor_set]),
default_runfiles = ctx.runfiles(), # empty
data_runfiles = data_runfiles,
),
]
def _process_srcs(ctx, srcs, import_prefix, strip_import_prefix):
"""Returns proto_path and sources, optionally symlinking them to _virtual_imports.
Returns:
(str, [File]) A pair of proto_path and virtual_sources.
"""
if import_prefix != "" or strip_import_prefix != "":
# Use virtual source roots
return _symlink_to_virtual_imports(ctx, srcs, import_prefix, strip_import_prefix)
else:
# No virtual source roots
return "", srcs
def _join(*path):
return "/".join([p for p in path if p != ""])
def _symlink_to_virtual_imports(ctx, srcs, import_prefix, strip_import_prefix):
"""Symlinks srcs to _virtual_imports.
Returns:
A pair proto_path, directs_sources.
"""
virtual_imports = _join("_virtual_imports", ctx.label.name)
proto_path = _join(ctx.label.package, virtual_imports)
if ctx.label.workspace_name == "":
full_strip_import_prefix = strip_import_prefix
else:
full_strip_import_prefix = _join("..", ctx.label.workspace_name, strip_import_prefix)
if full_strip_import_prefix:
full_strip_import_prefix += "/"
virtual_srcs = []
for src in srcs:
# Remove strip_import_prefix
if not src.short_path.startswith(full_strip_import_prefix):
fail(".proto file '%s' is not under the specified strip prefix '%s'" %
(src.short_path, full_strip_import_prefix))
import_path = src.short_path[len(full_strip_import_prefix):]
# Add import_prefix
virtual_src = ctx.actions.declare_file(_join(virtual_imports, import_prefix, import_path))
ctx.actions.symlink(
output = virtual_src,
target_file = src,
progress_message = "Symlinking virtual .proto sources for %{label}",
)
virtual_srcs.append(virtual_src)
return proto_path, virtual_srcs
def _write_descriptor_set(ctx, proto_info, deps, exports, descriptor_set):
"""Writes descriptor set."""
if proto_info.direct_sources == []:
ctx.actions.write(descriptor_set, "")
return
dependencies_descriptor_sets = depset(transitive = [dep.transitive_descriptor_sets for dep in deps])
args = ctx.actions.args()
if ctx.attr._experimental_proto_descriptor_sets_include_source_info[BuildSettingInfo].value:
args.add("--include_source_info")
args.add("--retain_options")
strict_deps = ctx.attr._strict_proto_deps[BuildSettingInfo].value
if strict_deps:
if proto_info.direct_sources:
strict_importable_sources = depset(
direct = proto_info._direct_proto_sources,
transitive = [dep._exported_sources for dep in deps],
)
else:
strict_importable_sources = None
if strict_importable_sources:
args.add_joined(
"--direct_dependencies",
strict_importable_sources,
map_each = proto_common.get_import_path,
join_with = ":",
)
# Example: `--direct_dependencies a.proto:b.proto`
else:
# The proto compiler requires an empty list to turn on strict deps checking
args.add("--direct_dependencies=")
# Set `-direct_dependencies_violation_msg=`
args.add(ctx.label, format = STRICT_DEPS_FLAG_TEMPLATE)
strict_imports = ctx.attr._strict_public_imports[BuildSettingInfo].value
if strict_imports:
public_import_protos = depset(transitive = [export._exported_sources for export in exports])
if not public_import_protos:
# This line is necessary to trigger the check.
args.add("--allowed_public_imports=")
else:
args.add_joined(
"--allowed_public_imports",
public_import_protos,
map_each = proto_common.get_import_path,
join_with = ":",
)
if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION:
toolchain = ctx.toolchains[toolchains.PROTO_TOOLCHAIN]
if not toolchain:
fail("Protocol compiler toolchain could not be resolved.")
proto_lang_toolchain_info = toolchain.proto
else:
proto_lang_toolchain_info = proto_common.ProtoLangToolchainInfo(
out_replacement_format_flag = "--descriptor_set_out=%s",
output_files = "single",
mnemonic = "GenProtoDescriptorSet",
progress_message = "Generating Descriptor Set proto_library %{label}",
proto_compiler = ctx.executable._proto_compiler,
protoc_opts = ctx.fragments.proto.experimental_protoc_opts,
plugin = None,
)
proto_common.compile(
ctx.actions,
proto_info,
proto_lang_toolchain_info,
generated_files = [descriptor_set],
additional_inputs = dependencies_descriptor_sets,
additional_args = args,
)
proto_library = rule(
_proto_library_impl,
# TODO: proto_common docs are missing
# TODO: ProtoInfo link doesn't work and docs are missing
doc = """
<p>If using Bazel, please load the rule from <a href="https://github.com/bazelbuild/rules_proto">
https://github.com/bazelbuild/rules_proto</a>.
<p>Use <code>proto_library</code> to define libraries of protocol buffers which
may be used from multiple languages. A <code>proto_library</code> may be listed
in the <code>deps</code> clause of supported rules, such as
<code>java_proto_library</code>.
<p>When compiled on the command-line, a <code>proto_library</code> creates a file
named <code>foo-descriptor-set.proto.bin</code>, which is the descriptor set for
the messages the rule srcs. The file is a serialized
<code>FileDescriptorSet</code>, which is described in
<a href="https://developers.google.com/protocol-buffers/docs/techniques#self-description">
https://developers.google.com/protocol-buffers/docs/techniques#self-description</a>.
<p>It only contains information about the <code>.proto</code> files directly
mentioned by a <code>proto_library</code> rule; the collection of transitive
descriptor sets is available through the
<code>[ProtoInfo].transitive_descriptor_sets</code> Starlark provider.
See documentation in <code>proto_info.bzl</code>.
<p>Recommended code organization:
<ul>
<li>One <code>proto_library</code> rule per <code>.proto</code> file.
<li>A file named <code>foo.proto</code> will be in a rule named <code>foo_proto</code>,
which is located in the same package.
<li>A <code>[language]_proto_library</code> that wraps a <code>proto_library</code>
named <code>foo_proto</code> should be called <code>foo_[language]_proto</code>,
and be located in the same package.
</ul>""",
attrs = {
"srcs": attr.label_list(
allow_files = [".proto", ".protodevel"],
flags = ["DIRECT_COMPILE_TIME_INPUT"],
# TODO: Should .protodevel be advertised or deprecated?
doc = """
The list of <code>.proto</code> and <code>.protodevel</code> files that are
processed to create the target. This is usually a non empty list. One usecase
where <code>srcs</code> can be empty is an <i>alias-library</i>. This is a
proto_library rule having one or more other proto_library in <code>deps</code>.
This pattern can be used to e.g. export a public api under a persistent name.""",
),
"deps": attr.label_list(
providers = [ProtoInfo],
doc = """
The list of other <code>proto_library</code> rules that the target depends upon.
A <code>proto_library</code> may only depend on other <code>proto_library</code>
targets. It may not depend on language-specific libraries.""",
),
"exports": attr.label_list(
providers = [ProtoInfo],
doc = """
List of proto_library targets that can be referenced via "import public" in the
proto source.
It's an error if you use "import public" but do not list the corresponding library
in the exports attribute.
Note that you have list the library both in deps and exports since not all
lang_proto_library implementations have been changed yet.""",
),
"strip_import_prefix": attr.string(
default = "/",
doc = """
The prefix to strip from the paths of the .proto files in this rule.
<p>When set, .proto source files in the <code>srcs</code> attribute of this rule are
accessible at their path with this prefix cut off.
<p>If it's a relative path (not starting with a slash), it's taken as a package-relative
one. If it's an absolute one, it's understood as a repository-relative path.
<p>The prefix in the <code>import_prefix</code> attribute is added after this prefix is
stripped.""",
),
"import_prefix": attr.string(
doc = """
The prefix to add to the paths of the .proto files in this rule.
<p>When set, the .proto source files in the <code>srcs</code> attribute of this rule are
accessible at is the value of this attribute prepended to their repository-relative path.
<p>The prefix in the <code>strip_import_prefix</code> attribute is removed before this
prefix is added.""",
),
"allow_exports": attr.label(
cfg = "exec",
providers = [bazel_features.globals.PackageSpecificationInfo] if bazel_features.globals.PackageSpecificationInfo else [],
doc = """
An optional allowlist that prevents proto library to be reexported or used in
lang_proto_library that is not in one of the listed packages.""",
),
"data": attr.label_list(
allow_files = True,
flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
),
# buildifier: disable=attr-license (calling attr.license())
"licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
"_experimental_proto_descriptor_sets_include_source_info": attr.label(
default = "//bazel/private:experimental_proto_descriptor_sets_include_source_info",
),
"_strict_proto_deps": attr.label(
default =
"//bazel/private:strict_proto_deps",
),
"_strict_public_imports": attr.label(
default = "//bazel/private:strict_public_imports",
),
} | toolchains.if_legacy_toolchain({
"_proto_compiler": attr.label(
cfg = "exec",
executable = True,
allow_files = True,
default = configuration_field("proto", "proto_compiler"),
),
}), # buildifier: disable=attr-licenses (attribute called licenses)
fragments = ["proto"],
provides = [ProtoInfo],
toolchains = toolchains.use_toolchain(toolchains.PROTO_TOOLCHAIN),
)

@ -0,0 +1,6 @@
"""Exposes cc_proto_aspect to rules_rust"""
load("//bazel/private:bazel_cc_proto_library.bzl", _cc_proto_aspect = "cc_proto_aspect") # buildifier: disable=bzl-visibility
load("//bazel/private:native.bzl", _native_cc_proto_aspect = "native_cc_proto_aspect") # buildifier: disable=bzl-visibility
cc_proto_aspect = _cc_proto_aspect if not hasattr(native, "cc_proto_library") else _native_cc_proto_aspect

@ -0,0 +1,143 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Supporting C++ compilation of generated code"""
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
def get_feature_configuration(ctx, has_sources, extra_requested_features = []):
"""Returns C++ feature configuration for compiling and linking generated C++ files.
Args:
ctx: (RuleCtx) rule context.
has_sources: (bool) Has the proto_library sources.
extra_requested_features: (list[str]) Additionally requested features.
Returns:
(FeatureConfiguration) C++ feature configuration
"""
cc_toolchain = find_cc_toolchain(ctx)
requested_features = ctx.features + extra_requested_features
# TODO: Remove LAYERING_CHECK once we have verified that there are direct
# dependencies for all generated #includes.
unsupported_features = ctx.disabled_features + ["parse_headers", "layering_check"]
if has_sources:
requested_features.append("header_modules")
else:
unsupported_features.append("header_modules")
return cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = requested_features,
unsupported_features = unsupported_features,
)
def _get_libraries_from_linking_outputs(linking_outputs, feature_configuration):
library_to_link = linking_outputs.library_to_link
if not library_to_link:
return []
outputs = []
if library_to_link.static_library:
outputs.append(library_to_link.static_library)
if library_to_link.pic_static_library:
outputs.append(library_to_link.pic_static_library)
# On Windows, dynamic library is not built by default, so don't add them to files_to_build.
if not cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
if library_to_link.resolved_symlink_dynamic_library:
outputs.append(library_to_link.resolved_symlink_dynamic_library)
elif library_to_link.dynamic_library:
outputs.append(library_to_link.dynamic_library)
if library_to_link.resolved_symlink_interface_library:
outputs.append(library_to_link.resolved_symlink_interface_library)
elif library_to_link.interface_library:
outputs.append(library_to_link.interface_library)
return outputs
def cc_proto_compile_and_link(ctx, deps, sources, headers, disallow_dynamic_library = None, feature_configuration = None, alwayslink = False, **kwargs):
"""Creates C++ compilation and linking actions for C++ proto sources.
Args:
ctx: rule context
deps: (list[CcInfo]) List of libraries to be added as dependencies to compilation and linking
actions.
sources:(list[File]) List of C++ sources files.
headers: list(File] List of C++ headers files.
disallow_dynamic_library: (bool) Are dynamic libraries disallowed.
feature_configuration: (FeatureConfiguration) feature configuration to use.
alwayslink: (bool) Should the library be always linked.
**kwargs: Additional arguments passed to the compilation. See cc_common.compile.
Returns:
(CcInfo, list[File], list[File])
- CcInfo provider with compilation context and linking context
- A list of linked libraries related to this proto
- A list of temporary files generated durind compilation
"""
cc_toolchain = find_cc_toolchain(ctx)
feature_configuration = feature_configuration or get_feature_configuration(ctx, bool(sources))
if disallow_dynamic_library == None:
# TODO: Configure output artifact with action_config
# once proto compile action is configurable from the crosstool.
disallow_dynamic_library = not cc_common.is_enabled(
feature_name = "supports_dynamic_linker",
feature_configuration = feature_configuration,
)
(compilation_context, compilation_outputs) = cc_common.compile(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
srcs = sources,
public_hdrs = headers,
compilation_contexts = [dep[CcInfo].compilation_context for dep in deps if CcInfo in dep],
name = ctx.label.name,
# Don't instrument the generated C++ files even when --collect_code_coverage is set.
# If we actually start generating coverage instrumentation for .proto files based on coverage
# data from the generated C++ files, this will have to be removed. Currently, the work done
# to instrument those files and execute the instrumentation is all for nothing, and it can
# be quite a bit of extra computation even when that's not made worse by performance bugs,
# as in b/64963386.
# code_coverage_enabled = False (cc_common.compile disables code_coverage by default)
**kwargs
)
if sources:
linking_context, linking_outputs = cc_common.create_linking_context_from_compilation_outputs(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
compilation_outputs = compilation_outputs,
linking_contexts = [dep[CcInfo].linking_context for dep in deps if CcInfo in dep],
name = ctx.label.name,
disallow_dynamic_library = disallow_dynamic_library,
alwayslink = alwayslink,
)
libraries = _get_libraries_from_linking_outputs(linking_outputs, feature_configuration)
else:
linking_context = cc_common.merge_linking_contexts(
linking_contexts = [dep[CcInfo].linking_context for dep in deps if CcInfo in dep],
)
libraries = []
debug_context = None
temps = []
if bazel_features.cc.protobuf_on_allowlist:
debug_context = cc_common.merge_debug_context(
[cc_common.create_debug_context(compilation_outputs)] +
[dep[CcInfo].debug_context() for dep in deps if CcInfo in dep],
)
temps = compilation_outputs.temps()
return CcInfo(
compilation_context = compilation_context,
linking_context = linking_context,
debug_context = debug_context,
), libraries, temps

@ -0,0 +1,178 @@
# Copyright (c) 2009-2024, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""A Starlark implementation of the java_lite_proto_library rule."""
load("@rules_java//java/common:java_common.bzl", "java_common")
load("@rules_java//java/common:java_info.bzl", "JavaInfo")
load("@rules_java//java/common:proguard_spec_info.bzl", "ProguardSpecInfo")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:java_proto_support.bzl", "JavaProtoAspectInfo", "java_compile_for_protos", "java_info_merge_for_protos")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
_PROTO_TOOLCHAIN_ATTR = "_aspect_proto_toolchain_for_javalite"
_JAVA_LITE_PROTO_TOOLCHAIN = Label("//bazel/private:javalite_toolchain_type")
def _aspect_impl(target, ctx):
"""Generates and compiles Java code for a proto_library dependency graph.
Args:
target: (Target) The `proto_library` target.
ctx: (RuleContext) The rule context.
Returns:
([JavaInfo, JavaProtoAspectInfo]) A JavaInfo describing compiled Java
version of`proto_library` and `JavaProtoAspectInfo` with all source and
runtime jars.
"""
deps = [dep[JavaInfo] for dep in ctx.rule.attr.deps]
exports = [exp[JavaInfo] for exp in ctx.rule.attr.exports]
proto_toolchain_info = toolchains.find_toolchain(
ctx,
"_aspect_proto_toolchain_for_javalite",
_JAVA_LITE_PROTO_TOOLCHAIN,
)
source_jar = None
if proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain_info, "java_lite_proto_library", target.label):
source_jar = ctx.actions.declare_file(ctx.label.name + "-lite-src.jar")
proto_common.compile(
ctx.actions,
target[ProtoInfo],
proto_toolchain_info,
[source_jar],
experimental_output_files = "single",
)
runtime = proto_toolchain_info.runtime
if runtime:
deps.append(runtime[JavaInfo])
java_info, jars = java_compile_for_protos(
ctx,
"-lite.jar",
source_jar,
deps,
exports,
injecting_rule_kind = "java_lite_proto_library",
)
transitive_jars = [dep[JavaProtoAspectInfo].jars for dep in ctx.rule.attr.deps]
return [
java_info,
JavaProtoAspectInfo(jars = depset(jars, transitive = transitive_jars)),
]
_java_lite_proto_aspect = aspect(
implementation = _aspect_impl,
attr_aspects = ["deps", "exports"],
attrs = toolchains.if_legacy_toolchain({
_PROTO_TOOLCHAIN_ATTR: attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"),
),
}),
fragments = ["java"],
required_providers = [ProtoInfo],
provides = [JavaInfo, JavaProtoAspectInfo],
toolchains = ["@bazel_tools//tools/jdk:toolchain_type"] +
toolchains.use_toolchain(_JAVA_LITE_PROTO_TOOLCHAIN),
)
def _rule_impl(ctx):
"""Merges results of `java_proto_aspect` in `deps`.
`java_lite_proto_library` is identical to `java_proto_library` in every respect, except it
builds JavaLite protos.
Implementation of this rule is built on the implementation of `java_proto_library`.
Args:
ctx: (RuleContext) The rule context.
Returns:
([JavaInfo, DefaultInfo, OutputGroupInfo, ProguardSpecInfo])
"""
proto_toolchain_info = toolchains.find_toolchain(
ctx,
"_aspect_proto_toolchain_for_javalite",
_JAVA_LITE_PROTO_TOOLCHAIN,
)
for dep in ctx.attr.deps:
proto_common.check_collocated(ctx.label, dep[ProtoInfo], proto_toolchain_info)
runtime = proto_toolchain_info.runtime
if runtime:
proguard_provider_specs = runtime[ProguardSpecInfo]
else:
proguard_provider_specs = ProguardSpecInfo(depset())
java_info = java_info_merge_for_protos([dep[JavaInfo] for dep in ctx.attr.deps], merge_java_outputs = False)
transitive_src_and_runtime_jars = depset(transitive = [dep[JavaProtoAspectInfo].jars for dep in ctx.attr.deps])
transitive_runtime_jars = depset(transitive = [java_info.transitive_runtime_jars])
if hasattr(java_common, "add_constraints"):
java_info = java_common.add_constraints(java_info, constraints = ["android"])
return [
java_info,
DefaultInfo(
files = transitive_src_and_runtime_jars,
runfiles = ctx.runfiles(transitive_files = transitive_runtime_jars),
),
OutputGroupInfo(default = depset()),
proguard_provider_specs,
]
java_lite_proto_library = rule(
implementation = _rule_impl,
doc = """
<p>
<code>java_lite_proto_library</code> generates Java code from <code>.proto</code> files.
</p>
<p>
<code>deps</code> must point to <a href="protocol-buffer.html#proto_library"><code>proto_library
</code></a> rules.
</p>
<p>
Example:
</p>
<pre class="code">
<code class="lang-starlark">
java_library(
name = "lib",
runtime_deps = [":foo"],
)
java_lite_proto_library(
name = "foo",
deps = [":bar"],
)
proto_library(
name = "bar",
)
</code>
</pre>
""",
attrs = {
"deps": attr.label_list(providers = [ProtoInfo], aspects = [_java_lite_proto_aspect], doc = """
The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
rules to generate Java code for.
"""),
} | toolchains.if_legacy_toolchain({
_PROTO_TOOLCHAIN_ATTR: attr.label(
default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"),
),
}),
provides = [JavaInfo],
toolchains = toolchains.use_toolchain(_JAVA_LITE_PROTO_TOOLCHAIN),
)

@ -0,0 +1,62 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""Support for compiling protoc generated Java code."""
load("@rules_java//java/private:proto_support.bzl", "compile", "merge") # buildifier: disable=bzl-visibility
# The provider is used to collect source and runtime jars in the `proto_library` dependency graph.
JavaProtoAspectInfo = provider("JavaProtoAspectInfo", fields = ["jars"])
java_info_merge_for_protos = merge
def java_compile_for_protos(ctx, output_jar_suffix, source_jar = None, deps = [], exports = [], injecting_rule_kind = "java_proto_library"):
"""Compiles Java source jar returned by proto compiler.
Use this call for java_xxx_proto_library. It uses java_common.compile with
some checks disabled (via javacopts) and jspecify disabled, so that the
generated code passes.
It also takes care that input source jar is not repackaged with a different
name.
When `source_jar` is `None`, the function only merges `deps` and `exports`.
Args:
ctx: (RuleContext) Used to call `java_common.compile`
output_jar_suffix: (str) How to name the output jar. For example: `-speed.jar`.
source_jar: (File) Input source jar (may be `None`).
deps: (list[JavaInfo]) `deps` of the `proto_library`.
exports: (list[JavaInfo]) `exports` of the `proto_library`.
injecting_rule_kind: (str) Rule kind requesting the compilation.
It's embedded into META-INF of the produced runtime jar, for debugging.
Returns:
((JavaInfo, list[File])) JavaInfo of this target and list containing source
and runtime jar, when they are created.
"""
if source_jar != None:
path, sep, filename = ctx.label.name.rpartition("/")
output_jar = ctx.actions.declare_file(path + sep + "lib" + filename + output_jar_suffix)
java_toolchain = ctx.toolchains["@bazel_tools//tools/jdk:toolchain_type"].java
java_info = compile(
ctx = ctx,
output = output_jar,
java_toolchain = java_toolchain,
source_jars = [source_jar],
deps = deps,
exports = exports,
output_source_jar = source_jar,
injecting_rule_kind = injecting_rule_kind,
javac_opts = java_toolchain._compatible_javacopts.get("proto", depset()),
enable_jspecify = False,
include_compilation_info = False,
)
jars = [source_jar, output_jar]
else:
# If there are no proto sources just pass along the compilation dependencies.
java_info = merge(deps + exports, merge_java_outputs = False, merge_source_jars = False)
jars = []
return java_info, jars

@ -1,5 +1,5 @@
"""Renames toplevel symbols so they can be exported in Starlark under the same name"""
NativeProtoInfo = ProtoInfo
native_proto_common = proto_common_do_not_use
native_cc_proto_aspect = cc_proto_aspect

@ -0,0 +1,35 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""
A helper rule that reads a native boolean flag.
"""
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
def _impl(ctx):
return [BuildSettingInfo(value = ctx.attr.value)]
_native_bool_flag_rule = rule(
implementation = _impl,
attrs = {"value": attr.bool()},
)
def native_bool_flag(*, name, flag, match_value = "true", result = True, **kwargs):
_native_bool_flag_rule(
name = name,
value = select({
name + "_setting": result,
"//conditions:default": not result,
}),
**kwargs
)
native.config_setting(
name = name + "_setting",
values = {flag: match_value},
visibility = ["//visibility:private"],
)

@ -0,0 +1,59 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Vendored version of bazel_features for protobuf, to keep a one-step setup"""
_PROTO_BAZEL_FEATURES = """bazel_features = struct(
cc = struct(
protobuf_on_allowlist = {protobuf_on_allowlist},
),
proto = struct(
starlark_proto_info = {starlark_proto_info},
),
globals = struct(
PackageSpecificationInfo = {PackageSpecificationInfo},
ProtoInfo = getattr(getattr(native, 'legacy_globals', None), 'ProtoInfo', {ProtoInfo})
),
)
"""
def _proto_bazel_features_impl(rctx):
# An empty string is treated as a "dev version", which is greater than anything.
bazel_version = native.bazel_version or "999999.999999.999999"
version_parts = bazel_version.split("-")[0].split(".")
if len(version_parts) != 3:
fail("invalid Bazel version '{}': got {} dot-separated segments, want 3".format(bazel_version, len(version_parts)))
major_version_int = int(version_parts[0])
minor_version_int = int(version_parts[1])
starlark_proto_info = major_version_int >= 7
PackageSpecificationInfo = major_version_int > 6 or (major_version_int == 6 and minor_version_int >= 4)
protobuf_on_allowlist = major_version_int > 7
ProtoInfo = "ProtoInfo" if major_version_int < 8 else "None"
rctx.file("BUILD.bazel", """
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
bzl_library(
name = "features",
srcs = ["features.bzl"],
visibility = ["//visibility:public"],
)
exports_files(["features.bzl"])
""")
rctx.file("features.bzl", _PROTO_BAZEL_FEATURES.format(
starlark_proto_info = repr(starlark_proto_info),
PackageSpecificationInfo = "PackageSpecificationInfo" if PackageSpecificationInfo else "None",
protobuf_on_allowlist = repr(protobuf_on_allowlist),
ProtoInfo = ProtoInfo,
))
proto_bazel_features = repository_rule(
implementation = _proto_bazel_features_impl,
# Force reruns on server restarts to keep native.bazel_version up-to-date.
local = True,
)

@ -0,0 +1,186 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""
Definition of ProtoInfo provider.
"""
_warning = """ Don't use this field. It's intended for internal use and will be changed or removed
without warning."""
def _uniq(iterable):
unique_elements = {element: None for element in iterable}
return list(unique_elements.keys())
def _join(*path):
return "/".join([p for p in path if p != ""])
def _empty_to_dot(path):
return path if path else "."
def _from_root(root, repo, relpath):
"""Constructs an exec path from root to relpath"""
if not root:
# `relpath` is a directory with an input source file, the exec path is one of:
# - when in main repo: `package/path`
# - when in a external repository: `external/repo/package/path`
# - with sibling layout: `../repo/package/path`
return _join(repo, relpath)
else:
# `relpath` is a directory with a generated file or an output directory:
# - when in main repo: `{root}/package/path`
# - when in an external repository: `{root}/external/repo/package/path`
# - with sibling layout: `{root}/package/path`
return _join(root, "" if repo.startswith("../") else repo, relpath)
def _create_proto_info(*, srcs, deps, descriptor_set, proto_path = "", workspace_root = "", bin_dir = None, allow_exports = None):
"""Constructs ProtoInfo.
Args:
srcs: ([File]) List of .proto files (possibly under _virtual path)
deps: ([ProtoInfo]) List of dependencies
descriptor_set: (File) Descriptor set for this Proto
proto_path: (str) Path that should be stripped from files in srcs. When
stripping is needed, the files should be symlinked into `_virtual_imports/target_name`
directory. Only such paths are accepted.
workspace_root: (str) Set to ctx.workspace_root if this is not the main repository.
bin_dir: (str) Set to ctx.bin_dir if _virtual_imports are used.
allow_exports: (Target) The packages where this proto_library can be exported.
Returns:
(ProtoInfo)
"""
# Validate parameters
src_prefix = _join(workspace_root.replace("external/", "../"), proto_path)
for src in srcs:
if type(src) != "File":
fail("srcs parameter expects a list of Files")
if src.owner.workspace_root != workspace_root:
fail("srcs parameter expects all files to have the same workspace_root: ", workspace_root)
if not src.short_path.startswith(src_prefix):
fail("srcs parameter expects all files start with %s" % src_prefix)
if type(descriptor_set) != "File":
fail("descriptor_set parameter expected to be a File")
if proto_path:
if "_virtual_imports/" not in proto_path:
fail("proto_path needs to contain '_virtual_imports' directory")
if proto_path.split("/")[-2] != "_virtual_imports":
fail("proto_path needs to be formed like '_virtual_imports/target_name'")
if not bin_dir:
fail("bin_dir parameter should be set when _virtual_imports are used")
direct_proto_sources = srcs
transitive_proto_sources = depset(
direct = direct_proto_sources,
transitive = [dep._transitive_proto_sources for dep in deps],
order = "preorder",
)
transitive_sources = depset(
direct = srcs,
transitive = [dep.transitive_sources for dep in deps],
order = "preorder",
)
# There can be up more than 1 direct proto_paths, for example when there's
# a generated and non-generated .proto file in srcs
root_paths = _uniq([src.root.path for src in srcs])
transitive_proto_path = depset(
direct = [_empty_to_dot(_from_root(root, workspace_root, proto_path)) for root in root_paths],
transitive = [dep.transitive_proto_path for dep in deps],
)
if srcs:
check_deps_sources = depset(direct = srcs)
else:
check_deps_sources = depset(transitive = [dep.check_deps_sources for dep in deps])
transitive_descriptor_sets = depset(
direct = [descriptor_set],
transitive = [dep.transitive_descriptor_sets for dep in deps],
)
# Layering checks.
if srcs:
exported_sources = depset(direct = direct_proto_sources)
else:
exported_sources = depset(transitive = [dep._exported_sources for dep in deps])
if "_virtual_imports/" in proto_path:
#TODO: remove bin_dir from proto_source_root (when users assuming it's there are migrated)
proto_source_root = _empty_to_dot(_from_root(bin_dir, workspace_root, proto_path))
elif workspace_root.startswith("../"):
proto_source_root = proto_path
else:
proto_source_root = _empty_to_dot(_join(workspace_root, proto_path))
proto_info = dict(
direct_sources = srcs,
transitive_sources = transitive_sources,
direct_descriptor_set = descriptor_set,
transitive_descriptor_sets = transitive_descriptor_sets,
proto_source_root = proto_source_root,
transitive_proto_path = transitive_proto_path,
check_deps_sources = check_deps_sources,
transitive_imports = transitive_sources,
_direct_proto_sources = direct_proto_sources,
_transitive_proto_sources = transitive_proto_sources,
_exported_sources = exported_sources,
)
if allow_exports:
proto_info["allow_exports"] = allow_exports
return proto_info
ProtoInfo, _ = provider(
doc = "Encapsulates information provided by a `proto_library.`",
fields = {
"direct_sources": "(list[File]) The `.proto` source files from the `srcs` attribute.",
"transitive_sources": """(depset[File]) The `.proto` source files from this rule and all
its dependent protocol buffer rules.""",
"direct_descriptor_set": """(File) The descriptor set of the direct sources. If no srcs,
contains an empty file.""",
"transitive_descriptor_sets": """(depset[File]) A set of descriptor set files of all
dependent `proto_library` rules, and this one's. This is not the same as passing
--include_imports to proto-compiler. Will be empty if no dependencies.""",
"proto_source_root": """(str) The directory relative to which the `.proto` files defined in
the `proto_library` are defined. For example, if this is `a/b` and the rule has the
file `a/b/c/d.proto` as a source, that source file would be imported as
`import c/d.proto`
In principle, the `proto_source_root` directory itself should always
be relative to the output directory (`ctx.bin_dir`).
This is at the moment not true for `proto_libraries` using (additional and/or strip)
import prefixes. `proto_source_root` is in this case prefixed with the output
directory. For example, the value is similar to
`bazel-out/k8-fastbuild/bin/a/_virtual_includes/b` for an input file in
`a/_virtual_includes/b/c.proto` that should be imported as `c.proto`.
When using the value please account for both cases in a general way.
That is assume the value is either prefixed with the output directory or not.
This will make it possible to fix `proto_library` in the future.
""",
"transitive_proto_path": """(depset(str) A set of `proto_source_root`s collected from the
transitive closure of this rule.""",
"check_deps_sources": """(depset[File]) The `.proto` sources from the 'srcs' attribute.
If the library is a proxy library that has no sources, it contains the
`check_deps_sources` from this library's direct deps.""",
"allow_exports": """(Target) The packages where this proto_library can be exported.""",
# Deprecated fields:
"transitive_imports": """(depset[File]) Deprecated: use `transitive_sources` instead.""",
# Internal fields:
"_direct_proto_sources": """(list[File]) The `ProtoSourceInfo`s from the `srcs`
attribute.""" + _warning,
"_transitive_proto_sources": """(depset[File]) The `ProtoSourceInfo`s from this
rule and all its dependent protocol buffer rules.""" + _warning,
"_exported_sources": """(depset[File]) A set of `ProtoSourceInfo`s that may be
imported by another `proto_library` depending on this one.""" + _warning,
},
init = _create_proto_info,
)

@ -0,0 +1,155 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Implementation of the proto_lang_toolchain rule."""
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
def _rule_impl(ctx):
provided_proto_sources = depset(transitive = [bp[ProtoInfo]._transitive_proto_sources for bp in ctx.attr.blacklisted_protos]).to_list()
flag = ctx.attr.command_line
if flag.find("$(PLUGIN_OUT)") > -1:
fail("in attribute 'command_line': Placeholder '$(PLUGIN_OUT)' is not supported.")
flag = flag.replace("$(OUT)", "%s")
plugin = None
if ctx.attr.plugin != None:
plugin = ctx.attr.plugin[DefaultInfo].files_to_run
if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION:
proto_compiler = ctx.toolchains[toolchains.PROTO_TOOLCHAIN].proto.proto_compiler
protoc_opts = ctx.toolchains[toolchains.PROTO_TOOLCHAIN].proto.protoc_opts
else:
proto_compiler = ctx.attr._proto_compiler.files_to_run
protoc_opts = ctx.fragments.proto.experimental_protoc_opts
if ctx.attr.protoc_minimal_do_not_use:
proto_compiler = ctx.attr.protoc_minimal_do_not_use.files_to_run
proto_lang_toolchain_info = ProtoLangToolchainInfo(
out_replacement_format_flag = flag,
output_files = ctx.attr.output_files,
plugin_format_flag = ctx.attr.plugin_format_flag,
plugin = plugin,
runtime = ctx.attr.runtime,
provided_proto_sources = provided_proto_sources,
proto_compiler = proto_compiler,
protoc_opts = protoc_opts,
progress_message = ctx.attr.progress_message,
mnemonic = ctx.attr.mnemonic,
allowlist_different_package = ctx.attr.allowlist_different_package,
toolchain_type = ctx.attr.toolchain_type.label if ctx.attr.toolchain_type else None,
)
return [
DefaultInfo(files = depset(), runfiles = ctx.runfiles()),
platform_common.ToolchainInfo(proto = proto_lang_toolchain_info),
# TODO: remove when --incompatible_enable_proto_toolchains is flipped and removed
proto_lang_toolchain_info,
]
proto_lang_toolchain = rule(
_rule_impl,
doc = """
<p>If using Bazel, please load the rule from <a href="https://github.com/bazelbuild/rules_proto">
https://github.com/bazelbuild/rules_proto</a>.
<p>Specifies how a LANG_proto_library rule (e.g., <code>java_proto_library</code>) should invoke the
proto-compiler.
Some LANG_proto_library rules allow specifying which toolchain to use using command-line flags;
consult their documentation.
<p>Normally you should not write those kind of rules unless you want to
tune your Java compiler.
<p>There's no compiler. The proto-compiler is taken from the proto_library rule we attach to. It is
passed as a command-line flag to Blaze.
Several features require a proto-compiler to be invoked on the proto_library rule itself.
It's beneficial to enforce the compiler that LANG_proto_library uses is the same as the one
<code>proto_library</code> does.
<h4>Examples</h4>
<p>A simple example would be:
<pre><code class="lang-starlark">
proto_lang_toolchain(
name = "javalite_toolchain",
command_line = "--javalite_out=shared,immutable:$(OUT)",
plugin = ":javalite_plugin",
runtime = ":protobuf_lite",
)
</code></pre>
""",
attrs = {
"progress_message": attr.string(default = "Generating proto_library %{label}", doc = """
This value will be set as the progress message on protoc action."""),
"mnemonic": attr.string(default = "GenProto", doc = """
This value will be set as the mnemonic on protoc action."""),
"command_line": attr.string(mandatory = True, doc = """
This value will be passed to proto-compiler to generate the code. Only include the parts
specific to this code-generator/plugin (e.g., do not include -I parameters)
<ul>
<li><code>$(OUT)</code> is LANG_proto_library-specific. The rules are expected to define
how they interpret this variable. For Java, for example, $(OUT) will be replaced with
the src-jar filename to create.</li>
</ul>"""),
"output_files": attr.string(values = ["single", "multiple", "legacy"], default = "legacy", doc = """
Controls how <code>$(OUT)</code> in <code>command_line</code> is formatted, either by
a path to a single file or output directory in case of multiple files.
Possible values are: "single", "multiple"."""),
"plugin_format_flag": attr.string(doc = """
If provided, this value will be passed to proto-compiler to use the plugin.
The value must contain a single %s which is replaced with plugin executable.
<code>--plugin=protoc-gen-PLUGIN=&lt;executable&gt;.</code>"""),
"plugin": attr.label(
executable = True,
cfg = "exec",
doc = """
If provided, will be made available to the action that calls the proto-compiler, and will be
passed to the proto-compiler:
<code>--plugin=protoc-gen-PLUGIN=&lt;executable&gt;.</code>""",
),
"runtime": attr.label(doc = """
A language-specific library that the generated code is compiled against.
The exact behavior is LANG_proto_library-specific.
Java, for example, should compile against the runtime."""),
"blacklisted_protos": attr.label_list(
providers = [ProtoInfo],
doc = """
No code will be generated for files in the <code>srcs</code> attribute of
<code>blacklisted_protos</code>.
This is used for .proto files that are already linked into proto runtimes, such as
<code>any.proto</code>.""",
),
# TODO: add doc
"allowlist_different_package": attr.label(
cfg = "exec",
providers = [bazel_features.globals.PackageSpecificationInfo] if bazel_features.globals.PackageSpecificationInfo else [],
),
# TODO: add doc
"toolchain_type": attr.label(),
# DO NOT USE. For Protobuf incremental changes only: b/305068148.
"protoc_minimal_do_not_use": attr.label(
cfg = "exec",
executable = True,
),
} | ({} if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION else {
"_proto_compiler": attr.label(
cfg = "exec",
executable = True,
allow_files = True,
default = configuration_field("proto", "proto_compiler"),
),
}),
provides = [ProtoLangToolchainInfo],
fragments = ["proto"],
toolchains = toolchains.use_toolchain(toolchains.PROTO_TOOLCHAIN), # Used to obtain protoc
)

@ -1,13 +1,17 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""A Starlark implementation of the proto_toolchain rule."""
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
def _impl(ctx):
kwargs = {}
if getattr(proto_common, "INCOMPATIBLE_PASS_TOOLCHAIN_TYPE", False):
kwargs["toolchain_type"] = "@rules_proto//proto:toolchain_type"
return [
DefaultInfo(
files = depset(),
@ -23,7 +27,7 @@ def _impl(ctx):
protoc_opts = ctx.fragments.proto.experimental_protoc_opts,
progress_message = ctx.attr.progress_message,
mnemonic = ctx.attr.mnemonic,
**kwargs
**(dict(toolchain_type = toolchains.PROTO_TOOLCHAIN) if proto_common.INCOMPATIBLE_PASS_TOOLCHAIN_TYPE else {})
),
),
]

@ -0,0 +1,49 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""
Toolchain helpers.
The helpers here should be used for a migration to toolchain in proto rules.
Anybody that needs them in another repository should copy them, because after
the migration is finished, the helpers can be removed.
"""
load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo")
load("//bazel/private:native.bzl", "native_proto_common")
_incompatible_toolchain_resolution = getattr(native_proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False)
def _find_toolchain(ctx, legacy_attr, toolchain_type):
if _incompatible_toolchain_resolution:
toolchain = ctx.toolchains[toolchain_type]
if not toolchain:
fail("No toolchains registered for '%s'." % toolchain_type)
return toolchain.proto
else:
return getattr(ctx.attr, legacy_attr)[ProtoLangToolchainInfo]
def _use_toolchain(toolchain_type):
if _incompatible_toolchain_resolution:
return [config_common.toolchain_type(toolchain_type, mandatory = False)]
else:
return []
def _if_legacy_toolchain(legacy_attr_dict):
if _incompatible_toolchain_resolution:
return {}
else:
return legacy_attr_dict
toolchains = struct(
use_toolchain = _use_toolchain,
find_toolchain = _find_toolchain,
if_legacy_toolchain = _if_legacy_toolchain,
INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION = _incompatible_toolchain_resolution,
PROTO_TOOLCHAIN = Label("//bazel/private:proto_toolchain_type"),
)

@ -0,0 +1,85 @@
load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain")
load("//bazel/toolchains:proto_toolchain.bzl", "proto_toolchain")
# Keep this file as small as possible and free of any unnecessary loads
# It is loaded by every use of protobuf repository, and loads here can force
# fetching of additional external repositories
# It's also intentionally using toolchain instead of proto_lang_toolchain,
# because the former does not resolve dependencies until toolchain resolution
# needs them
proto_toolchain(
name = "protoc_sources",
exec_compatible_with = [],
proto_compiler = "//:protoc",
)
toolchain(
name = "cc_source_toolchain",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//:cc_toolchain",
toolchain_type = "//bazel/private:cc_toolchain_type",
)
toolchain(
name = "java_source_toolchain",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//java/core:toolchain",
toolchain_type = "//bazel/private:java_toolchain_type",
)
toolchain(
name = "javalite_source_toolchain",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//java/lite:toolchain",
toolchain_type = "//bazel/private:javalite_toolchain_type",
)
toolchain(
name = "python_source_toolchain",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//python:python_toolchain",
toolchain_type = "//bazel/private:python_toolchain_type",
)
# Following toolchain registrations are for builtin Bazel 7 rules
# which defined them in other repositories.
toolchain(
name = "cc_source_toolchain_bazel7",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//:cc_toolchain",
toolchain_type = "@rules_cc//cc/proto:toolchain_type",
)
toolchain(
name = "java_source_toolchain_bazel7",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//java/core:toolchain",
toolchain_type = "@rules_java//java/proto:toolchain_type",
)
toolchain(
name = "javalite_source_toolchain_bazel7",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = "//java/lite:toolchain",
toolchain_type = "@rules_java//java/proto:lite_toolchain_type",
)
filegroup(
name = "for_bazel_tests",
testonly = True,
srcs = [
"BUILD.bazel",
],
visibility = [
"//bazel/private:__pkg__",
],
)

@ -1,23 +1,18 @@
"""Implementation of the aspect that powers the upb_*_proto_library() rules."""
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load(":upb_proto_library_internal/cc_library_func.bzl", "cc_library_func")
load(":upb_proto_library_internal/copts.bzl", "UpbProtoLibraryCoptsInfo")
# begin:github_only
_is_google3 = False
# end:github_only
# begin:google_only
# _is_google3 = True
# end:google_only
GeneratedSrcsInfo = provider(
"Provides generated headers and sources",
fields = {
"srcs": "list of srcs",
"hdrs": "list of hdrs",
"thunks": "Experimental, do not use. List of srcs defining C API. Incompatible with hdrs.",
},
)
@ -51,16 +46,58 @@ def _merge_generated_srcs(srcs):
return GeneratedSrcsInfo(
srcs = _concat_lists([s.srcs for s in srcs]),
hdrs = _concat_lists([s.hdrs for s in srcs]),
thunks = _concat_lists([s.thunks for s in srcs]),
)
def _generate_upb_protos(ctx, generator, proto_info):
def _get_implicit_weak_field_sources(ctx, proto_info):
# Creating one .cc file for each Message in a proto allows the linker to be more aggressive
# about removing unused classes. However, since the number of outputs won't be known at Blaze
# analysis time, all of the generated source files are put in a directory and a TreeArtifact is
# used to represent them.
proto_artifacts = []
for proto_source in proto_info.direct_sources:
# We can have slashes in the target name. For example, proto_source can be:
# dir/a.proto. However proto_source.basename will return a.proto, when in reality
# the BUILD file declares it as dir/a.proto, because target name contains a slash.
# There is no good workaround for this.
# I am using ctx.label.package to check if the name of the target contains slash or not.
# This is similar to what declare_directory does.
if not proto_source.short_path.startswith(ctx.label.package):
fail("This should never happen, proto source {} path does not start with {}.".format(
proto_source.short_path,
ctx.label.package,
))
proto_source_name = proto_source.short_path[len(ctx.label.package) + 1:]
last_dot = proto_source_name.rfind(".")
if last_dot != -1:
proto_source_name = proto_source_name[:last_dot]
proto_artifacts.append(ctx.actions.declare_directory(proto_source_name + ".upb_weak_minitables"))
return proto_artifacts
def _get_feature_configuration(ctx, cc_toolchain, proto_info):
requested_features = list(ctx.features)
# Disable the whole-archive behavior for protobuf generated code when the
# proto_one_output_per_message feature is enabled.
requested_features.append("disable_whole_archive_for_static_lib_if_proto_one_output_per_message")
unsupported_features = list(ctx.disabled_features)
if len(proto_info.direct_sources) != 0:
requested_features.append("header_modules")
else:
unsupported_features.append("header_modules")
return cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = requested_features,
unsupported_features = unsupported_features,
)
def _generate_srcs_list(ctx, generator, proto_info):
if len(proto_info.direct_sources) == 0:
return GeneratedSrcsInfo(srcs = [], hdrs = [], thunks = [], includes = [])
return GeneratedSrcsInfo(srcs = [], hdrs = [], includes = [])
ext = "." + generator
srcs = []
thunks = []
hdrs = proto_common.declare_generated_files(
ctx.actions,
extension = ext + ".h",
@ -75,40 +112,37 @@ def _generate_upb_protos(ctx, generator, proto_info):
extension = ext + ".c",
proto_info = proto_info,
)
if generator == "upb":
thunks = proto_common.declare_generated_files(
ctx.actions,
extension = ext + ".thunks.c",
proto_info = proto_info,
)
ctx.actions.run_shell(
inputs = hdrs,
outputs = thunks,
command = " && ".join([
"sed 's/UPB_INLINE //' {} > {}".format(hdr.path, thunk.path)
for (hdr, thunk) in zip(hdrs, thunks)
]),
progress_message = "Generating thunks for upb protos API for: " + ctx.label.name,
mnemonic = "GenUpbProtosThunks",
)
return GeneratedSrcsInfo(
srcs = srcs,
hdrs = hdrs,
)
def _generate_upb_protos(ctx, generator, proto_info, feature_configuration):
implicit_weak = generator == "upb_minitable" and cc_common.is_enabled(
feature_configuration = feature_configuration,
feature_name = "proto_one_output_per_message",
)
srcs = _generate_srcs_list(ctx, generator, proto_info)
additional_args = ctx.actions.args()
if implicit_weak:
srcs.srcs.extend(_get_implicit_weak_field_sources(ctx, proto_info))
additional_args.add("--upb_minitable_opt=one_output_per_message")
proto_common.compile(
actions = ctx.actions,
proto_info = proto_info,
proto_lang_toolchain_info = _get_lang_toolchain(ctx, generator),
generated_files = srcs + hdrs,
generated_files = srcs.srcs + srcs.hdrs,
experimental_exec_group = "proto_compiler",
additional_args = additional_args,
)
return GeneratedSrcsInfo(
srcs = srcs,
hdrs = hdrs,
thunks = thunks,
)
return srcs
def _generate_name(ctx, generator, thunks = False):
if thunks:
return ctx.rule.attr.name + "." + generator + ".thunks"
def _generate_name(ctx, generator):
return ctx.rule.attr.name + "." + generator
def _get_dep_cc_infos(target, ctx, generator, cc_provider, dep_cc_provider):
@ -139,24 +173,9 @@ def _compile_upb_protos(ctx, files, generator, dep_ccinfos, cc_provider, proto_i
dep_ccinfos = dep_ccinfos,
)
if files.thunks:
cc_info_with_thunks = cc_library_func(
ctx = ctx,
name = _generate_name(ctx, generator, files.thunks),
hdrs = [],
srcs = files.thunks,
includes = [output_dir(ctx, proto_info)],
copts = ctx.attr._copts[UpbProtoLibraryCoptsInfo].copts,
dep_ccinfos = dep_ccinfos + [cc_info],
)
return cc_provider(
cc_info = cc_info,
cc_info_with_thunks = cc_info_with_thunks,
)
else:
return cc_provider(
cc_info = cc_info,
)
return cc_provider(
cc_info = cc_info,
)
_GENERATORS = ["upb", "upbdefs", "upb_minitable"]
@ -167,7 +186,6 @@ def _get_hint_providers(ctx, generator):
possible_owners = []
for generator in _GENERATORS:
possible_owners.append(ctx.label.relative(_generate_name(ctx, generator)))
possible_owners.append(ctx.label.relative(_generate_name(ctx, generator, thunks = True)))
if hasattr(cc_common, "CcSharedLibraryHintInfo"):
return [cc_common.CcSharedLibraryHintInfo(owners = possible_owners)]
@ -196,7 +214,7 @@ def upb_proto_aspect_impl(
`cc_info` field. The aspect will ensure that each compilation action can compile and link
against this provider's cc_info for all proto_library() deps.
dep_cc_provider: For aspects that depend on other aspects, this is the provider of the aspect
that we depend on. The aspect wil be able to include the header files from this provider.
that we depend on. The aspect will be able to include the header files from this provider.
file_provider: A provider that this aspect will attach to the target to expose the source
files generated by this aspect. These files are primarily useful for returning in
DefaultInfo(), so users who build the upb_*proto_library() rule directly can view the
@ -210,17 +228,20 @@ def upb_proto_aspect_impl(
if not getattr(ctx.rule.attr, "srcs", []):
# This target doesn't declare any sources, reexport all its deps instead.
# This is known as an "alias library":
# https://bazel.build/reference/be/protocol-buffer#proto_library.srcs
# https://bazel.build/versions/6.4.0/reference/be/protocol-buffer#proto_library.srcs
files = _merge_generated_srcs([dep[file_provider].srcs for dep in ctx.rule.attr.deps])
wrapped_cc_info = cc_provider(
cc_info = cc_common.merge_cc_infos(direct_cc_infos = dep_ccinfos),
)
else:
proto_info = target[ProtoInfo]
cc_toolchain = find_cpp_toolchain(ctx)
feature_configuration = _get_feature_configuration(ctx, cc_toolchain, proto_info)
files = _generate_upb_protos(
ctx,
generator,
proto_info,
feature_configuration,
)
wrapped_cc_info = _compile_upb_protos(
ctx,

@ -1,28 +1,11 @@
"""A function to compile C/C++ code, like cc_library() but from Starlark."""
# begin:google_only
# load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
#
# def upb_use_cpp_toolchain():
# return [
# config_common.toolchain_type(
# "@bazel_tools//tools/cpp:cc_runtimes_toolchain_type",
# mandatory = False,
# ),
# ] + use_cpp_toolchain()
#
# end:google_only
# begin:github_only
# Compatibility code for Bazel 4.x. Remove this when we drop support for Bazel 4.x.
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
def upb_use_cpp_toolchain():
return ["@bazel_tools//tools/cpp:toolchain_type"]
# end:github_only
return use_cpp_toolchain()
def cc_library_func(ctx, name, hdrs, srcs, copts, includes, dep_ccinfos):
def cc_library_func(ctx, name, hdrs, srcs, copts, dep_ccinfos, includes = []):
"""Like cc_library(), but callable from rules.
Args:
@ -31,23 +14,13 @@ def cc_library_func(ctx, name, hdrs, srcs, copts, includes, dep_ccinfos):
hdrs: Public headers that can be #included from other rules.
srcs: C/C++ source files.
copts: Additional options for cc compilation.
includes: Additional include paths.
dep_ccinfos: CcInfo providers of dependencies we should build/link against.
includes: Additional include paths.
Returns:
CcInfo provider for this compilation.
"""
# begin:google_only
# cc_runtimes_toolchain = ctx.toolchains["@bazel_tools//tools/cpp:cc_runtimes_toolchain_type"]
# if cc_runtimes_toolchain:
# dep_ccinfos += [
# target[CcInfo]
# for target in cc_runtimes_toolchain.cc_runtimes_info.runtimes
# ]
#
# end:google_only
compilation_contexts = [info.compilation_context for info in dep_ccinfos]
linking_contexts = [info.linking_context for info in dep_ccinfos]
toolchain = find_cpp_toolchain(ctx)

@ -1,3 +1,20 @@
"""proto_library rule"""
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""
Macro of proto_library rule.
"""
proto_library = native.proto_library
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/private:bazel_proto_library_rule.bzl", _proto_library = "proto_library")
def proto_library(**kwattrs):
# This condition causes Starlark rules to be used only on Bazel >=7.0.0
if bazel_features.proto.starlark_proto_info:
_proto_library(**kwattrs)
else:
# On older Bazel versions keep using native rules, so that mismatch in ProtoInfo doesn't happen
native.proto_library(**kwattrs)

@ -3,8 +3,9 @@
load("@rules_python//python:py_info.bzl", "PyInfo")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
_PY_PROTO_TOOLCHAIN = Label("//bazel/private:python_toolchain_type")
_PyProtoInfo = provider(
doc = "Encapsulates information needed by the Python proto rules.",
@ -48,7 +49,14 @@ def _py_proto_aspect_impl(target, ctx):
proto.path,
))
proto_lang_toolchain_info = ctx.attr._aspect_proto_toolchain[ProtoLangToolchainInfo]
if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION:
toolchain = ctx.toolchains[_PY_PROTO_TOOLCHAIN]
if not toolchain:
fail("No toolchains registered for '%s'." % _PY_PROTO_TOOLCHAIN)
proto_lang_toolchain_info = toolchain.proto
else:
proto_lang_toolchain_info = getattr(ctx.attr, "_aspect_proto_toolchain")[proto_common.ProtoLangToolchainInfo]
api_deps = [proto_lang_toolchain_info.runtime]
generated_sources = []
@ -110,14 +118,15 @@ def _py_proto_aspect_impl(target, ctx):
_py_proto_aspect = aspect(
implementation = _py_proto_aspect_impl,
attrs = {
attrs = toolchains.if_legacy_toolchain({
"_aspect_proto_toolchain": attr.label(
default = "//python:python_toolchain",
),
},
}),
attr_aspects = ["deps"],
required_providers = [ProtoInfo],
provides = [_PyProtoInfo],
toolchains = toolchains.use_toolchain(_PY_PROTO_TOOLCHAIN),
)
def _py_proto_library_rule(ctx):

@ -0,0 +1,5 @@
load(":proto_common_compile_tests.bzl", "proto_common_compile_test_suite")
package(default_applicable_licenses = ["//:license"])
proto_common_compile_test_suite(name = "proto_common_compile_test_suite")

@ -0,0 +1,368 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Tests for `proto_common.compile` function."""
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
load("@rules_testing//lib:truth.bzl", "matching")
load("@rules_testing//lib:util.bzl", "util")
load("//bazel:proto_library.bzl", "proto_library")
load("//bazel/tests/testdata:compile_rule.bzl", "compile_rule")
protocol_compiler = "/protoc"
def proto_common_compile_test_suite(name):
util.helper_target(
proto_library,
name = "simple_proto",
srcs = ["A.proto"],
)
test_suite(
name = name,
tests = [
_test_compile_basic,
_test_compile_noplugin,
_test_compile_with_plugin_output,
_test_compile_with_directory_plugin_output,
_test_compile_additional_args,
_test_compile_additional_tools,
_test_compile_additional_tools_no_plugin,
_test_compile_additional_inputs,
_test_compile_resource_set,
_test_compile_protoc_opts,
_test_compile_direct_generated_protos,
_test_compile_indirect_generated_protos,
],
)
# Verifies basic usage of `proto_common.compile`.
def _test_compile_basic(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_basic_impl,
)
def _test_compile_basic_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
action.mnemonic().equals("MyMnemonic")
# Verifies usage of proto_common.generate_code with no plugin specified by toolchain.
def _test_compile_noplugin(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
toolchain = "//bazel/tests/testdata:toolchain_noplugin",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_noplugin_impl,
)
def _test_compile_noplugin_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
# Verifies usage of `proto_common.compile` with `plugin_output` parameter set to file.
def _test_compile_with_plugin_output(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
plugin_output = "single",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_with_plugin_output_impl,
)
def _test_compile_with_plugin_output_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.str_matches("--java_out=param1,param2:b*-out/*/test_compile_with_plugin_output_compile"),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
# Verifies usage of `proto_common.compile` with `plugin_output` parameter set to file.
def _test_compile_with_directory_plugin_output(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
plugin_output = "multiple",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_with_directory_plugin_output_impl,
)
def _test_compile_with_directory_plugin_output_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.str_matches("--java_out=param1,param2:b*-out/*/bin"),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
# Verifies usage of `proto_common.compile` with `additional_args` parameter
def _test_compile_additional_args(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
additional_args = ["--a", "--b"],
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_additional_args_impl,
)
def _test_compile_additional_args_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.equals_wrapper("--a"),
matching.equals_wrapper("--b"),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
# Verifies usage of `proto_common.compile` with `additional_tools` parameter
def _test_compile_additional_tools(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
additional_tools = [
"//bazel/tests/testdata:_tool1",
"//bazel/tests/testdata:_tool2",
],
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_additional_tools_impl,
)
def _test_compile_additional_tools_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.inputs().contains_at_least_predicates(
[
matching.file_basename_equals("_tool1"),
matching.file_basename_equals("_tool2"),
matching.file_basename_equals("plugin"),
],
)
# Verifies usage of `proto_common.compile` with `additional_tools` parameter and no plugin on the toolchain.
def _test_compile_additional_tools_no_plugin(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
additional_tools = [
"//bazel/tests/testdata:_tool1",
"//bazel/tests/testdata:_tool2",
],
toolchain = "//bazel/tests/testdata:toolchain_noplugin",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_additional_tools_no_plugin_impl,
)
def _test_compile_additional_tools_no_plugin_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.inputs().contains_at_least_predicates(
[
matching.file_basename_equals("_tool1"),
matching.file_basename_equals("_tool2"),
],
)
action.inputs().not_contains_predicate(matching.file_basename_equals("plugin"))
# Verifies usage of `proto_common.compile` with `additional_inputs` parameter.
def _test_compile_additional_inputs(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
additional_inputs = ["input1.txt", "input2.txt"],
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_additional_inputs_impl,
)
def _test_compile_additional_inputs_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.inputs().contains_at_least_predicates(
[
matching.file_basename_equals("input1.txt"),
matching.file_basename_equals("input2.txt"),
],
)
# Verifies usage of `proto_common.compile` with `additional_tools` parameter and no plugin on the toolchain.
def _test_compile_resource_set(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
use_resource_set = True,
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_resource_set_impl,
)
def _test_compile_resource_set_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic") # @unused
# We can't check the specification of the resource set, but we at least verify analysis passes
# Verifies `--protocopts` are passed to command line.
def _test_compile_protoc_opts(name):
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = ":simple_proto",
)
analysis_test(
name = name,
target = name + "_compile",
config_settings = {"//command_line_option:protocopt": ["--foo", "--bar"]},
impl = _test_compile_protoc_opts_impl,
)
def _test_compile_protoc_opts_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.equals_wrapper("--foo"),
matching.equals_wrapper("--bar"),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)
# Verifies `proto_common.compile`> correctly handles direct generated `.proto` files.
def _test_compile_direct_generated_protos(name):
util.helper_target(native.genrule, name = name + "_generate_G", cmd = "", outs = ["G.proto"])
util.helper_target(
proto_library,
name = name + "_directly_generated_proto",
srcs = ["A.proto", "G.proto"],
)
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = name + "_directly_generated_proto",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_direct_generated_protos_impl,
)
def _test_compile_direct_generated_protos_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.str_matches("-Ib*-out/*/*"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
matching.str_matches("*-out/*/*/*/G.proto"),
],
)
# Verifies usage of `proto_common.compile` with `plugin_output` parameter
def _test_compile_indirect_generated_protos(name):
util.helper_target(native.genrule, name = "_generate_h", srcs = ["A.txt"], cmd = "", outs = ["H.proto"])
util.helper_target(proto_library, name = "_generated_proto", srcs = ["H.proto"])
util.helper_target(
proto_library,
name = name + "_indirectly_generated_proto",
srcs = ["A.proto"],
deps = [":_generated_proto"],
)
util.helper_target(
compile_rule,
name = name + "_compile",
proto_dep = name + "_indirectly_generated_proto",
)
analysis_test(
name = name,
target = name + "_compile",
impl = _test_compile_indirect_generated_protos_impl,
)
def _test_compile_indirect_generated_protos_impl(env, target):
action = env.expect.that_target(target).action_named("MyMnemonic")
action.argv().contains_exactly_predicates(
[
matching.str_endswith(protocol_compiler),
matching.str_matches("--plugin=b*-out/*-exec-*/bin/*/testdata/plugin"),
matching.str_matches("-Ib*-out/*/*"),
matching.equals_wrapper("-I."),
matching.str_endswith("/A.proto"),
],
)

@ -0,0 +1,136 @@
load("//bazel:proto_library.bzl", "proto_library")
load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain")
package(
default_applicable_licenses = ["//:license"],
default_visibility = ["//visibility:public"],
)
proto_lang_toolchain(
name = "toolchain",
blacklisted_protos = [":denied"],
command_line = "--java_out=param1,param2:$(OUT)",
mnemonic = "MyMnemonic",
plugin = ":plugin",
plugin_format_flag = "--plugin=%s",
progress_message = "Progress Message %{label}",
runtime = ":runtime",
tags = [
"manual",
"nobuilder",
"notap",
],
)
proto_lang_toolchain(
name = "toolchain_noplugin",
blacklisted_protos = [":denied"],
command_line = "--java_out=param1,param2:$(OUT)",
mnemonic = "MyMnemonic",
progress_message = "Progress Message %{label}",
runtime = ":runtime",
tags = [
"manual",
"nobuilder",
"notap",
],
)
cc_binary(
name = "plugin",
srcs = ["plugin.cc"],
tags = [
"manual",
"nobuilder",
"notap",
],
)
cc_library(
name = "runtime",
srcs = ["runtime.cc"],
tags = [
"manual",
"nobuilder",
"notap",
],
)
filegroup(
name = "descriptors",
srcs = [
"descriptor.proto",
"metadata.proto",
],
tags = [
"manual",
"nobuilder",
"notap",
],
)
filegroup(
name = "any",
srcs = ["any.proto"],
tags = [
"manual",
"nobuilder",
"notap",
],
)
filegroup(
name = "something",
srcs = ["something.proto"],
tags = [
"manual",
"nobuilder",
"notap",
],
)
proto_library(
name = "mixed",
srcs = [
":descriptors",
":something",
],
tags = [
"manual",
"nobuilder",
"notap",
],
)
proto_library(
name = "denied",
srcs = [
":any",
":descriptors",
],
tags = [
"manual",
"nobuilder",
"notap",
],
)
cc_binary(
name = "_tool1",
srcs = ["tool1.cc"],
tags = [
"manual",
"nobuilder",
"notap",
],
)
cc_binary(
name = "_tool2",
srcs = ["tool2.cc"],
tags = [
"manual",
"nobuilder",
"notap",
],
)

@ -0,0 +1,57 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Testing function for proto_common module"""
load("//bazel/common:proto_common.bzl", "proto_common")
def _resource_set_callback(_os, inputs_size):
return {"memory": 25 + 0.15 * inputs_size, "cpu": 1}
def _impl(ctx):
outfile = ctx.actions.declare_file(ctx.attr.name)
kwargs = {}
if ctx.attr.plugin_output == "single":
kwargs["plugin_output"] = outfile.path
elif ctx.attr.plugin_output == "multiple":
kwargs["plugin_output"] = ctx.bin_dir.path
elif ctx.attr.plugin_output == "wrong":
kwargs["plugin_output"] = ctx.bin_dir.path + "///"
if ctx.attr.additional_args:
additional_args = ctx.actions.args()
additional_args.add_all(ctx.attr.additional_args)
kwargs["additional_args"] = additional_args
if ctx.files.additional_tools:
kwargs["additional_tools"] = ctx.files.additional_tools
if ctx.files.additional_inputs:
kwargs["additional_inputs"] = depset(ctx.files.additional_inputs)
if ctx.attr.use_resource_set:
kwargs["resource_set"] = _resource_set_callback
if ctx.attr.progress_message:
kwargs["experimental_progress_message"] = ctx.attr.progress_message
proto_common.compile(
ctx.actions,
ctx.attr.proto_dep[ProtoInfo],
ctx.attr.toolchain[proto_common.ProtoLangToolchainInfo],
[outfile],
**kwargs
)
return [DefaultInfo(files = depset([outfile]))]
compile_rule = rule(
_impl,
attrs = {
"proto_dep": attr.label(),
"plugin_output": attr.string(),
"toolchain": attr.label(default = ":toolchain"),
"additional_args": attr.string_list(),
"additional_tools": attr.label_list(cfg = "exec"),
"additional_inputs": attr.label_list(allow_files = True),
"use_resource_set": attr.bool(),
"progress_message": attr.string(),
},
)

@ -1,5 +1,7 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
package(default_applicable_licenses = ["//:license"])
bzl_library(
name = "proto_toolchain_bzl",
srcs = [
@ -8,6 +10,7 @@ bzl_library(
visibility = ["//visibility:public"],
deps = [
"//bazel/private:proto_toolchain_rule_bzl",
"//bazel/private:toolchain_helpers_bzl",
],
)
@ -19,5 +22,20 @@ bzl_library(
visibility = ["//visibility:public"],
deps = [
"//bazel/common:proto_common_bzl",
"//bazel/private:proto_lang_toolchain_rule_bzl",
"@proto_bazel_features//:features",
],
)
filegroup(
name = "for_bazel_tests",
testonly = True,
srcs = [
"BUILD",
"proto_lang_toolchain_bzl",
"proto_toolchain_bzl",
],
visibility = [
"//bazel:__pkg__",
],
)

@ -1,6 +1,15 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""proto_lang_toolchain rule"""
load("@proto_bazel_features//:features.bzl", "bazel_features")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/private:proto_lang_toolchain_rule.bzl", _proto_lang_toolchain_rule = "proto_lang_toolchain")
def proto_lang_toolchain(*, name, toolchain_type = None, exec_compatible_with = [], target_compatible_with = [], **attrs):
"""Creates a proto_lang_toolchain and corresponding toolchain target.
@ -21,8 +30,12 @@ def proto_lang_toolchain(*, name, toolchain_type = None, exec_compatible_with =
if getattr(proto_common, "INCOMPATIBLE_PASS_TOOLCHAIN_TYPE", False):
attrs["toolchain_type"] = toolchain_type
# buildifier: disable=native-proto
native.proto_lang_toolchain(name = name, **attrs)
# This condition causes Starlark rules to be used only on Bazel >=7.0.0
if bazel_features.proto.starlark_proto_info:
_proto_lang_toolchain_rule(name = name, **attrs)
else:
# On older Bazel versions keep using native rules, so that mismatch in ProtoInfo doesn't happen
native.proto_lang_toolchain(name = name, **attrs)
if toolchain_type:
native.toolchain(

@ -1,9 +1,17 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2024 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
#
"""Macro wrapping the proto_toolchain implementation.
The macro additionally creates toolchain target when toolchain_type is given.
"""
load("//bazel/private:proto_toolchain_rule.bzl", _proto_toolchain_rule = "proto_toolchain")
load("//bazel/private:toolchain_helpers.bzl", "toolchains")
def proto_toolchain(*, name, proto_compiler, exec_compatible_with = []):
"""Creates a proto_toolchain and toolchain target for proto_library.
@ -19,7 +27,7 @@ def proto_toolchain(*, name, proto_compiler, exec_compatible_with = []):
native.toolchain(
name = name + "_toolchain",
toolchain_type = "@rules_proto//proto:toolchain_type",
toolchain_type = toolchains.PROTO_TOOLCHAIN,
exec_compatible_with = exec_compatible_with,
target_compatible_with = [],
toolchain = name,

@ -1,13 +1,14 @@
"""upb_c_proto_library() exposes upb's generated C API for protobuf (foo.upb.h)"""
load("//bazel:upb_minitable_proto_library.bzl", "UpbMinitableCcInfo", "upb_minitable_proto_library_aspect")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:upb_proto_library_internal/aspect.bzl", "upb_proto_aspect_impl")
load("//bazel/private:upb_proto_library_internal/cc_library_func.bzl", "upb_use_cpp_toolchain")
load("//bazel/private:upb_proto_library_internal/rule.bzl", "upb_proto_rule_impl")
UpbWrappedCcInfo = provider(
"Provider for cc_info for protos",
fields = ["cc_info", "cc_info_with_thunks"],
fields = ["cc_info"],
)
_UpbWrappedGeneratedSrcsInfo = provider(
@ -32,7 +33,7 @@ upb_c_proto_library_aspect = aspect(
default = "//upb:upb_proto_library_copts__for_generated_code_only_do_not_use",
),
"_upb_toolchain": attr.label(
default = Label("//upb_generator:protoc-gen-upb_toolchain"),
default = Label("//upb_generator/c:toolchain"),
),
"_cc_toolchain": attr.label(
default = "@bazel_tools//tools/cpp:current_cc_toolchain",

@ -1,5 +1,6 @@
"""upb_minitable_proto_library() exposes upb's generated minitables (foo.upb_minitable.h)"""
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:upb_proto_library_internal/aspect.bzl", "upb_proto_aspect_impl")
load("//bazel/private:upb_proto_library_internal/cc_library_func.bzl", "upb_use_cpp_toolchain")
load("//bazel/private:upb_proto_library_internal/rule.bzl", "upb_proto_rule_impl")
@ -44,7 +45,7 @@ upb_minitable_proto_library_aspect = aspect(
default = "//upb:upb_proto_library_copts__for_generated_code_only_do_not_use",
),
"_upb_minitable_toolchain": attr.label(
default = Label("//upb_generator:protoc-gen-upb_minitable_toolchain"),
default = Label("//upb_generator/minitable:toolchain"),
),
"_cc_toolchain": attr.label(
default = "@bazel_tools//tools/cpp:current_cc_toolchain",

@ -1,6 +1,8 @@
"""upb_c_proto_reflection_library() exposes upb reflection for protobuf (foo.upbdefs.h)"""
load("//bazel:upb_minitable_proto_library.bzl", "UpbMinitableCcInfo", "upb_minitable_proto_library_aspect")
load("//bazel/common:proto_common.bzl", "proto_common")
load("//bazel/common:proto_info.bzl", "ProtoInfo")
load("//bazel/private:upb_proto_library_internal/aspect.bzl", "upb_proto_aspect_impl")
load("//bazel/private:upb_proto_library_internal/cc_library_func.bzl", "upb_use_cpp_toolchain")
load("//bazel/private:upb_proto_library_internal/rule.bzl", "upb_proto_rule_impl")
@ -29,7 +31,7 @@ _upb_proto_reflection_library_aspect = aspect(
default = "//upb:upb_proto_library_copts__for_generated_code_only_do_not_use",
),
"_upbdefs_toolchain": attr.label(
default = Label("//upb_generator:protoc-gen-upbdefs_toolchain"),
default = Label("//upb_generator/reflection:toolchain"),
cfg = getattr(proto_common, "proto_lang_toolchain_cfg", "target"),
),
"_cc_toolchain": attr.label(

@ -20,9 +20,7 @@ load(
"tmpl_cc_binary",
)
# begin:google_only
# package(default_applicable_licenses = ["//upb:license"])
# end:google_only
package(default_applicable_licenses = ["//:license"])
licenses(["notice"])
@ -74,7 +72,6 @@ cc_test(
"//:protobuf",
"//src/google/protobuf/json",
"//upb:base",
"//upb:descriptor_upb_proto",
"//upb:json",
"//upb:mem",
"//upb:reflection",
@ -238,7 +235,7 @@ genrule(
),
outs = ["size_data.txt"],
# We want --format=GNU which counts rodata with data, not text.
cmd = "size $$($$OSTYPE == 'linux-gnu' ? '--format=GNU -d' : '') $(SRCS) > $@",
cmd = "size $$([ $$OSTYPE == 'linux-gnu' ] && echo '--format=GNU -d' || echo '') $(SRCS) > $@",
# "size" sometimes isn't available remotely.
local = 1,
tags = ["no-remote-exec"],

@ -29,7 +29,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
load(
"@protobuf//bazel:proto_library.bzl",
"@com_google_protobuf//bazel:proto_library.bzl",
"proto_library",
)

@ -8,13 +8,7 @@
load("//bazel:cc_proto_library.bzl", "cc_proto_library")
load("//bazel:proto_library.bzl", "proto_library")
# begin:google_only
# _is_google3 = True
# end:google_only
# begin:github_only
_is_google3 = False
# end:github_only
def tmpl_cc_binary(name, gen, args, replacements = [], **kwargs):
srcs = [name + ".cc"]
@ -26,7 +20,7 @@ def tmpl_cc_binary(name, gen, args, replacements = [], **kwargs):
)
if _is_google3:
kwargs["malloc"] = "//base:system_malloc"
kwargs["malloc"] = "@bazel_tools//tools/cpp:malloc"
kwargs["features"] = ["-static_linking_mode"]
native.cc_binary(
name = name,

@ -22,7 +22,6 @@ option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
option cc_enable_arenas = true;
// The protocol compiler can output a FileDescriptorSet containing the .proto
// files it parses.
@ -34,13 +33,16 @@ message FileDescriptorSet {
message FileDescriptorProto {
optional string name = 1
[ctype = STRING_PIECE]; // file name, relative to root of source tree
optional string package = 2
[ctype = STRING_PIECE]; // e.g. "foo", "foo.bar", etc.
// Names of files imported by this file.
repeated string dependency = 3 [ctype = STRING_PIECE];
// Indexes of the public imported files in the dependency list above.
repeated int32 public_dependency = 10;
// Indexes of the weak imported files in the dependency list.
// For Google-internal migration only. Do not use.
repeated int32 weak_dependency = 11;
@ -50,7 +52,6 @@ message FileDescriptorProto {
repeated EnumDescriptorProto enum_type = 5;
repeated ServiceDescriptorProto service = 6;
repeated FieldDescriptorProto extension = 7;
optional FileOptions options = 8;
// This field contains optional information about the original source code.
@ -70,20 +71,17 @@ message DescriptorProto {
repeated FieldDescriptorProto field = 2;
repeated FieldDescriptorProto extension = 6;
repeated DescriptorProto nested_type = 3;
repeated EnumDescriptorProto enum_type = 4;
message ExtensionRange {
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Exclusive.
optional ExtensionRangeOptions options = 3;
}
repeated ExtensionRange extension_range = 5;
repeated ExtensionRange extension_range = 5;
repeated OneofDescriptorProto oneof_decl = 8;
optional MessageOptions options = 7;
// Range of reserved tag numbers. Reserved tag numbers may not be used by
@ -93,7 +91,9 @@ message DescriptorProto {
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Exclusive.
}
repeated ReservedRange reserved_range = 9;
// Reserved field names, which may not be used by fields in the same message.
// A given name may only be reserved once.
repeated string reserved_name = 10 [ctype = STRING_PIECE];
@ -114,10 +114,12 @@ message FieldDescriptorProto {
// Order is weird for historical reasons.
TYPE_DOUBLE = 1;
TYPE_FLOAT = 2;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
// negative values are likely.
TYPE_INT64 = 3;
TYPE_UINT64 = 4;
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
// negative values are likely.
TYPE_INT32 = 5;
@ -125,6 +127,7 @@ message FieldDescriptorProto {
TYPE_FIXED32 = 7;
TYPE_BOOL = 8;
TYPE_STRING = 9;
// Tag-delimited aggregate.
// Group type is deprecated and not supported in proto3. However, Proto3
// implementations should still be able to parse the group wire format and
@ -150,6 +153,7 @@ message FieldDescriptorProto {
}
optional string name = 1 [ctype = STRING_PIECE];
optional int32 number = 3;
optional Label label = 4;
@ -214,6 +218,7 @@ message FieldDescriptorProto {
// Describes a oneof.
message OneofDescriptorProto {
optional string name = 1 [ctype = STRING_PIECE];
optional OneofOptions options = 2;
}
@ -222,7 +227,6 @@ message EnumDescriptorProto {
optional string name = 1 [ctype = STRING_PIECE];
repeated EnumValueDescriptorProto value = 2;
optional EnumOptions options = 3;
// Range of reserved numeric values. Reserved values may not be used by
@ -249,16 +253,16 @@ message EnumDescriptorProto {
// Describes a value within an enum.
message EnumValueDescriptorProto {
optional string name = 1 [ctype = STRING_PIECE];
optional int32 number = 2;
optional int32 number = 2;
optional EnumValueOptions options = 3;
}
// Describes a service.
message ServiceDescriptorProto {
optional string name = 1 [ctype = STRING_PIECE];
repeated MethodDescriptorProto method = 2;
repeated MethodDescriptorProto method = 2;
optional ServiceOptions options = 3;
}
@ -269,12 +273,14 @@ message MethodDescriptorProto {
// Input and output type names. These are resolved in the same way as
// FieldDescriptorProto.type_name, but must refer to a message type.
optional string input_type = 2 [ctype = STRING_PIECE];
optional string output_type = 3 [ctype = STRING_PIECE];
optional MethodOptions options = 4;
// Identifies if client streams multiple client messages
optional bool client_streaming = 5 [default = false];
// Identifies if server streams multiple server messages
optional bool server_streaming = 6 [default = false];
}
@ -351,6 +357,7 @@ message FileOptions {
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
}
optional OptimizeMode optimize_for = 9 [default = SPEED];
// Sets the Go package where structs generated from this .proto will be
@ -371,8 +378,11 @@ message FileOptions {
// these default to false. Old code which depends on generic services should
// explicitly set them to true.
optional bool cc_generic_services = 16 [default = false];
optional bool java_generic_services = 17 [default = false];
optional bool py_generic_services = 18 [default = false];
optional bool php_generic_services = 42 [default = false];
// Is this file deprecated?
@ -499,14 +509,14 @@ message FieldOptions {
// options below. This option is not yet implemented in the open source
// release -- sorry, we'll try to include it in a future version!
optional CType ctype = 1 [default = STRING];
enum CType {
// Default mode.
STRING = 0;
CORD = 1;
STRING_PIECE = 2;
}
// The packed option can be enabled for repeated primitive fields to enable
// a more efficient representation on the wire. Rather than repeatedly
// writing the tag and type for each element, the entire array is encoded as
@ -526,6 +536,7 @@ message FieldOptions {
// This option is an enum to permit additional types to be added, e.g.
// goog.math.Integer.
optional JSType jstype = 6 [default = JS_NORMAL];
enum JSType {
// Use the default type.
JS_NORMAL = 0;
@ -554,7 +565,6 @@ message FieldOptions {
// call from multiple threads concurrently, while non-const methods continue
// to require exclusive access.
//
//
// Note that implementations may choose not to check required fields within
// a lazy sub-message. That is, calling IsInitialized() on the outer message
// may return true even if the inner message has missing required fields.
@ -666,6 +676,7 @@ message MethodOptions {
NO_SIDE_EFFECTS = 1; // implies idempotent
IDEMPOTENT = 2; // idempotent, but may have side effects
}
optional IdempotencyLevel idempotency_level = 34
[default = IDEMPOTENCY_UNKNOWN];
@ -690,13 +701,16 @@ message UninterpretedOption {
// "foo.(bar.baz).qux".
message NamePart {
optional string name_part = 1 [ctype = STRING_PIECE];
optional bool is_extension = 2;
}
repeated NamePart name = 2;
// The value of the uninterpreted option, in whatever type the tokenizer
// identified it as during parsing. Exactly one of these should be set.
optional string identifier_value = 3 [ctype = STRING_PIECE];
optional uint64 positive_int_value = 4;
optional int64 negative_int_value = 5;
optional double double_value = 6;
@ -754,6 +768,7 @@ message SourceCodeInfo {
// ignore those that it doesn't understand, as more types of locations could
// be recorded in the future.
repeated Location location = 1;
message Location {
// Identifies which part of the FileDescriptorProto was defined at this
// location.
@ -835,7 +850,9 @@ message SourceCodeInfo {
//
// // ignored detached comments.
optional string leading_comments = 3 [ctype = STRING_PIECE];
optional string trailing_comments = 4 [ctype = STRING_PIECE];
repeated string leading_detached_comments = 6 [ctype = STRING_PIECE];
}
}
@ -847,6 +864,7 @@ message GeneratedCodeInfo {
// An Annotation connects some span of text in generated code to an element
// of its generating .proto file.
repeated Annotation annotation = 1;
message Annotation {
// Identifies the element in the original source .proto file. This field
// is formatted the same as SourceCodeInfo.Location.path.

@ -15,14 +15,9 @@ COPTS = select({
"/wd4506", # no definition for inline function 'function'
"/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning)
"/wd4996", # The compiler encountered a deprecated declaration.
"/utf-8", # Set source and execution character sets to UTF-8
],
"//conditions:default": [
"-DHAVE_ZLIB",
"-Woverloaded-virtual",
"-Wno-sign-compare",
"-Wno-nonnull",
"-Werror",
],
})

@ -3,6 +3,9 @@ Internal tools to migrate shell commands to Bazel as an intermediate step
to wider Bazelification.
"""
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
def inline_sh_binary(
name,
srcs = [],
@ -41,7 +44,7 @@ def inline_sh_binary(
testonly = kwargs["testonly"] if "testonly" in kwargs else None,
)
native.sh_binary(
sh_binary(
name = name,
srcs = [name + "_genrule"],
data = srcs + tools + deps,
@ -86,7 +89,7 @@ def inline_sh_test(
testonly = kwargs["testonly"] if "testonly" in kwargs else None,
)
native.sh_test(
sh_test(
name = name,
srcs = [name + "_genrule"],
data = srcs + tools + deps,

@ -5,7 +5,7 @@ load("@rules_jvm_external//:defs.bzl", "java_export")
load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//java/osgi:osgi.bzl", "osgi_java_library")
JAVA_OPTS = [
JAVA_RELEASE_OPTS = [
"-source 8",
"-target 8",
"-Xep:Java8ApiChecker:ERROR",
@ -16,13 +16,21 @@ BUNDLE_LICENSE = "https://opensource.org/licenses/BSD-3-Clause"
def protobuf_java_export(**kwargs):
java_export(
javacopts = JAVA_OPTS,
javacopts = JAVA_RELEASE_OPTS,
# https://github.com/bazelbuild/rules_jvm_external/issues/1245
javadocopts = [
"-notimestamp",
"-use",
"-quiet",
"-Xdoclint:-missing",
"-encoding",
"UTF8",
],
**kwargs
)
def protobuf_java_library(**kwargs):
java_library(
javacopts = JAVA_OPTS,
**kwargs
)
@ -68,7 +76,7 @@ def protobuf_versioned_java_library(
java_library target.
"""
osgi_java_library(
javacopts = JAVA_OPTS,
javacopts = JAVA_RELEASE_OPTS,
automatic_module_name = automatic_module_name,
bundle_doc_url = BUNDLE_DOC_URL,
bundle_license = BUNDLE_LICENSE,

@ -0,0 +1,61 @@
"""Protobuf-specific kotlin build rules."""
load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION")
load("//java/osgi:kotlin_osgi.bzl", "osgi_kt_jvm_library")
BUNDLE_DOC_URL = "https://developers.google.com/protocol-buffers/"
BUNDLE_LICENSE = "https://opensource.org/licenses/BSD-3-Clause"
def protobuf_versioned_kt_jvm_library(
automatic_module_name,
bundle_description,
bundle_name,
bundle_symbolic_name,
bundle_additional_imports = [],
bundle_additional_exports = [],
**kwargs):
"""Extends `kt_jvm_library` to add OSGi headers to the MANIFEST.MF using bndlib
This macro should be usable as a drop-in replacement for kt_jvm_library.
The additional arguments are given the bndlib tool to generate an OSGi-compliant manifest file.
See [bnd documentation](https://bnd.bndtools.org/chapters/110-introduction.html)
Takes all the args that are standard for a kt_jvm_library target plus the following.
Args:
bundle_description: (required) The Bundle-Description header defines a short
description of this bundle.
automatic_module_name: (required) The Automatic-Module-Name header that represents
the name of the module when this bundle is used as an automatic
module.
bundle_name: (required) The Bundle-Name header defines a readable name for this
bundle. This should be a short, human-readable name that can
contain spaces.
bundle_symbolic_name: (required) The Bundle-SymbolicName header specifies a
non-localizable name for this bundle. The bundle symbolic name
together with a version must identify a unique bundle though it can
be installed multiple times in a framework. The bundle symbolic
name should be based on the reverse domain name convention.
bundle_additional_exports: The Export-Package header contains a
declaration of exported packages. These are additional export
package statements to be added before the default wildcard export
"*;version={$Bundle-Version}".
bundle_additional_imports: The Import-Package header declares the
imported packages for this bundle. These are additional import
package statements to be added before the default wildcard import
"*".
**kwargs: Additional key-word arguments that are passed to the internal
kt_jvm_library target.
"""
osgi_kt_jvm_library(
automatic_module_name = automatic_module_name,
bundle_doc_url = BUNDLE_DOC_URL,
bundle_license = BUNDLE_LICENSE,
bundle_version = PROTOBUF_JAVA_VERSION,
bundle_description = bundle_description,
bundle_name = bundle_name,
bundle_symbolic_name = bundle_symbolic_name,
bundle_additional_exports = bundle_additional_exports,
bundle_additional_imports = bundle_additional_imports + ["sun.misc;resolution:=optional"],
**kwargs
)

@ -1,3 +1,6 @@
import common.bazelrc
build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build --cxxopt="-Woverloaded-virtual"
build --copt="-Werror" --copt="-Wno-sign-compare" --copt="-Wno-sign-conversion" --copt="-Wno-error=sign-conversion" --copt="-Wno-deprecated-declarations"

@ -1,5 +1,7 @@
import common.bazelrc
# Workaround for maximum path length issues
build --cxxopt=/std:c++17 --host_cxxopt=/std:c++17
startup --output_user_root=C:/tmp --windows_enable_symlinks
common --enable_runfiles
common --enable_runfiles

@ -1,3 +1,6 @@
# TODO: ErrorProne's SelfAssertions are violated in tests
build --javacopt=-Xep:SelfAssertion:WARN
build:dbg --compilation_mode=dbg
build:opt --compilation_mode=opt
@ -27,6 +30,8 @@ build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1
# Workaround for the fact that Bazel links with $CC, not $CXX
# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748
build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
# Abseil passes nullptr to memcmp with 0 size
build:ubsan --copt=-fno-sanitize=nonnull-attribute
# Workaround Bazel 7 remote cache issues.
# See https://github.com/bazelbuild/bazel/issues/20161
@ -75,6 +80,10 @@ build --incompatible_use_host_features
# https://github.com/protocolbuffers/protobuf/issues/14313
common --noenable_bzlmod
# For easier debugging of build failures.
common --announce_rc
build --verbose_failures
# Important: this flag ensures that we remain compliant with the C++ layering
# check.
build --features=layering_check

@ -1,5 +1,8 @@
import common.bazelrc
build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build --cxxopt="-Woverloaded-virtual"
build --copt="-Werror" --copt="-Wno-sign-compare" --copt="-Wno-sign-conversion" --copt="-Wno-error=sign-conversion" --copt="-Wno-deprecated-declarations"
common --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1
common --xcode_version_config=@com_google_protobuf//.github:host_xcodes
common --xcode_version_config=@com_google_protobuf//.github:host_xcodes

@ -0,0 +1,25 @@
load("@rules_python//python:defs.bzl", "py_binary")
load("//upb/cmake:build_defs.bzl", "staleness_test")
py_binary(
name = "dependencies_generator",
srcs = ["dependencies_generator.py"],
)
genrule(
name = "generate_dependencies",
srcs = ["//:MODULE.bazel"],
outs = ["generated-in/dependencies.cmake"],
cmd = "$(location :dependencies_generator) " +
"$(location //:MODULE.bazel) $@",
tools = [":dependencies_generator"],
)
staleness_test(
name = "test_dependencies_staleness",
outs = [
"dependencies.cmake",
],
generated_pattern = "generated-in/%s",
tags = ["manual"],
)

@ -82,13 +82,6 @@ Go to the project folder:
C:\Path\to\src> cd protobuf
C:\Path\to\src\protobuf>
Remember to update any submodules if you are using git clone (you can skip this
step if you are using a release .tar.gz or .zip package):
```console
C:\Path\to\src\protobuf> git submodule update --init --recursive
```
Good. Now you are ready for *CMake* configuration.
## CMake Configuration
@ -117,8 +110,8 @@ Create a temporary *build* folder and change your working directory to it:
C:\Path\to\build\protobuf>
During configuration you will also be specifying where CMake should expect to
find your Abseil installation. To do so, first set `-Dprotobuf_ABSL_PROVIDER=package`
and then set `-DCMAKE_PREFIX_PATH` to the path where you installed Abseil.
find your Abseil installation. To do so, set `-DCMAKE_PREFIX_PATH` to the path
where you installed Abseil.
For example:
@ -126,10 +119,14 @@ For example:
C:\Path\to\build\protobuf> cmake -S. -Bcmake-out \
-DCMAKE_INSTALL_PREFIX=/tmp/protobuf \
-DCMAKE_CXX_STANDARD=14 \
-Dprotobuf_ABSL_PROVIDER=package \
-DCMAKE_PREFIX_PATH=/tmp/absl # Path to where I installed Abseil
```
If the installation of a dependency can't be found, CMake will default to
downloading and building a copy from GitHub. To prevent this and make it an
error condition, you can optionally set
`-Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON`.
The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build
a separate folder for each configuration.
@ -156,15 +153,14 @@ It will generate *Visual Studio* solution file *protobuf.sln* in current directo
Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test).
A copy of [Google Test](https://github.com/google/googletest) is included as a Git submodule in the `third-party/googletest` folder.
(You do need to initialize the Git submodules as explained above.)
By default, a local copy of [Google Test](https://github.com/google/googletest)
will be downloaded during CMake configuration.
Alternately, you may want to use protobuf in a larger set-up, you may want to use that standard CMake approach where
you build and install a shared copy of Google Test.
After you've built and installed your Google Test copy, you need add the following definition to your *cmake* command line
during the configuration step: `-Dprotobuf_USE_EXTERNAL_GTEST=ON`.
This will cause the standard CMake `find_package(GTest REQUIRED)` to be used.
After you've built and installed your Google Test copy, the standard CMake
`find_package(GTest)` will use it.
[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) will search in a default location,
which on Windows is *C:\Program Files*. This is most likely not what you want. You will want instead to search for

@ -10,31 +10,36 @@ if(protobuf_BUILD_TESTS)
set(ABSL_FIND_GOOGLETEST OFF)
endif()
if(TARGET absl::strings)
# If Abseil is included already, skip including it.
# (https://github.com/protocolbuffers/protobuf/issues/10435)
elseif(protobuf_ABSL_PROVIDER STREQUAL "module")
if(NOT ABSL_ROOT_DIR)
set(ABSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)
if (NOT TARGET absl::strings)
if (NOT protobuf_FORCE_FETCH_DEPENDENCIES)
# Use "CONFIG" as there is no built-in cmake module for absl.
find_package(absl CONFIG)
endif()
if(EXISTS "${ABSL_ROOT_DIR}/CMakeLists.txt")
if(protobuf_INSTALL)
# Fallback to fetching Abseil from github if it's not found locally.
if (NOT absl_FOUND AND NOT protobuf_LOCAL_DEPENDENCIES_ONLY)
include(${protobuf_SOURCE_DIR}/cmake/dependencies.cmake)
message(STATUS "Fallback to downloading Abseil ${abseil-cpp-version} from GitHub")
include(FetchContent)
FetchContent_Declare(
absl
GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git"
GIT_TAG "${abseil-cpp-version}"
)
if (protobuf_INSTALL)
# When protobuf_INSTALL is enabled and Abseil will be built as a module,
# Abseil will be installed along with protobuf for convenience.
set(ABSL_ENABLE_INSTALL ON)
endif()
add_subdirectory(${ABSL_ROOT_DIR} third_party/abseil-cpp)
else()
message(WARNING "protobuf_ABSL_PROVIDER is \"module\" but ABSL_ROOT_DIR is wrong")
FetchContent_MakeAvailable(absl)
endif()
if(protobuf_INSTALL AND NOT _protobuf_INSTALL_SUPPORTED_FROM_MODULE)
message(WARNING "protobuf_INSTALL will be forced to FALSE because protobuf_ABSL_PROVIDER is \"module\" and CMake version (${CMAKE_VERSION}) is less than 3.13.")
set(protobuf_INSTALL FALSE)
endif()
elseif(protobuf_ABSL_PROVIDER STREQUAL "package")
# Use "CONFIG" as there is no built-in cmake module for absl.
find_package(absl REQUIRED CONFIG)
endif()
if (NOT TARGET absl::strings)
message(FATAL_ERROR "Cannot find abseil-cpp dependency that's needed to build protobuf.\n")
endif()
set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n find_package(absl CONFIG)\nendif()")
if (BUILD_SHARED_LIBS AND MSVC)
@ -45,13 +50,8 @@ if (BUILD_SHARED_LIBS AND MSVC)
# Once https://github.com/abseil/abseil-cpp/pull/1466 is merged and released
# in the minimum version of abseil required by protobuf, it is possible to
# always link absl::abseil_dll and absl::abseil_test_dll and remove the if
if(protobuf_ABSL_PROVIDER STREQUAL "package")
set(protobuf_ABSL_USED_TARGETS absl::abseil_dll)
set(protobuf_ABSL_USED_TEST_TARGETS absl::abseil_test_dll)
else()
set(protobuf_ABSL_USED_TARGETS abseil_dll)
set(protobuf_ABSL_USED_TEST_TARGETS abseil_test_dll)
endif()
set(protobuf_ABSL_USED_TARGETS absl::abseil_dll)
set(protobuf_ABSL_USED_TEST_TARGETS absl::abseil_test_dll)
else()
set(protobuf_ABSL_USED_TARGETS
absl::absl_check

@ -1,15 +1,31 @@
if (protobuf_JSONCPP_PROVIDER STREQUAL "module")
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/jsoncpp/CMakeLists.txt")
message(FATAL_ERROR
"Cannot find third_party/jsoncpp directory that's needed to "
"build conformance tests. If you use git, make sure you have cloned "
"submodules:\n"
" git submodule update --init --recursive\n"
"If instead you want to skip them, run cmake with:\n"
" cmake -Dprotobuf_BUILD_CONFORMANCE=OFF\n")
# Don't run jsoncpp tests.
set(JSONCPP_WITH_TESTS OFF)
if (NOT TARGET jsoncpp_lib)
if (NOT protobuf_FORCE_FETCH_DEPENDENCIES)
find_package(jsoncpp)
endif()
# Fallback to fetching Googletest from github if it's not found locally.
if (NOT jsoncpp_FOUND AND NOT protobuf_LOCAL_DEPENDENCIES_ONLY)
include(${protobuf_SOURCE_DIR}/cmake/dependencies.cmake)
message(STATUS "Fallback to downloading jsoncpp ${jsoncpp-version} from GitHub")
include(FetchContent)
FetchContent_Declare(
jsoncpp
GIT_REPOSITORY "https://github.com/open-source-parsers/jsoncpp.git"
GIT_TAG "${jsoncpp-version}"
)
FetchContent_MakeAvailable(jsoncpp)
endif()
elseif(protobuf_JSONCPP_PROVIDER STREQUAL "package")
find_package(jsoncpp REQUIRED)
endif()
if (NOT TARGET jsoncpp_lib)
message(FATAL_ERROR
"Cannot find jsoncpp dependency that's needed to build conformance tests.\n"
"If instead you want to skip these tests, run cmake with:\n"
" cmake -Dprotobuf_BUILD_CONFORMANCE=OFF\n")
endif()
file(MAKE_DIRECTORY ${protobuf_BINARY_DIR}/conformance)
@ -93,6 +109,8 @@ add_executable(conformance_test_runner
${protobuf_SOURCE_DIR}/conformance/conformance_test_main.cc
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.cc
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.h
${protobuf_SOURCE_DIR}/conformance/failure_list_trie_node.cc
${protobuf_SOURCE_DIR}/conformance/failure_list_trie_node.h
)
add_executable(conformance_cpp
@ -127,18 +145,13 @@ add_test(NAME conformance_cpp_test
--text_format_failure_list ${protobuf_SOURCE_DIR}/conformance/text_format_failure_list_cpp.txt
--output_dir ${protobuf_TEST_XML_OUTDIR}
--maximum_edition 2023
${CMAKE_CURRENT_BINARY_DIR}/conformance_cpp
$<TARGET_FILE:conformance_cpp>
DEPENDS conformance_test_runner conformance_cpp)
set(JSONCPP_WITH_TESTS OFF CACHE BOOL "Disable tests")
if(protobuf_JSONCPP_PROVIDER STREQUAL "module")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp third_party/jsoncpp)
target_include_directories(conformance_test_runner PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp/include)
if(BUILD_SHARED_LIBS)
target_link_libraries(conformance_test_runner jsoncpp_lib)
else()
target_link_libraries(conformance_test_runner jsoncpp_static)
endif()
if(BUILD_SHARED_LIBS)
target_link_libraries(conformance_test_runner jsoncpp_lib)
else()
target_link_libraries(conformance_test_runner jsoncpp)
target_link_libraries(conformance_test_runner jsoncpp_static)
endif()

@ -0,0 +1,34 @@
# Auto-generated by @//cmake:make_dependencies
#
# This file contains lists of external dependencies based on our Bazel
# config. It should be included from a hand-written CMake file that uses
# them.
#
# Changes to this file will be overwritten based on Bazel definitions.
if(${CMAKE_VERSION} VERSION_GREATER 3.10 OR ${CMAKE_VERSION} VERSION_EQUAL 3.10)
include_guard()
endif()
set(abseil-cpp-version "20240722.0")
set(bazel_skylib-version "1.7.0")
set(jsoncpp-version "1.9.6")
set(rules_cc-version "0.0.16")
set(rules_fuzzing-version "0.5.2")
set(rules_java-version "8.3.2")
set(rules_jvm_external-version "6.3")
set(rules_kotlin-version "1.9.6")
set(rules_license-version "1.0.0")
set(rules_pkg-version "1.0.1")
set(rules_python-version "0.28.0")
set(rules_rust-version "0.51.0")
set(platforms-version "0.0.8")
set(zlib-version "1.3.1")
set(bazel_features-version "1.17.0")
set(rules_shell-version "0.2.0")
set(googletest-version "1.14.0")
set(rules_buf-version "0.3.0")
set(rules_testing-version "0.6.0")
set(rules_proto-version "4.0.0")

@ -0,0 +1,143 @@
#!/usr/bin/python
#
# Protocol Buffers - Google's data interchange format
# Copyright 2023 Google LLC. All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google LLC nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""A tool to convert MODULE.bazel -> CMakeLists.txt.
This tool is very protobuf-specific at the moment, and should not be seen as a
generic Bazel -> CMake converter.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
import textwrap
class ExtensionFunctions(object):
"""A fake extension that we can use to get the functions we need."""
def toolchain(self, *args, **kwargs):
pass
def parse(self, *args, **kwargs):
pass
def spec(self, *args, **kwargs):
pass
def from_specs(self, *args, **kwargs):
pass
def install(self, *args, **kwargs):
pass
class ModuleFileFunctions(object):
"""A fake MODULE file that we can exec() to get the functions we need."""
def __init__(self, converter):
self.converter = converter
def module(self, *args, **kwargs):
pass
def bazel_dep(self, name, version, **kwargs):
self.converter.toplevel += textwrap.dedent(
"""\
set(%(name)s-version "%(version)s")
"""
% {
"name": name,
"version": version,
}
)
def register_toolchains(self, *args):
pass
def use_repo(self, *args, **kwargs):
pass
def use_extension(self, *args):
return ExtensionFunctions()
class Converter(object):
def __init__(self):
self.toplevel = ""
self.if_lua = ""
def convert(self):
return self.template % {
"toplevel": converter.toplevel,
}
template = textwrap.dedent("""\
# Auto-generated by @//cmake:make_dependencies
#
# This file contains lists of external dependencies based on our Bazel
# config. It should be included from a hand-written CMake file that uses
# them.
#
# Changes to this file will be overwritten based on Bazel definitions.
if(${CMAKE_VERSION} VERSION_GREATER 3.10 OR ${CMAKE_VERSION} VERSION_EQUAL 3.10)
include_guard()
endif()
%(toplevel)s
""")
data = {}
converter = Converter()
def GetDict(obj):
ret = {}
for k in dir(obj):
if not k.startswith("_"):
ret[k] = getattr(obj, k)
return ret
# We take the MODULE path as a command-line argument to ensure that we can find
# it regardless of how exactly Bazel was invoked.
exec(open(sys.argv[1]).read(), GetDict(ModuleFileFunctions(converter)))
with open(sys.argv[2], "w") as f:
f.write(converter.convert())

@ -1,48 +1,28 @@
option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF)
if (protobuf_USE_EXTERNAL_GTEST)
find_package(GTest REQUIRED CONFIG)
else()
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/googletest/CMakeLists.txt")
message(FATAL_ERROR
"Cannot find third_party/googletest directory that's needed to "
"build tests. If you use git, make sure you have cloned submodules:\n"
" git submodule update --init --recursive\n"
"If instead you want to skip tests, run cmake with:\n"
" cmake -Dprotobuf_BUILD_TESTS=OFF\n")
if (NOT TARGET GTest::gmock)
if (NOT protobuf_FORCE_FETCH_DEPENDENCIES)
find_package(GTest CONFIG)
endif()
set(googlemock_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googlemock")
set(googletest_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googletest")
include_directories(
${googlemock_source_dir}
${googletest_source_dir}
${googletest_source_dir}/include
${googlemock_source_dir}/include
)
# Fallback to fetching Googletest from github if it's not found locally.
if (NOT GTest_FOUND AND NOT protobuf_LOCAL_DEPENDENCIES_ONLY)
include(${protobuf_SOURCE_DIR}/cmake/dependencies.cmake)
message(STATUS "Fallback to downloading GTest ${googletest-version} from GitHub")
add_library(gmock ${protobuf_SHARED_OR_STATIC}
"${googlemock_source_dir}/src/gmock-all.cc"
"${googletest_source_dir}/src/gtest-all.cc"
)
if (protobuf_BUILD_SHARED_LIBS)
set_target_properties(gmock
PROPERTIES
COMPILE_DEFINITIONS
"GTEST_CREATE_SHARED_LIBRARY=1"
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY "https://github.com/google/googletest.git"
GIT_TAG "v${googletest-version}"
)
endif()
if (protobuf_INSTALL)
set(protobuf_INSTALL_TESTS ON)
# Due to https://github.com/google/googletest/issues/4384, we can't name this
# GTest for use with find_package until 1.15.0.
FetchContent_MakeAvailable(googletest)
endif()
endif()
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc")
target_link_libraries(gmock_main gmock)
add_library(GTest::gmock ALIAS gmock)
add_library(GTest::gmock_main ALIAS gmock_main)
add_library(GTest::gtest ALIAS gmock)
add_library(GTest::gtest_main ALIAS gmock_main)
if (NOT TARGET GTest::gmock)
message(FATAL_ERROR
"Cannot find googletest dependency that's needed to build tests.\n"
"If instead you want to skip tests, run cmake with:\n"
" cmake -Dprotobuf_BUILD_TESTS=OFF\n")
endif()

@ -24,6 +24,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf-lite.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY)
if (protobuf_BUILD_LIBUPB)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/upb.pc.cmake
${CMAKE_CURRENT_BINARY_DIR}/upb.pc @ONLY)
endif ()
set(_protobuf_libraries libprotobuf-lite libprotobuf)
if (protobuf_BUILD_LIBPROTOC)
@ -72,6 +76,9 @@ if (protobuf_BUILD_PROTOC_BINARIES)
endif (protobuf_BUILD_PROTOC_BINARIES)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
if (protobuf_BUILD_LIBUPB)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif ()
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
set(protobuf_HEADERS
@ -122,15 +129,9 @@ set(_install_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the c
set(_build_cmakedir_desc "Directory relative to CMAKE_CURRENT_BINARY_DIR for cmake configuration files")
set(_exampledir_desc "Directory relative to CMAKE_INSTALL_DATA to install examples")
set(_protobuf_subdir_desc "Subdirectory in which to install cmake configuration files")
if(NOT MSVC)
set(protobuf_CMAKE_SUBDIR "cmake/protobuf" CACHE STRING "${_protobuf_subdir_desc}")
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_install_cmakedir_desc}")
set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}")
else()
set(protobuf_CMAKE_SUBDIR "cmake" CACHE STRING "${_protobuf_subdir_desc}")
set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}")
set(CMAKE_INSTALL_EXAMPLEDIR "examples" CACHE STRING "${_exampledir_desc}")
endif()
set(protobuf_CMAKE_SUBDIR "cmake/protobuf" CACHE STRING "${_protobuf_subdir_desc}")
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_install_cmakedir_desc}")
set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}")
set(CMAKE_BUILD_CMAKEDIR "${CMAKE_CURRENT_BINARY_DIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_build_cmakedir_desc}")
mark_as_advanced(protobuf_CMAKE_SUBDIR)
mark_as_advanced(CMAKE_BUILD_CMAKEDIR)

@ -29,6 +29,7 @@ target_include_directories(libprotobuf-lite PUBLIC
)
target_link_libraries(libprotobuf-lite PUBLIC ${protobuf_ABSL_USED_TARGETS})
protobuf_configure_target(libprotobuf-lite)
protobuf_configure_unity_target(libprotobuf-lite)
if(protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf-lite
PUBLIC PROTOBUF_USE_DLLS

@ -44,9 +44,12 @@ macro(_check_and_save_build_option OPTION VALUE)
endif()
set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE} PARENT_SCOPE)
endmacro()
_check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
_check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
_check_and_save_build_option(BUILD_SHARED_LIBS @protobuf_BUILD_SHARED_LIBS@)
if(PACKAGE_VERSION_COMPATIBLE)
_check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
_check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
_check_and_save_build_option(BUILD_SHARED_LIBS @protobuf_BUILD_SHARED_LIBS@)
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if(CMAKE_SIZEOF_VOID_P AND "@CMAKE_SIZEOF_VOID_P@")

@ -52,4 +52,21 @@ function(protobuf_configure_target target)
if (HAVE_ZLIB)
target_compile_definitions("${target}" PRIVATE -DHAVE_ZLIB)
endif ()
endfunction ()
function(protobuf_configure_unity_target target)
if(protobuf_USE_UNITY_BUILD)
# UNITY_BUILD available in CMake >=3.18.
if(${CMAKE_VERSION} VERSION_GREATER 3.18 OR ${CMAKE_VERSION} VERSION_EQUAL 3.18)
# If protobuf_USE_UNITY_BUILD is set to ON, set target to use Unity builds.
set_target_properties("${target}"
PROPERTIES
UNITY_BUILD ON
UNITY_BUILD_MODE BATCH
UNITY_BUILD_BATCH_SIZE 50
)
endif()
endif()
endfunction ()

@ -2,11 +2,11 @@ function(protobuf_generate)
include(CMakeParseArguments)
set(_options APPEND_PATH)
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES)
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS PROTOC_EXE)
if(COMMAND target_sources)
list(APPEND _singleargs TARGET)
endif()
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS DEPENDENCIES)
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
@ -83,6 +83,11 @@ function(protobuf_generate)
endforeach()
endif()
if(NOT protobuf_generate_PROTOC_EXE)
# Default to using the CMake executable
set(protobuf_generate_PROTOC_EXE protobuf::protoc)
endif()
foreach(DIR ${protobuf_generate_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
@ -143,7 +148,7 @@ function(protobuf_generate)
add_custom_command(
OUTPUT ${_generated_srcs}
COMMAND protobuf::protoc
COMMAND ${protobuf_generate_PROTOC_EXE}
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
DEPENDS ${_abs_file} ${protobuf_PROTOC_EXE} ${protobuf_generate_DEPENDENCIES}
COMMENT ${_comment}

@ -103,6 +103,7 @@ add_executable(tests ${tests_files} ${common_test_files})
if (MSVC)
target_compile_options(tests PRIVATE
/wd4146 # unary minus operator applied to unsigned type, result still unsigned
/bigobj
)
endif()
target_link_libraries(tests
@ -219,6 +220,8 @@ add_custom_target(restore-installed-headers)
file(GLOB_RECURSE _local_hdrs
"${PROJECT_SOURCE_DIR}/src/*.h"
"${PROJECT_SOURCE_DIR}/src/*.inc"
)
file(GLOB_RECURSE _local_upb_hdrs
"${PROJECT_SOURCE_DIR}/upb/*.h"
)
@ -234,6 +237,7 @@ list(APPEND _exclude_hdrs ${test_util_hdrs} ${lite_test_util_hdrs} ${common_test
${compiler_test_utils_hdrs} ${upb_test_util_files})
foreach(_hdr ${_exclude_hdrs})
list(REMOVE_ITEM _local_hdrs ${_hdr})
list(REMOVE_ITEM _local_upb_hdrs ${_hdr})
endforeach()
foreach(_hdr ${_local_hdrs})
@ -249,6 +253,19 @@ foreach(_hdr ${_local_hdrs})
copy "${_tmp_file}" "${_hdr}")
endforeach()
foreach(_hdr ${_local_upb_hdrs})
string(REPLACE "${protobuf_SOURCE_DIR}/upb" "" _file ${_hdr})
set(_tmp_file "${CMAKE_BINARY_DIR}/tmp-install-test/${_file}")
add_custom_command(TARGET remove-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E remove -f "${_hdr}")
add_custom_command(TARGET save-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E
copy "${_hdr}" "${_tmp_file}" || true)
add_custom_command(TARGET restore-installed-headers PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E
copy "${_tmp_file}" "${_hdr}")
endforeach()
add_dependencies(remove-installed-headers save-installed-headers)
if(protobuf_REMOVE_INSTALLED_HEADERS)
# Make sure we remove all the headers *before* any codegen occurs.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save