From 4f536bee2f6263ecf4e1b45898265c4020a1c369 Mon Sep 17 00:00:00 2001 From: Carlos O'Ryan Date: Fri, 26 May 2023 10:10:47 -0700 Subject: [PATCH 1/3] feat: workaround for `DOMAIN` macro (#12903) This is a macro on some (older) versions of GCC, and macOS, and Windows. Sigh. I moved the `#undef` block to a common section. I also took the opportunity to add a regression test for all these macros that need to be `#undef`'d. Part of the work for googleapis/google-cloud-cpp#8125 Closes #12903 PiperOrigin-RevId: 535649278 --- src/file_lists.cmake | 1 + src/google/protobuf/BUILD.bazel | 2 + src/google/protobuf/port_def.inc | 22 +++-- src/google/protobuf/port_undef.inc | 12 ++- .../protobuf/unittest_proto3_bad_macros.proto | 98 +++++++++++++++++++ 5 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 src/google/protobuf/unittest_proto3_bad_macros.proto diff --git a/src/file_lists.cmake b/src/file_lists.cmake index da030df3d8..8b48f6b9c2 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -666,6 +666,7 @@ set(protobuf_test_protos_files ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_arena.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_arena_lite.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_bad_macros.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_lite.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_proto3_optional.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_retention.proto diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 77ed2309f3..91827d9cff 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -645,6 +645,7 @@ filegroup( "unittest_proto3.proto", "unittest_proto3_arena.proto", "unittest_proto3_arena_lite.proto", + "unittest_proto3_bad_macros.proto", "unittest_proto3_lite.proto", "unittest_proto3_optional.proto", "unittest_retention.proto", @@ -702,6 +703,7 @@ proto_library( "unittest_proto3.proto", "unittest_proto3_arena.proto", "unittest_proto3_arena_lite.proto", + "unittest_proto3_bad_macros.proto", "unittest_proto3_lite.proto", "unittest_proto3_optional.proto", "unittest_retention.proto", diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 18d7ccfe83..8b2f74e232 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -888,11 +888,18 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #undef PACKAGE #endif -// autoheader defines this in some circumstances -#ifdef PACKAGE -#define PROTOBUF_DID_UNDEF_PACKAGE -#pragma push_macro("PACKAGE") -#undef PACKAGE +// a few common headers define this +#ifdef PACKED +#define PROTOBUF_DID_UNDEF_PACKED +#pragma push_macro("PACKED") +#undef PACKED +#endif + +// This is a macro on Windows, macOS, and some variants of GCC. +#ifdef DOMAIN +#define PROTOBUF_DID_UNDEF_DOMAIN +#pragma push_macro("DOMAIN") +#undef DOMAIN #endif // linux is a legacy MACRO defined in most popular C++ standards. @@ -909,8 +916,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #undef CREATE_NEW #pragma push_macro("DELETE") #undef DELETE -#pragma push_macro("DOMAIN") -#undef DOMAIN #pragma push_macro("DOUBLE_CLICK") #undef DOUBLE_CLICK #pragma push_macro("ERROR") @@ -968,9 +973,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #endif // _WIN32 #ifdef __APPLE__ -// Inconvenient macro names from usr/include/math.h in some macOS SDKs. -#pragma push_macro("DOMAIN") -#undef DOMAIN // Inconvenient macro names from /usr/include/mach/boolean.h in some macOS SDKs. #pragma push_macro("TRUE") #undef TRUE diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index e9eae069c3..cee6f8b901 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -128,6 +128,16 @@ #undef PROTOBUF_DID_UNDEF_PACKAGE #endif +#ifdef PROTOBUF_DID_UNDEF_PACKED +#pragma pop_macro("PACKED") +#undef PROTOBUF_DID_UNDEF_PACKED +#endif + +#ifdef PROTOBUF_DID_UNDEF_DOMAIN +#pragma pop_macro("DOMAIN") +#undef PROTOBUF_DID_UNDEF_DOMAIN +#endif + #ifdef PROTOBUF_DID_UNDEF_LINUX #pragma pop_macro("linux") #endif @@ -135,7 +145,6 @@ #ifdef _WIN32 #pragma pop_macro("CREATE_NEW") #pragma pop_macro("DELETE") -#pragma pop_macro("DOMAIN") #pragma pop_macro("DOUBLE_CLICK") #pragma pop_macro("ERROR") #pragma pop_macro("ERROR_BUSY") @@ -166,7 +175,6 @@ #endif #ifdef __APPLE__ -#pragma pop_macro("DOMAIN") #pragma pop_macro("TRUE") #pragma pop_macro("FALSE") #pragma pop_macro("UID_MAX") diff --git a/src/google/protobuf/unittest_proto3_bad_macros.proto b/src/google/protobuf/unittest_proto3_bad_macros.proto new file mode 100644 index 0000000000..7d245b5d45 --- /dev/null +++ b/src/google/protobuf/unittest_proto3_bad_macros.proto @@ -0,0 +1,98 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. 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 Inc. 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. + +syntax = "proto3"; + +package protobuf_unittest; + +option csharp_namespace = "ProtobufUnittest"; +option java_multiple_files = true; +option java_package = "com.google.protobuf.testing.proto"; + +// `google/protobuf/port_def.inc` #undef's a number of inconvenient macros +// defined in system headers under varying circumstances. The code generated +// from this file will not compile if those `#undef` calls are accidentally +// removed. + +// This generates `GID_MAX`, which is a macro in some circumstances. +enum GID { + GID_UNUSED = 0; +} + +// This generates `UID_MAX`, which is a mcro in some circumstances. +enum UID { + UID_UNUSED = 0; +} + +// Just a container for bad macro names. Some of these do not follow the normal +// naming conventions, this is intentional, we just want to trigger a build +// failure if the macro is left defined. +enum BadNames { + // autoheader defines this in some circumstances. + PACKAGE = 0; + // The comment says "a few common headers define this". + PACKED = 1; + // Defined in many Linux system headers. + linux = 2; + // This is often a macro in ``. + DOMAIN = 3; + // These are defined in both Windows and macOS headers. + TRUE = 4; + FALSE = 5; + // Sometimes defined in Windows system headers. + CREATE_NEW = 6; + DELETE = 7; + DOUBLE_CLICK = 8; + ERROR = 9; + ERROR_BUSY = 10; + ERROR_INSTALL_FAILED = 11; + ERROR_NOT_FOUND = 12; + GetClassName = 13; + GetCurrentTime = 14; + GetMessage = 15; + GetObject = 16; + IGNORE = 17; + IN = 18; + INPUT_KEYBOARD = 19; + NO_ERROR = 20; + OUT = 21; + OPTIONAL = 22; + NEAR = 23; + NO_DATA = 24; + REASON_UNKNOWN = 25; + SERVICE_DISABLED = 26; + SEVERITY_ERROR = 27; + STATUS_PENDING = 28; + STRICT = 29; + // Sometimed defined in macOS system headers. + TYPE_BOOL = 30; + // Defined in macOS, Windows, and Linux headers. + DEBUG = 31; +} From b1e59e363ce02b59b8e68d05e2c8560a6c934469 Mon Sep 17 00:00:00 2001 From: Silvio Traversaro Date: Mon, 5 Jun 2023 15:01:50 -0700 Subject: [PATCH 2/3] CMake: Fix abseil_dll target name when using find_package(absl) (#12978) This additional if is necessary as of abseil 20230125.3 when abseil is consumed via add_subdirectory, the abseil_dll target is named abseil_dll, while if abseil is consumed via find_package, the target is called `absl::abseil_dll` . 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. You may wonder how linking worked at all before when `protobuf_ABSL_PROVIDER STREQUAL "package"`, as `abseil_dll` was not an imported target defined by `find_package(absl)`. The reason behind this is that if a name that is not an imported target is passed to `target_link_libraries`, it is just regarded as a C++ library name. So, in the end the `abseil_dll` library was correctly linked, simply all the transitive usage requirements defined by the `absl::abseil_dll` target were not propagated, that could lead to compilation errors if abseil was compiled with the `ABSL_PROPAGATE_CXX_STD` CMake option enabled. Closes #12978 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/12978 from traversaro:patch-1 39dd074281161fa0c4be69035d33b41a50e048c2 PiperOrigin-RevId: 537990391 --- cmake/abseil-cpp.cmake | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/cmake/abseil-cpp.cmake b/cmake/abseil-cpp.cmake index e7bfb2b15f..b50fb89e6c 100644 --- a/cmake/abseil-cpp.cmake +++ b/cmake/abseil-cpp.cmake @@ -39,9 +39,19 @@ set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n find_package(absl CONFI if (BUILD_SHARED_LIBS AND MSVC) # On MSVC Abseil is bundled into a single DLL. - set(protobuf_ABSL_USED_TARGETS abseil_dll) - - set(protobuf_ABSL_USED_TEST_TARGETS abseil_test_dll) + # This condition is necessary as of abseil 20230125.3 when abseil is consumed via add_subdirectory, + # the abseil_dll target is named abseil_dll, while if abseil is consumed via find_package, the target + # is called absl::abseil_dll + # 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() else() set(protobuf_ABSL_USED_TARGETS absl::absl_check From cdb535a74fe48c37f547718205c654a875c2b49b Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 1 Jun 2023 09:14:48 -0700 Subject: [PATCH 3/3] fix: missing `PROTOBUF_EXPORT` for public symbols PiperOrigin-RevId: 537042088 --- src/google/protobuf/io/strtod.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/google/protobuf/io/strtod.h b/src/google/protobuf/io/strtod.h index 851c8e621f..b368e4d87a 100644 --- a/src/google/protobuf/io/strtod.h +++ b/src/google/protobuf/io/strtod.h @@ -60,12 +60,12 @@ PROTOBUF_EXPORT std::string SimpleFtoa(float value); // A locale-independent version of the standard strtod(), which always // uses a dot as the decimal separator. -double NoLocaleStrtod(const char* str, char** endptr); +PROTOBUF_EXPORT double NoLocaleStrtod(const char* str, char** endptr); // Casts a double value to a float value. If the value is outside of the // representable range of float, it will be converted to positive or negative // infinity. -float SafeDoubleToFloat(double value); +PROTOBUF_EXPORT float SafeDoubleToFloat(double value); } // namespace io } // namespace protobuf