Skip to content

Commit a6d6623

Browse files
mkruskal-googlecopybara-github
authored andcommitted
Announce proto_h changes
PiperOrigin-RevId: 859363574
1 parent 426dbdb commit a6d6623

2 files changed

Lines changed: 127 additions & 0 deletions

File tree

content/news/2026-01-20.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
+++
2+
title = "Changes Announced on January 20, 2026"
3+
linkTitle = "January 20, 2026"
4+
toc_hide = "true"
5+
description = "Changes announced for Protocol Buffers on January 20, 2026."
6+
type = "docs"
7+
+++
8+
9+
## Efficient headers in C++
10+
11+
As of the 34.0 release, the C++ code generator will start setting the `proto_h`
12+
option by default. Instead of just producing a `pb.h` header, it will begin
13+
producing both `pb.h` and `proto.h` ones. This provides a more efficient option
14+
to reduce build times in systems with large proto trees.
15+
16+
### Opting out
17+
18+
When `proto_h` is set, `pb.h` headers will still be generated for convenience
19+
when build size isn't a concern. You can continue to use these as before, as
20+
long as you make sure the `proto.h` headers are provided in your include path.
21+
The `pb.h` files will now simply import the `proto.h` header and all of their
22+
dependencies' `pb.h` files instead of defining any symbols themselves.
23+
24+
If you hit problems with getting `proto.h` on your include path, you can restore
25+
the old behavior by passing the generator argument `proto_h=false` to protoc.
26+
For example:
27+
28+
```
29+
protoc --cpp_opt=proto_h=false --cpp_out=out/dir myproto.proto
30+
```
31+
32+
### Why `proto.h`?
33+
34+
The traditional `pb.h` file transitively includes all the `pb.h` files of every
35+
other `.proto` whose messages are referenced in the file. As some of our message
36+
types reference hundreds of different message types, this can result in any code
37+
using a single field from one of these messages paying to compile the headers
38+
from every one of its referenced messages. This causes heavy load on your builds
39+
due to excessively long compiles, and even break them due to the amount of code
40+
being built.
41+
42+
By contrast, `proto.h` headers do not include the headers for all the file's
43+
referenced messages. Instead, they use forward declarations to minimize the APIs
44+
exposed, which dramatically reduces compile time for some message types.
45+
46+
### Using `proto.h`
47+
48+
Because `proto.h` files don't include other message types' headers, you may need
49+
to modify your `#include`s in order to use them. For example, let's say you have
50+
two `.proto` files, `foo.proto` and `bar.proto`:
51+
52+
```proto
53+
// my_package/foo.proto
54+
edition = "2023";
55+
56+
package my_package;
57+
58+
message Foo {
59+
int32 some_data = 42;
60+
}
61+
62+
enum Truthy {
63+
TRUTHY_UNSPECIFIED = 0;
64+
TRUTHY_FALSE = 1;
65+
TRUTHY_TRUE = 2;
66+
TRUTHY_MAYBE = 3;
67+
}
68+
```
69+
70+
```proto
71+
// my_package/bar.proto
72+
edition = "2023";
73+
74+
import "my_package/foo.proto";
75+
76+
package my_package;
77+
78+
message Bar {
79+
Truthy some_flag = 42;
80+
repeated Foo foo = 43;
81+
}
82+
```
83+
84+
Using `pb.h` headers, you can write code like this:
85+
86+
```c++
87+
// my_package/test1.cc
88+
#include "my_package/bar.pb.h"
89+
namespace my_package {
90+
void Test1Function1(const Bar &bar_message) {
91+
if (bar_message.some_flag()) { ... }
92+
}
93+
void Test1Function2(const Bar &bar_message) {
94+
if (bar_message.some_flag() != MAYBE) { ... }
95+
}
96+
void Test1Function3(const Bar &bar_message) {
97+
for (Foo foo : bar_message.foos()) {
98+
DoSomething(foo.some_data());
99+
}
100+
...
101+
}
102+
```
103+
104+
However, this will **not** work with `proto.h`, because you won't have the
105+
header information for `foo.proto`. To get this code to work, you need to
106+
`#include` the `proto.h` headers for both `bar.proto` **and** `foo.proto`.
107+
108+
```c++
109+
// my_package/test1.cc
110+
#include "my_package/bar.proto.h"
111+
#include "my_package/foo.proto.h"
112+
namespace my_package {
113+
void Test1Function1(const Bar &bar_message) {
114+
if (bar_message.some_flag()) { ... }
115+
}
116+
void Test1Function2(const Bar &bar_message) {
117+
if (bar_message.some_flag() != MAYBE) { ... }
118+
}
119+
void Test1Function3(const Bar &bar_message) {
120+
for (Foo foo : bar_message.foos()) {
121+
DoSomething(foo.some_data());
122+
}
123+
...
124+
}
125+
```

content/news/_index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ New news topics will also be published to the
2020
The following news topics provide information in the reverse order in which it
2121
was released.
2222

23+
* [January 20, 2026](/news/2026-01-20) - Efficient
24+
headers in C++
2325
* [January 16, 2026](/news/2026-01-16) - Prebuilt proto
2426
compiler (protoc) for Bazel
2527
* [September 19, 2025](/news/2025-09-19) - Breaking

0 commit comments

Comments
 (0)