]>
Commit | Line | Data |
---|---|---|
38208315 JR |
1 | From 416f90939d4de58fe1a4e2489120010313183291 Mon Sep 17 00:00:00 2001 |
2 | From: Feng Xiao <xfxyjwf@gmail.com> | |
3 | Date: Tue, 14 Mar 2017 23:12:52 +0000 | |
4 | Subject: [PATCH] Fix freebsd build. | |
5 | ||
6 | It turns out system headers included by generated plugin.pb.h file already contains | |
7 | major/minor macro definitions when built on FreeBSD and we need to add #undefs to | |
8 | the generated header file. | |
9 | ||
10 | This change also fixes another compile error regarding EXPECT_DEATH on FreeBSD. | |
11 | --- | |
12 | src/google/protobuf/compiler/cpp/cpp_file.cc | 46 +++++++++++++++++++++++ | |
13 | src/google/protobuf/compiler/cpp/cpp_file.h | 9 +++++ | |
14 | src/google/protobuf/compiler/plugin.pb.h | 6 +++ | |
15 | src/google/protobuf/stubs/stringpiece_unittest.cc | 2 + | |
16 | 4 files changed, 63 insertions(+) | |
17 | ||
18 | diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc | |
19 | index 0e5e2f1..f2e013c 100644 | |
20 | --- a/src/google/protobuf/compiler/cpp/cpp_file.cc | |
21 | +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc | |
22 | @@ -54,6 +54,39 @@ namespace google { | |
23 | namespace protobuf { | |
24 | namespace compiler { | |
25 | namespace cpp { | |
26 | +namespace { | |
27 | +// The list of names that are defined as macros on some platforms. We need to | |
28 | +// #undef them for the generated code to compile. | |
29 | +const char* kMacroNames[] = {"major", "minor"}; | |
30 | + | |
31 | +bool IsMacroName(const string& name) { | |
32 | + // Just do a linear search as the number of elements is very small. | |
33 | + for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) { | |
34 | + if (name == kMacroNames[i]) return true; | |
35 | + } | |
36 | + return false; | |
37 | +} | |
38 | + | |
39 | +void CollectMacroNames(const Descriptor* message, vector<string>* names) { | |
40 | + for (int i = 0; i < message->field_count(); ++i) { | |
41 | + const FieldDescriptor* field = message->field(i); | |
42 | + if (IsMacroName(field->name())) { | |
43 | + names->push_back(field->name()); | |
44 | + } | |
45 | + } | |
46 | + for (int i = 0; i < message->nested_type_count(); ++i) { | |
47 | + CollectMacroNames(message->nested_type(i), names); | |
48 | + } | |
49 | +} | |
50 | + | |
51 | +void CollectMacroNames(const FileDescriptor* file, vector<string>* names) { | |
52 | + for (int i = 0; i < file->message_type_count(); ++i) { | |
53 | + CollectMacroNames(file->message_type(i), names); | |
54 | + } | |
55 | +} | |
56 | + | |
57 | + | |
58 | +} // namespace | |
59 | ||
60 | // =================================================================== | |
61 | ||
62 | @@ -103,10 +136,23 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) | |
63 | ||
64 | FileGenerator::~FileGenerator() {} | |
65 | ||
66 | +void FileGenerator::GenerateMacroUndefs(io::Printer* printer) { | |
67 | + vector<string> names_to_undef; | |
68 | + CollectMacroNames(file_, &names_to_undef); | |
69 | + for (int i = 0; i < names_to_undef.size(); ++i) { | |
70 | + printer->Print( | |
71 | + "#ifdef $name$\n" | |
72 | + "#undef $name$\n" | |
73 | + "#endif\n", | |
74 | + "name", names_to_undef[i]); | |
75 | + } | |
76 | +} | |
77 | + | |
78 | void FileGenerator::GenerateHeader(io::Printer* printer) { | |
79 | printer->Print( | |
80 | "// @@protoc_insertion_point(includes)\n"); | |
81 | ||
82 | + GenerateMacroUndefs(printer); | |
83 | ||
84 | GenerateForwardDeclarations(printer); | |
85 | ||
86 | diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h | |
87 | index 25d6eab..e3fbb96 100644 | |
88 | --- a/src/google/protobuf/compiler/cpp/cpp_file.h | |
89 | +++ b/src/google/protobuf/compiler/cpp/cpp_file.h | |
90 | @@ -133,6 +133,15 @@ class FileGenerator { | |
91 | ||
92 | void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer); | |
93 | ||
94 | + // Sometimes the names we use in a .proto file happen to be defined as macros | |
95 | + // on some platforms (e.g., macro/minor used in plugin.proto are defined as | |
96 | + // macros in sys/types.h on FreeBSD and a few other platforms). To make the | |
97 | + // generated code compile on these platforms, we either have to undef the | |
98 | + // macro for these few platforms, or rename the field name for all platforms. | |
99 | + // Since these names are part of protobuf public API, renaming is generally | |
100 | + // a breaking change so we prefer the #undef approach. | |
101 | + void GenerateMacroUndefs(io::Printer* printer); | |
102 | + | |
103 | const FileDescriptor* file_; | |
104 | const Options options_; | |
105 | ||
106 | diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h | |
107 | index 1b91dac..d6afb21 100644 | |
108 | --- a/src/google/protobuf/compiler/plugin.pb.h | |
109 | +++ b/src/google/protobuf/compiler/plugin.pb.h | |
110 | @@ -30,6 +30,12 @@ | |
111 | #include <google/protobuf/unknown_field_set.h> | |
112 | #include <google/protobuf/descriptor.pb.h> | |
113 | // @@protoc_insertion_point(includes) | |
114 | +#ifdef major | |
115 | +#undef major | |
116 | +#endif | |
117 | +#ifdef minor | |
118 | +#undef minor | |
119 | +#endif | |
120 | namespace google { | |
121 | namespace protobuf { | |
122 | class DescriptorProto; | |
123 | diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc | |
124 | index a52d81f..a6a8759 100644 | |
125 | --- a/src/google/protobuf/stubs/stringpiece_unittest.cc | |
126 | +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc | |
127 | @@ -783,11 +783,13 @@ TEST(FindOneCharTest, EdgeCases) { | |
128 | EXPECT_EQ(StringPiece::npos, a.rfind('x')); | |
129 | } | |
130 | ||
131 | +#ifdef PROTOBUF_HAS_DEATH_TEST | |
132 | #ifndef NDEBUG | |
133 | TEST(NonNegativeLenTest, NonNegativeLen) { | |
134 | EXPECT_DEATH(StringPiece("xyz", -1), "len >= 0"); | |
135 | } | |
136 | #endif // ndef DEBUG | |
137 | +#endif // PROTOBUF_HAS_DEATH_TEST | |
138 | ||
139 | } // namespace | |
140 | } // namespace protobuf |