diff --git a/src/brpc/CMakeLists.txt b/src/brpc/CMakeLists.txt index 4efd059bfd..3f1ed29960 100644 --- a/src/brpc/CMakeLists.txt +++ b/src/brpc/CMakeLists.txt @@ -208,7 +208,8 @@ if(WITH_URMA AND URMA_USE_MOCK_ENABLED) target_compile_features(brpc_build_config INTERFACE cxx_std_17) endif() target_include_directories(brpc_build_config BEFORE INTERFACE - ${CMAKE_CURRENT_BINARY_DIR}) + ${CMAKE_CURRENT_BINARY_DIR} + ${Protobuf_INCLUDE_DIRS}) target_compile_definitions(brpc_build_config INTERFACE ${BRPC_DEFINITIONS}) target_include_directories(brpc_build_config INTERFACE ${BRPC_INCLUDE_DIRS}) diff --git a/src/butil/CMakeLists.txt b/src/butil/CMakeLists.txt index 1e57710a19..eb19c0d008 100644 --- a/src/butil/CMakeLists.txt +++ b/src/butil/CMakeLists.txt @@ -46,7 +46,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in get_filename_component(butil_generated_include_dir "${CMAKE_CURRENT_BINARY_DIR}/.." ABSOLUTE) -set(BUTIL_INCLUDE_DIRS ${GFLAGS_INCLUDE_PATH} ${PROTOBUF_INCLUDE_DIRS}) +# Keep generic dependency prefixes after the selected Protobuf installation. +# Otherwise a shared prefix can supply incompatible google/protobuf headers. +set(BUTIL_INCLUDE_DIRS ${GFLAGS_INCLUDE_PATH}) if(WITH_GLOG) find_path(GLOG_INCLUDE_PATH NAMES glog/logging.h) find_library(GLOG_LIB NAMES glog) @@ -85,7 +87,8 @@ add_library(butil_build_config INTERFACE) target_link_libraries(butil_build_config INTERFACE brpc_common_config) target_compile_definitions(butil_build_config INTERFACE ${BUTIL_DEFINITIONS}) target_include_directories(butil_build_config BEFORE INTERFACE - ${butil_generated_include_dir}) + ${butil_generated_include_dir} + ${Protobuf_INCLUDE_DIRS}) target_include_directories(butil_build_config INTERFACE ${BUTIL_INCLUDE_DIRS}) set(butil_crc32c_options) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a0fc2d0536..c3334965fd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -23,7 +23,9 @@ find_package(Gperftools) add_library(brpc_test_config INTERFACE) target_link_libraries(brpc_test_config INTERFACE brpc_build_config) -target_include_directories(brpc_test_config INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(brpc_test_config BEFORE INTERFACE + ${CMAKE_CURRENT_BINARY_DIR} + ${Protobuf_INCLUDE_DIRS}) target_compile_definitions(brpc_test_config INTERFACE UNIT_TEST BVAR_NOT_LINK_DEFAULT_VARIABLES @@ -253,6 +255,19 @@ target_link_libraries(test_butil PRIVATE add_test(NAME test_butil COMMAND test_butil) +# The generic dependency intentionally contains an incompatible header at the +# same path as a Protobuf header. Compilation verifies that the include order +# seen by the compiler selects the Protobuf package found for this build. +add_library(protobuf_include_order_generic INTERFACE) +target_include_directories(protobuf_include_order_generic INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/protobuf_include_order/generic_include) +add_executable(cmake_protobuf_include_order + ${CMAKE_CURRENT_SOURCE_DIR}/protobuf_include_order/protobuf_include_order.cpp) +target_link_libraries(cmake_protobuf_include_order PRIVATE + brpc_test_config + protobuf_include_order_generic) +add_test(NAME cmake_protobuf_include_order COMMAND cmake_protobuf_include_order) + # test_bvar # -DBVAR_NOT_LINK_DEFAULT_VARIABLES not work for gcc >= 5.0, just remove the file to prevent linking into unit tests get_filename_component(bvar_default_variables diff --git a/test/protobuf_include_order/generic_include/google/protobuf/stubs/common.h b/test/protobuf_include_order/generic_include/google/protobuf/stubs/common.h new file mode 100644 index 0000000000..a4ca30df6a --- /dev/null +++ b/test/protobuf_include_order/generic_include/google/protobuf/stubs/common.h @@ -0,0 +1,3 @@ +// This deliberately conflicts with the selected Protobuf installation. The +// compile probe must never see this header. +#define GOOGLE_PROTOBUF_VERSION 1 diff --git a/test/protobuf_include_order/protobuf_include_order.cpp b/test/protobuf_include_order/protobuf_include_order.cpp new file mode 100644 index 0000000000..b131db3ed5 --- /dev/null +++ b/test/protobuf_include_order/protobuf_include_order.cpp @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information regarding copyright +// ownership. The ASF licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +#include + +#if GOOGLE_PROTOBUF_VERSION == 1 +#error "A generic dependency's Protobuf header was selected" +#endif + +int main() { + return 0; +}