Full Code of apache/brpc for AI

master 0565d8d2c7a1 cached
11 files
81.8 KB
24.1k tokens
1 requests
Download .txt
Repository: apache/brpc
Branch: master
Commit: 0565d8d2c7a1
Files: 11
Total size: 81.8 KB

Directory structure:
gitextract_27i_xhfr/

├── BUILD.bazel
├── CHANGES.md
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── MODULE.bazel
├── README.md
├── README_cn.md
├── WORKSPACE.bzlmod
├── config.h.in
└── config_brpc.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: BUILD.bazel
================================================
# 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.

load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "objc_library")

licenses(["notice"])  # Apache v2

exports_files(["LICENSE"])

COPTS = [
    "-fno-omit-frame-pointer",
    "-DBTHREAD_USE_FAST_PTHREAD_MUTEX",
    "-D__const__=__unused__",
    "-D_GNU_SOURCE",
    "-DUSE_SYMBOLIZE",
    "-DNO_TCMALLOC",
    "-D__STDC_FORMAT_MACROS",
    "-D__STDC_LIMIT_MACROS",
    "-D__STDC_CONSTANT_MACROS",
] + select({
    "//bazel/config:brpc_with_glog": ["-DBRPC_WITH_GLOG=1"],
    "//conditions:default": ["-DBRPC_WITH_GLOG=0"],
}) + select({
    "//bazel/config:brpc_with_mesalink": ["-DUSE_MESALINK"],
    "//conditions:default": [""],
}) + select({
    "//bazel/config:brpc_with_thrift": ["-DENABLE_THRIFT_FRAMED_PROTOCOL=1"],
    "//conditions:default": [""],
}) + select({
    "//bazel/config:brpc_with_thrift_legacy_version": [],
    "//conditions:default": ["-DTHRIFT_STDCXX=std"],
}) + select({
    "//bazel/config:brpc_with_rdma": ["-DBRPC_WITH_RDMA=1"],
    "//conditions:default": [""],
}) + select({
    "//bazel/config:brpc_with_debug_bthread_sche_safety": ["-DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=1"],
    "//conditions:default": ["-DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=0"],
}) + select({
    "//bazel/config:brpc_with_debug_lock": ["-DBRPC_DEBUG_LOCK=1"],
    "//conditions:default": ["-DBRPC_DEBUG_LOCK=0"],
}) + select({
    "//bazel/config:brpc_with_asan": ["-fsanitize=address"],
    "//conditions:default": [""],
}) + select({
    "//bazel/config:brpc_with_no_pthread_mutex_hook": ["-DNO_PTHREAD_MUTEX_HOOK"],
    "//conditions:default": [""],
})

LINKOPTS = [
    "-pthread",
    "-ldl",
] + select({
    "@bazel_tools//src/conditions:darwin": [
        "-framework CoreFoundation",
        "-framework CoreGraphics",
        "-framework CoreData",
        "-framework CoreText",
        "-framework Security",
        "-framework Foundation",
        "-Wl,-U,_MallocExtension_ReleaseFreeMemory",
        "-Wl,-U,_ProfilerStart",
        "-Wl,-U,_ProfilerStop",
        "-Wl,-U,__Z13GetStackTracePPvii",
        "-Wl,-U,_RegisterThriftProtocol",
        "-Wl,-U,_mallctl",
        "-Wl,-U,_malloc_stats_print",
    ],
    "//conditions:default": [
        "-lrt",
    ],
}) + select({
    "//bazel/config:brpc_with_mesalink": [
        "-lmesalink",
    ],
    "//conditions:default": [],
}) + select({
    "//bazel/config:brpc_with_rdma": [
        "-libverbs",
    ],
    "//conditions:default": [],
}) + select({
        "//bazel/config:brpc_with_asan": ["-fsanitize=address"],
        "//conditions:default": [""],
  })

genrule(
    name = "config_h",
    outs = [
        "src/butil/config.h",
    ],
    cmd = """cat << EOF  >$@""" + """
// This file is auto-generated.
#ifndef  BUTIL_CONFIG_H
#define  BUTIL_CONFIG_H
#ifdef BRPC_WITH_GLOG
#undef BRPC_WITH_GLOG
#endif
#define BRPC_WITH_GLOG """ + select({
              "//bazel/config:brpc_with_glog": "1",
              "//conditions:default": "0",
          }) +
          """
#endif  // BUTIL_CONFIG_H
EOF
    """,
)

BUTIL_SRCS = [
    "src/butil/third_party/dmg_fp/g_fmt.cc",
    "src/butil/third_party/dmg_fp/dtoa_wrapper.cc",
    "src/butil/third_party/dynamic_annotations/dynamic_annotations.c",
    "src/butil/third_party/icu/icu_utf.cc",
    "src/butil/third_party/superfasthash/superfasthash.c",
    "src/butil/third_party/modp_b64/modp_b64.cc",
    "src/butil/third_party/symbolize/demangle.cc",
    "src/butil/third_party/symbolize/symbolize.cc",
    "src/butil/third_party/snappy/snappy-sinksource.cc",
    "src/butil/third_party/snappy/snappy-stubs-internal.cc",
    "src/butil/third_party/snappy/snappy.cc",
    "src/butil/third_party/murmurhash3/murmurhash3.cpp",
    "src/butil/arena.cpp",
    "src/butil/at_exit.cc",
    "src/butil/atomicops_internals_x86_gcc.cc",
    "src/butil/base64.cc",
    "src/butil/base64url.cc",
    "src/butil/big_endian.cc",
    "src/butil/cpu.cc",
    "src/butil/debug/alias.cc",
    "src/butil/debug/asan_invalid_access.cc",
    "src/butil/debug/crash_logging.cc",
    "src/butil/debug/debugger.cc",
    "src/butil/debug/debugger_posix.cc",
    "src/butil/debug/dump_without_crashing.cc",
    "src/butil/debug/proc_maps_linux.cc",
    "src/butil/debug/stack_trace.cc",
    "src/butil/debug/stack_trace_posix.cc",
    "src/butil/environment.cc",
    "src/butil/files/file.cc",
    "src/butil/files/file_posix.cc",
    "src/butil/files/file_enumerator.cc",
    "src/butil/files/file_enumerator_posix.cc",
    "src/butil/files/file_path.cc",
    "src/butil/files/file_path_constants.cc",
    "src/butil/files/memory_mapped_file.cc",
    "src/butil/files/memory_mapped_file_posix.cc",
    "src/butil/files/scoped_file.cc",
    "src/butil/files/scoped_temp_dir.cc",
    "src/butil/file_util.cc",
    "src/butil/file_util_posix.cc",
    "src/butil/guid.cc",
    "src/butil/guid_posix.cc",
    "src/butil/hash.cc",
    "src/butil/lazy_instance.cc",
    "src/butil/location.cc",
    "src/butil/memory/aligned_memory.cc",
    "src/butil/memory/ref_counted.cc",
    "src/butil/memory/ref_counted_memory.cc",
    "src/butil/memory/singleton.cc",
    "src/butil/memory/weak_ptr.cc",
    "src/butil/posix/file_descriptor_shuffle.cc",
    "src/butil/posix/global_descriptors.cc",
    "src/butil/process_util.cc",
    "src/butil/rand_util.cc",
    "src/butil/rand_util_posix.cc",
    "src/butil/fast_rand.cpp",
    "src/butil/safe_strerror_posix.cc",
    "src/butil/sha1_portable.cc",
    "src/butil/strings/latin1_string_conversions.cc",
    "src/butil/strings/nullable_string16.cc",
    "src/butil/strings/safe_sprintf.cc",
    "src/butil/strings/string16.cc",
    "src/butil/strings/string_number_conversions.cc",
    "src/butil/strings/string_split.cc",
    "src/butil/strings/string_piece.cc",
    "src/butil/strings/string_util.cc",
    "src/butil/strings/string_util_constants.cc",
    "src/butil/strings/stringprintf.cc",
    "src/butil/strings/utf_offset_string_conversions.cc",
    "src/butil/strings/utf_string_conversion_utils.cc",
    "src/butil/strings/utf_string_conversions.cc",
    "src/butil/synchronization/cancellation_flag.cc",
    "src/butil/synchronization/condition_variable_posix.cc",
    "src/butil/synchronization/waitable_event_posix.cc",
    "src/butil/threading/non_thread_safe_impl.cc",
    "src/butil/threading/platform_thread_posix.cc",
    "src/butil/threading/simple_thread.cc",
    "src/butil/threading/thread_checker_impl.cc",
    "src/butil/threading/thread_collision_warner.cc",
    "src/butil/threading/thread_id_name_manager.cc",
    "src/butil/threading/thread_local_posix.cc",
    "src/butil/threading/thread_local_storage.cc",
    "src/butil/threading/thread_local_storage_posix.cc",
    "src/butil/threading/thread_restrictions.cc",
    "src/butil/threading/watchdog.cc",
    "src/butil/time/clock.cc",
    "src/butil/time/default_clock.cc",
    "src/butil/time/default_tick_clock.cc",
    "src/butil/time/tick_clock.cc",
    "src/butil/time/time.cc",
    "src/butil/time/time_posix.cc",
    "src/butil/version.cc",
    "src/butil/logging.cc",
    "src/butil/class_name.cpp",
    "src/butil/errno.cpp",
    "src/butil/find_cstr.cpp",
    "src/butil/status.cpp",
    "src/butil/string_printf.cpp",
    "src/butil/thread_local.cpp",
    "src/butil/thread_key.cpp",
    "src/butil/unix_socket.cpp",
    "src/butil/endpoint.cpp",
    "src/butil/fd_utility.cpp",
    "src/butil/files/temp_file.cpp",
    "src/butil/files/file_watcher.cpp",
    "src/butil/time.cpp",
    "src/butil/zero_copy_stream_as_streambuf.cpp",
    "src/butil/crc32c.cc",
    "src/butil/containers/case_ignored_flat_map.cpp",
    "src/butil/iobuf.cpp",
    "src/butil/single_iobuf.cpp",
    "src/butil/iobuf_profiler.cpp",
    "src/butil/binary_printer.cpp",
    "src/butil/recordio.cc",
    "src/butil/popen.cpp",
] + select({
    "@bazel_tools//src/conditions:darwin": [
        "src/butil/time/time_mac.cc",
        "src/butil/mac/scoped_mach_port.cc",
    ],
    "//conditions:default": [
        "src/butil/file_util_linux.cc",
        "src/butil/threading/platform_thread_linux.cc",
        "src/butil/strings/sys_string_conversions_posix.cc",
    ],
})

objc_library(
    name = "macos_lib",
    hdrs = [
        "src/butil/atomicops.h",
        "src/butil/atomicops_internals_atomicword_compat.h",
        "src/butil/atomicops_internals_mac.h",
        "src/butil/base_export.h",
        "src/butil/basictypes.h",
        "src/butil/build_config.h",
        "src/butil/compat.h",
        "src/butil/compiler_specific.h",
        "src/butil/containers/hash_tables.h",
        "src/butil/debug/debugger.h",
        "src/butil/debug/leak_annotations.h",
        "src/butil/file_descriptor_posix.h",
        "src/butil/file_util.h",
        "src/butil/files/file.h",
        "src/butil/files/file_path.h",
        "src/butil/files/scoped_file.h",
        "src/butil/lazy_instance.h",
        "src/butil/logging.h",
        "src/butil/mac/bundle_locations.h",
        "src/butil/mac/foundation_util.h",
        "src/butil/mac/scoped_cftyperef.h",
        "src/butil/mac/scoped_typeref.h",
        "src/butil/macros.h",
        "src/butil/string_printf.h",
        "src/butil/memory/aligned_memory.h",
        "src/butil/memory/scoped_policy.h",
        "src/butil/memory/scoped_ptr.h",
        "src/butil/move.h",
        "src/butil/port.h",
        "src/butil/posix/eintr_wrapper.h",
        "src/butil/scoped_generic.h",
        "src/butil/strings/string16.h",
        "src/butil/strings/string_piece.h",
        "src/butil/strings/string_util.h",
        "src/butil/strings/string_util_posix.h",
        "src/butil/strings/sys_string_conversions.h",
        "src/butil/synchronization/lock.h",
        "src/butil/third_party/dynamic_annotations/dynamic_annotations.h",
        "src/butil/third_party/murmurhash3/murmurhash3.h",
        "src/butil/threading/platform_thread.h",
        "src/butil/threading/thread_id_name_manager.h",
        "src/butil/threading/thread_restrictions.h",
        "src/butil/time.h",
        "src/butil/time/time.h",
        "src/butil/type_traits.h",
        ":config_h",
    ],
    enable_modules = True,
    includes = ["src/"],
    non_arc_srcs = [
        "src/butil/mac/bundle_locations.mm",
        "src/butil/mac/foundation_util.mm",
        "src/butil/file_util_mac.mm",
        "src/butil/threading/platform_thread_mac.mm",
        "src/butil/strings/sys_string_conversions_mac.mm",
    ],
    tags = ["manual"],
    deps = [
        "@com_github_gflags_gflags//:gflags",
    ] + select({
        "//bazel/config:brpc_with_glog": ["@com_github_google_glog//:glog"],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "butil",
    srcs = BUTIL_SRCS,
    hdrs = glob([
        "src/butil/*.h",
        "src/butil/*.hpp",
        "src/butil/**/*.h",
        "src/butil/**/*.hpp",
        "src/butil/**/**/*.h",
        "src/butil/**/**/*.hpp",
        "src/butil/**/**/**/*.h",
        "src/butil/**/**/**/*.hpp",
    ]) + [
        "src/butil/third_party/dmg_fp/dtoa.cc",
        ":config_h",
    ],
    copts = COPTS + select({
        "//bazel/config:brpc_build_for_unittest": [
            "-DBVAR_NOT_LINK_DEFAULT_VARIABLES",
            "-DUNIT_TEST",
        ],
        "//conditions:default": [],
    }),
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        "@com_github_gflags_gflags//:gflags",
        "@com_github_madler_zlib//:zlib",
        "@com_google_protobuf//:protobuf",
    ] + select({
        "//bazel/config:brpc_with_glog": ["@com_github_google_glog//:glog"],
        "//conditions:default": [],
    }) + select({
        "@bazel_tools//src/conditions:darwin": [":macos_lib"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:brpc_with_boringssl": ["@boringssl//:ssl", "@boringssl//:crypto"],
        "//conditions:default": ["@openssl//:ssl", "@openssl//:crypto"],
    }),
)

cc_library(
    name = "bvar",
    srcs = glob(
        [
            "src/bvar/*.cpp",
            "src/bvar/detail/*.cpp",
        ],
        exclude = [
            "src/bvar/default_variables.cpp",
        ],
    ) + select({
        "//bazel/config:brpc_build_for_unittest": [],
        "//conditions:default": ["src/bvar/default_variables.cpp"],
    }),
    hdrs = glob([
        "src/bvar/*.h",
        "src/bvar/utils/*.h",
        "src/bvar/detail/*.h",
    ]),
    defines = [] + select({
        "//bazel/config:with_babylon_counter": ["WITH_BABYLON_COUNTER=1"],
        "//conditions:default": [],
    }),
    copts = COPTS + select({
        "//bazel/config:brpc_build_for_unittest": [
            "-DBVAR_NOT_LINK_DEFAULT_VARIABLES",
            "-DUNIT_TEST",
        ],
        "//conditions:default": [],
    }),
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
    ]  + select({
        "//bazel/config:with_babylon_counter": ["@babylon//:concurrent_counter"],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "bthread",
    srcs = glob([
        "src/bthread/*.cpp",
    ]),
    hdrs = glob([
        "src/bthread/*.h",
        "src/bthread/*.list",
    ]),
    defines = [] + select({
        "//bazel/config:brpc_with_bthread_tracer": [
            "BRPC_BTHREAD_TRACER",
        ],
        "//conditions:default": [],
    }),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
        ":bvar",
    ] + select({
        "//bazel/config:brpc_with_bthread_tracer": [
            "@com_github_libunwind_libunwind//:libunwind",
            "@com_google_absl//absl/debugging:stacktrace",
            "@com_google_absl//absl/debugging:symbolize",
        ],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "json2pb",
    srcs = glob([
        "src/json2pb/*.cpp",
    ]),
    hdrs = glob([
        "src/json2pb/*.h",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
    ],
)

cc_library(
    name = "mcpack2pb",
    srcs = [
        "src/mcpack2pb/field_type.cpp",
        "src/mcpack2pb/mcpack2pb.cpp",
        "src/mcpack2pb/parser.cpp",
        "src/mcpack2pb/serializer.cpp",
    ],
    hdrs = glob([
        "src/mcpack2pb/*.h",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc_idl_options_cc_proto",
        ":butil",
        "@com_google_protobuf//src/google/protobuf/compiler:code_generator",
    ],
)

filegroup(
    name = "brpc_idl_options_proto_srcs",
    srcs = [
        "src/idl_options.proto",
    ],
    visibility = ["//visibility:public"],
)

proto_library(
    name = "brpc_idl_options_proto",
    srcs = [":brpc_idl_options_proto_srcs"],
    strip_import_prefix = "src",
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_protobuf//:descriptor_proto",
    ],
)

cc_proto_library(
    name = "brpc_idl_options_cc_proto",
    visibility = ["//visibility:public"],
    deps = [":brpc_idl_options_proto"],
)

filegroup(
    name = "brpc_internal_proto_srcs",
    srcs = glob([
        "src/brpc/*.proto",
        "src/brpc/policy/*.proto",
    ]),
    visibility = ["//visibility:public"],
)

proto_library(
    name = "brpc_internal_proto",
    srcs = [":brpc_internal_proto_srcs"],
    strip_import_prefix = "src",
    visibility = ["//visibility:public"],
    deps = [
        ":brpc_idl_options_proto",
        "@com_google_protobuf//:descriptor_proto",
    ],
)

cc_proto_library(
    name = "brpc_internal_cc_proto",
    visibility = ["//visibility:public"],
    deps = [":brpc_internal_proto"],
)

cc_library(
    name = "brpc",
    srcs = glob([
        "src/brpc/*.cpp",
        "src/brpc/**/*.cpp",
    ],
    exclude = [
        "src/brpc/thrift_service.cpp",
        "src/brpc/thrift_message.cpp",
        "src/brpc/policy/thrift_protocol.cpp",
        "src/brpc/event_dispatcher_epoll.cpp",
        "src/brpc/event_dispatcher_kqueue.cpp",
    ]) + select({
        "//bazel/config:brpc_with_thrift": glob([
            "src/brpc/thrift*.cpp",
            "src/brpc/**/thrift*.cpp",
        ]),
        "//conditions:default": [],
    }),
    hdrs = glob([
        "src/brpc/*.h",
        "src/brpc/**/*.h",
        "src/brpc/event_dispatcher_epoll.cpp",
        "src/brpc/event_dispatcher_kqueue.cpp",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc_internal_cc_proto",
        ":bthread",
        ":butil",
        ":bvar",
        ":json2pb",
        ":mcpack2pb",
        "@com_github_google_leveldb//:leveldb",
    ] + select({
        "//bazel/config:brpc_with_thrift": [
            "@org_apache_thrift//:thrift",
        ],
        "//conditions:default": [],
    }),
)

cc_binary(
    name = "protoc-gen-mcpack",
    srcs = [
        "src/mcpack2pb/generator.cpp",
    ],
    copts = COPTS,
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc",
        ":brpc_idl_options_cc_proto",
    ],
)


================================================
FILE: CHANGES.md
================================================
<!--
#
# 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.
#
-->

# Table of Contents

- [0.9.7](#0.9.7)
- [0.9.6](#0.9.6)
- [0.9.5](#0.9.5)
- [0.9.0](#0.9.0)

## 0.9.7
* Add DISCLAIMER-WIP as license issues are not all resolved
* Fix many license related issues
* Ignore flow control in h2 when sending first request
* Add flame graph view for profiling builtin service
* Fix bug that _avg_latency maybe zero in lalb
* Fix bug that logging namespace conflicts with others
* Add gdb_bthread_stack.py to read bthread stack
* Adapt to Arm64
* Support redis server protocol
* Enable circuit breaker for backup request
* Support zone for bilibili discovery naming service when fetching server nodes
* Add brpc revision in release version

## 0.9.6
* Health (of a connection) can be checked at rpc-level
* Fix SSL-related compilation issues on Mac
* Support SSL-replacement lib MesaLink
* Support consistent hashing with ketama algo.
* bvar variables can be exported for prometheus services
* String[Multi]Splitter supports '\0' as separator
* Support for bilibili discovery service
* Improved CircuitBreaker
* grpc impl. supports timeout

## 0.9.5
* h2c/grpc are supported now, h2(encrypted) is not included.
* thrift support.
* Mac build support
* Extend ConcurrencyLimiter to control max-concurrency dynamically and an "auto" CL is supported by default
* CircuitBreaker support to isolate abnormal servers more effectively

## 0.9.0
* Contains major features of brpc, OK for production usages.
* No h2/h2c/rdma support, Mac/Windows ports are not ready yet.


================================================
FILE: CMakeLists.txt
================================================
# 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.

cmake_minimum_required(VERSION 2.8.12)
project(brpc C CXX)

option(WITH_GLOG "With glog" OFF)
option(WITH_MESALINK "With MesaLink" OFF)
option(WITH_BORINGSSL "With BoringSSL" OFF)
option(DEBUG "Print debug logs" OFF)
option(WITH_DEBUG_SYMBOLS "With debug symbols" ON)
option(WITH_THRIFT "With thrift framed protocol supported" OFF)
option(WITH_BTHREAD_TRACER "With bthread tracer supported" OFF)
option(WITH_SNAPPY "With snappy" OFF)
option(WITH_RDMA "With RDMA" OFF)
option(WITH_DEBUG_BTHREAD_SCHE_SAFETY "With debugging bthread sche safety" OFF)
option(WITH_DEBUG_LOCK "With debugging lock" OFF)
option(WITH_ASAN "With AddressSanitizer" OFF)
option(BUILD_UNIT_TESTS "Whether to build unit tests" OFF)
option(BUILD_FUZZ_TESTS "Whether to build fuzz tests" OFF)
option(BUILD_BRPC_TOOLS "Whether to build brpc tools" ON)
option(DOWNLOAD_GTEST "Download and build a fresh copy of googletest. Requires Internet access." ON)

# Enable MACOSX_RPATH. Run "cmake --help-policy CMP0042" for policy details.
if(POLICY CMP0042)
    cmake_policy(SET CMP0042 NEW)
endif()

set(BRPC_VERSION 1.16.0)

SET(CPACK_GENERATOR "DEB")
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "brpc authors")
INCLUDE(CPack)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    # require at least gcc 4.8
    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
        message(FATAL_ERROR "GCC is too old, please install a newer version supporting C++11")
    endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # require at least clang 3.3
    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3)
        message(FATAL_ERROR "Clang is too old, please install a newer version supporting C++11")
    endif()
else()
    message(WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang and GCC.")
endif()

set(WITH_GLOG_VAL "0")
if(WITH_GLOG)
    set(WITH_GLOG_VAL "1")
    set(BRPC_WITH_GLOG 1)
endif()

if(WITH_DEBUG_SYMBOLS)
    set(DEBUG_SYMBOL "-g")
endif()

set(WITH_DEBUG_LOCK_VAL "0")
if(WITH_DEBUG_LOCK)
    set(WITH_DEBUG_LOCK_VAL "1")
endif()

if(WITH_THRIFT)
    set(THRIFT_CPP_FLAG "-DENABLE_THRIFT_FRAMED_PROTOCOL")
    find_library(THRIFT_LIB NAMES thrift)
    if (NOT THRIFT_LIB)
        message(FATAL_ERROR "Fail to find Thrift")
    endif()
endif()

if (WITH_BTHREAD_TRACER)
    if (NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux")  OR NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64"))
        message(FATAL_ERROR "bthread tracer is only supported on Linux x86_64 platform")
    endif()
    find_path(LIBUNWIND_INCLUDE_PATH NAMES libunwind.h)
    find_library(LIBUNWIND_LIB NAMES unwind)
    find_library(LIBUNWIND_X86_64_LIB NAMES unwind-x86_64)
    if (NOT LIBUNWIND_INCLUDE_PATH OR NOT LIBUNWIND_LIB)
        message(FATAL_ERROR "Fail to find libunwind, which is needed by bthread tracer")
    endif()
    find_package(absl REQUIRED CONFIG)
    set(bthread_tracer_ABSL_USED_TARGETS absl::base absl::stacktrace absl::symbolize)
    add_definitions(-DBRPC_BTHREAD_TRACER)
    include_directories(${LIBUNWIND_INCLUDE_PATH})
endif ()

set(WITH_RDMA_VAL "0")
if(WITH_RDMA)
    set(WITH_RDMA_VAL "1")
endif()

set(WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL "0")
if(WITH_DEBUG_BTHREAD_SCHE_SAFETY)
    set(WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL "1")
endif()

include(GNUInstallDirs)

configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_SOURCE_DIR}/src/butil/config.h @ONLY)

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

find_package(GFLAGS REQUIRED)

include_directories(
    ${PROJECT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_BINARY_DIR}
)

execute_process(
    COMMAND bash -c "${PROJECT_SOURCE_DIR}/tools/get_brpc_revision.sh ${PROJECT_SOURCE_DIR} | tr -d '\n'"
    OUTPUT_VARIABLE BRPC_REVISION
)

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    include(CheckFunctionExists)
    CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
    if(NOT HAVE_CLOCK_GETTIME)
        set(DEFINE_CLOCK_GETTIME "-DNO_CLOCK_GETTIME_IN_MAC")
    endif()
    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wno-deprecated-declarations -Wno-inconsistent-missing-override")
endif()

set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEFINE_CLOCK_GETTIME} -DBRPC_WITH_GLOG=${WITH_GLOG_VAL} -DBRPC_WITH_RDMA=${WITH_RDMA_VAL} -DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=${WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL} -DBRPC_DEBUG_LOCK=${WITH_DEBUG_LOCK_VAL}")
if (WITH_ASAN)
    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
    set(CMAKE_C_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
endif()
if(WITH_MESALINK)
    set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DUSE_MESALINK")
endif()
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DBTHREAD_USE_FAST_PTHREAD_MUTEX -D__const__=__unused__ -D_GNU_SOURCE -DUSE_SYMBOLIZE -DNO_TCMALLOC -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DBRPC_REVISION=\\\"${BRPC_REVISION}\\\" -D__STRICT_ANSI__")
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEBUG_SYMBOL} ${THRIFT_CPP_FLAG}")
set(CMAKE_CXX_FLAGS "${CMAKE_CPP_FLAGS} ${CMAKE_CXX_FLAGS} -O2 -pipe -Wall -W -fPIC -fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_CPP_FLAGS} -O2 -pipe -Wall -W -fPIC -fstrict-aliasing -Wno-unused-parameter -fno-omit-frame-pointer")

macro(use_cxx11)
if(CMAKE_VERSION VERSION_LESS "3.1.3")
    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    endif()
    if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    endif()
else()
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
endmacro(use_cxx11)

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    #required by butil/crc32.cc to boost performance for 10x
    if((CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4))
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -msse4.2")
    elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64"))
        # segmentation fault in libcontext
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-gcse")
    elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64"))
        # RISC-V specific optimizations
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gc")
    endif()
    if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
    endif()
endif()

find_package(Protobuf REQUIRED)
if(Protobuf_VERSION GREATER 4.21)
    # required by absl
    set(CMAKE_CXX_STANDARD 17)

    find_package(absl REQUIRED CONFIG)
    set(protobuf_ABSL_USED_TARGETS
        absl::absl_check
        absl::absl_log
        absl::algorithm
        absl::base
        absl::bind_front
        absl::bits
        absl::btree
        absl::cleanup
        absl::cord
        absl::core_headers
        absl::debugging
        absl::die_if_null
        absl::dynamic_annotations
        absl::flags
        absl::flat_hash_map
        absl::flat_hash_set
        absl::function_ref
        absl::hash
        absl::layout
        absl::log_initialize
        absl::log_severity
        absl::memory
        absl::node_hash_map
        absl::node_hash_set
        absl::optional
        absl::span
        absl::status
        absl::statusor
        absl::strings
        absl::synchronization
        absl::time
        absl::type_traits
        absl::utility
        absl::variant
    )
else()
    use_cxx11()
endif()
find_package(Threads REQUIRED)

find_path(LEVELDB_INCLUDE_PATH NAMES leveldb/db.h)
find_library(LEVELDB_LIB NAMES leveldb)
if ((NOT LEVELDB_INCLUDE_PATH) OR (NOT LEVELDB_LIB))
    message(FATAL_ERROR "Fail to find leveldb")
endif()

if(WITH_SNAPPY)
    find_path(SNAPPY_INCLUDE_PATH NAMES snappy.h)
    find_library(SNAPPY_LIB NAMES snappy)
    if ((NOT SNAPPY_INCLUDE_PATH) OR (NOT SNAPPY_LIB))
        message(FATAL_ERROR "Fail to find snappy")
    endif()
    include_directories(${SNAPPY_INCLUDE_PATH})
endif()

if(WITH_GLOG)
    find_path(GLOG_INCLUDE_PATH NAMES glog/logging.h)
    find_library(GLOG_LIB NAMES glog)
    if((NOT GLOG_INCLUDE_PATH) OR (NOT GLOG_LIB))
        message(FATAL_ERROR "Fail to find glog")
    endif()
    include_directories(${GLOG_INCLUDE_PATH})
endif()

if(WITH_MESALINK)
    find_path(MESALINK_INCLUDE_PATH NAMES mesalink/openssl/ssl.h)
    find_library(MESALINK_LIB NAMES mesalink)
    if((NOT MESALINK_INCLUDE_PATH) OR (NOT MESALINK_LIB))
        message(FATAL_ERROR "Fail to find MesaLink")
    else()
        message(STATUS "Found MesaLink: ${MESALINK_LIB}")
    endif()
    include_directories(${MESALINK_INCLUDE_PATH})
endif()

if(WITH_RDMA)
    message("brpc compile with rdma")
    find_path(RDMA_INCLUDE_PATH NAMES infiniband/verbs.h)
    find_library(RDMA_LIB NAMES ibverbs)
    if((NOT RDMA_INCLUDE_PATH) OR (NOT RDMA_LIB))
        message(FATAL_ERROR "Fail to find ibverbs")
    endif()
endif()

find_library(PROTOC_LIB NAMES protoc)
if(NOT PROTOC_LIB)
    message(FATAL_ERROR "Fail to find protoc lib")
endif()

if(WITH_BORINGSSL)
    find_package(BoringSSL)
    include_directories(${BORINGSSL_INCLUDE_DIR})
else()
    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT OPENSSL_ROOT_DIR)
        set(OPENSSL_ROOT_DIR
            "/usr/local/opt/openssl" # Homebrew installed OpenSSL
        )
    endif()

    find_package(OpenSSL)
    include_directories(${OPENSSL_INCLUDE_DIR})
endif()

include_directories(
        ${GFLAGS_INCLUDE_PATH}
        ${PROTOBUF_INCLUDE_DIRS}
        ${LEVELDB_INCLUDE_PATH}
        )

set(DYNAMIC_LIB
    ${GFLAGS_LIBRARY}
    ${PROTOBUF_LIBRARIES} ${protobuf_ABSL_USED_TARGETS}
    ${LEVELDB_LIB}
    ${PROTOC_LIB}
    ${CMAKE_THREAD_LIBS_INIT}
    ${THRIFT_LIB}
    dl
    z)

if(WITH_BORINGSSL)
    list(APPEND DYNAMIC_LIB ${BORINGSSL_SSL_LIBRARY})
    list(APPEND DYNAMIC_LIB ${BORINGSSL_CRYPTO_LIBRARY})
else()
    if(WITH_MESALINK)
        list(APPEND DYNAMIC_LIB ${OPENSSL_CRYPTO_LIBRARY})
        list(APPEND DYNAMIC_LIB ${MESALINK_LIB})
    else()
        list(APPEND DYNAMIC_LIB ${OPENSSL_SSL_LIBRARY})
        list(APPEND DYNAMIC_LIB ${OPENSSL_CRYPTO_LIBRARY})
    endif()
endif()

if(WITH_RDMA)
    list(APPEND DYNAMIC_LIB ${RDMA_LIB})
endif()

set(BRPC_PRIVATE_LIBS "-lgflags -lprotobuf -lleveldb -lprotoc -lssl -lcrypto -ldl -lz")

if(WITH_GLOG)
    set(DYNAMIC_LIB ${GLOG_LIB} ${DYNAMIC_LIB})
    set(BRPC_PRIVATE_LIBS "-lglog ${BRPC_PRIVATE_LIBS}")
endif()

if(WITH_SNAPPY)
    set(DYNAMIC_LIB ${DYNAMIC_LIB} ${SNAPPY_LIB})
    set(BRPC_PRIVATE_LIBS "${BRPC_PRIVATE_LIBS} -lsnappy")
endif()

if (WITH_BTHREAD_TRACER)
    set(DYNAMIC_LIB ${DYNAMIC_LIB} ${LIBUNWIND_LIB} ${LIBUNWIND_X86_64_LIB} ${bthread_tracer_ABSL_USED_TARGETS})
    set(BRPC_PRIVATE_LIBS "${BRPC_PRIVATE_LIBS} -lunwind -lunwind-x86_64  -labsl_stacktrace -labsl_symbolize -labsl_debugging_internal -labsl_demangle_internal -labsl_malloc_internal -labsl_raw_logging_internal -labsl_spinlock_wait -labsl_base")
endif()

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    set(DYNAMIC_LIB ${DYNAMIC_LIB} rt)
    set(BRPC_PRIVATE_LIBS "${BRPC_PRIVATE_LIBS} -lrt")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(DYNAMIC_LIB ${DYNAMIC_LIB}
        pthread
        "-framework CoreFoundation"
        "-framework CoreGraphics"
        "-framework CoreData"
        "-framework CoreText"
        "-framework Security"
        "-framework Foundation"
        "-Wl,-U,_MallocExtension_ReleaseFreeMemory"
        "-Wl,-U,_ProfilerStart"
        "-Wl,-U,_ProfilerStop"
        "-Wl,-U,__Z13GetStackTracePPvii"
        "-Wl,-U,_mallctl"
        "-Wl,-U,_malloc_stats_print"
    )
endif()

# for *.so
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/output/lib)
# for *.a
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/output/lib)

# the reason why not using file(GLOB_RECURSE...) is that we want to
# include different files on different platforms.
set(BUTIL_SOURCES
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/dmg_fp/g_fmt.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/dmg_fp/dtoa_wrapper.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/dynamic_annotations/dynamic_annotations.c
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/icu/icu_utf.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/superfasthash/superfasthash.c
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/modp_b64/modp_b64.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/symbolize/demangle.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/symbolize/symbolize.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/snappy/snappy-sinksource.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/snappy/snappy-stubs-internal.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/snappy/snappy.cc
    ${PROJECT_SOURCE_DIR}/src/butil/third_party/murmurhash3/murmurhash3.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/arena.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/at_exit.cc
    ${PROJECT_SOURCE_DIR}/src/butil/atomicops_internals_x86_gcc.cc
    ${PROJECT_SOURCE_DIR}/src/butil/base64.cc
    ${PROJECT_SOURCE_DIR}/src/butil/base64url.cc
    ${PROJECT_SOURCE_DIR}/src/butil/big_endian.cc
    ${PROJECT_SOURCE_DIR}/src/butil/cpu.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/alias.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/asan_invalid_access.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/crash_logging.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/debugger.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/debugger_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/dump_without_crashing.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/proc_maps_linux.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/stack_trace.cc
    ${PROJECT_SOURCE_DIR}/src/butil/debug/stack_trace_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/environment.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_enumerator.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_enumerator_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_path.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_path_constants.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/memory_mapped_file.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/memory_mapped_file_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/scoped_file.cc
    ${PROJECT_SOURCE_DIR}/src/butil/files/scoped_temp_dir.cc
    ${PROJECT_SOURCE_DIR}/src/butil/file_util.cc
    ${PROJECT_SOURCE_DIR}/src/butil/file_util_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/guid.cc
    ${PROJECT_SOURCE_DIR}/src/butil/guid_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/hash.cc
    ${PROJECT_SOURCE_DIR}/src/butil/lazy_instance.cc
    ${PROJECT_SOURCE_DIR}/src/butil/location.cc
    ${PROJECT_SOURCE_DIR}/src/butil/memory/aligned_memory.cc
    ${PROJECT_SOURCE_DIR}/src/butil/memory/ref_counted.cc
    ${PROJECT_SOURCE_DIR}/src/butil/memory/ref_counted_memory.cc
    ${PROJECT_SOURCE_DIR}/src/butil/memory/singleton.cc
    ${PROJECT_SOURCE_DIR}/src/butil/memory/weak_ptr.cc
    ${PROJECT_SOURCE_DIR}/src/butil/posix/file_descriptor_shuffle.cc
    ${PROJECT_SOURCE_DIR}/src/butil/posix/global_descriptors.cc
    ${PROJECT_SOURCE_DIR}/src/butil/process_util.cc
    ${PROJECT_SOURCE_DIR}/src/butil/rand_util.cc
    ${PROJECT_SOURCE_DIR}/src/butil/rand_util_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/fast_rand.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/safe_strerror_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/sha1_portable.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/latin1_string_conversions.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/nullable_string16.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/safe_sprintf.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string16.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string_number_conversions.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string_split.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string_piece.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string_util.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/string_util_constants.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/stringprintf.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/utf_offset_string_conversions.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/utf_string_conversion_utils.cc
    ${PROJECT_SOURCE_DIR}/src/butil/strings/utf_string_conversions.cc
    ${PROJECT_SOURCE_DIR}/src/butil/synchronization/cancellation_flag.cc
    ${PROJECT_SOURCE_DIR}/src/butil/synchronization/condition_variable_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/synchronization/waitable_event_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/non_thread_safe_impl.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/platform_thread_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/simple_thread.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_checker_impl.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_collision_warner.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_id_name_manager.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_local_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_local_storage.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_local_storage_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/thread_restrictions.cc
    ${PROJECT_SOURCE_DIR}/src/butil/threading/watchdog.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/clock.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/default_clock.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/default_tick_clock.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/tick_clock.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/time.cc
    ${PROJECT_SOURCE_DIR}/src/butil/time/time_posix.cc
    ${PROJECT_SOURCE_DIR}/src/butil/version.cc
    ${PROJECT_SOURCE_DIR}/src/butil/logging.cc
    ${PROJECT_SOURCE_DIR}/src/butil/class_name.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/errno.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/find_cstr.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/status.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/string_printf.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/thread_local.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/thread_key.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/unix_socket.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/endpoint.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/fd_utility.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/files/temp_file.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/files/file_watcher.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/time.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/zero_copy_stream_as_streambuf.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/crc32c.cc
    ${PROJECT_SOURCE_DIR}/src/butil/containers/case_ignored_flat_map.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/iobuf.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/single_iobuf.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/iobuf_profiler.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/binary_printer.cpp
    ${PROJECT_SOURCE_DIR}/src/butil/recordio.cc
    ${PROJECT_SOURCE_DIR}/src/butil/popen.cpp
    )

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    set(BUTIL_SOURCES ${BUTIL_SOURCES}
        ${PROJECT_SOURCE_DIR}/src/butil/file_util_linux.cc
        ${PROJECT_SOURCE_DIR}/src/butil/threading/platform_thread_linux.cc
        ${PROJECT_SOURCE_DIR}/src/butil/strings/sys_string_conversions_posix.cc)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(BUTIL_SOURCES ${BUTIL_SOURCES}
        ${PROJECT_SOURCE_DIR}/src/butil/mac/bundle_locations.mm
        ${PROJECT_SOURCE_DIR}/src/butil/mac/foundation_util.mm
        ${PROJECT_SOURCE_DIR}/src/butil/file_util_mac.mm
        ${PROJECT_SOURCE_DIR}/src/butil/threading/platform_thread_mac.mm
        ${PROJECT_SOURCE_DIR}/src/butil/strings/sys_string_conversions_mac.mm
        ${PROJECT_SOURCE_DIR}/src/butil/time/time_mac.cc
        ${PROJECT_SOURCE_DIR}/src/butil/mac/scoped_mach_port.cc)
endif()

file(GLOB_RECURSE BVAR_SOURCES "${PROJECT_SOURCE_DIR}/src/bvar/*.cpp")
file(GLOB_RECURSE BTHREAD_SOURCES "${PROJECT_SOURCE_DIR}/src/bthread/*.cpp")
file(GLOB_RECURSE JSON2PB_SOURCES "${PROJECT_SOURCE_DIR}/src/json2pb/*.cpp")
file(GLOB_RECURSE BRPC_SOURCES "${PROJECT_SOURCE_DIR}/src/brpc/*.cpp")
file(GLOB_RECURSE THRIFT_SOURCES "${PROJECT_SOURCE_DIR}/src/brpc/thrift*.cpp")
file(GLOB_RECURSE EXCLUDE_SOURCES "${PROJECT_SOURCE_DIR}/src/brpc/event_dispatcher_*.cpp")

if(WITH_THRIFT)
    message("brpc compile with thrift protocol")
else()
    # Remove thrift sources
    foreach(v ${THRIFT_SOURCES})
        list(REMOVE_ITEM BRPC_SOURCES ${v})
    endforeach()
    set(THRIFT_SOURCES "")
endif()

foreach(v ${EXCLUDE_SOURCES})
    list(REMOVE_ITEM BRPC_SOURCES ${v})
endforeach()

set(MCPACK2PB_SOURCES
    ${PROJECT_SOURCE_DIR}/src/mcpack2pb/field_type.cpp
    ${PROJECT_SOURCE_DIR}/src/mcpack2pb/mcpack2pb.cpp
    ${PROJECT_SOURCE_DIR}/src/mcpack2pb/parser.cpp
    ${PROJECT_SOURCE_DIR}/src/mcpack2pb/serializer.cpp)

include(CompileProto)
set(PROTO_FILES idl_options.proto
                brpc/rtmp.proto
                brpc/rpc_dump.proto
                brpc/get_favicon.proto
                brpc/span.proto
                brpc/builtin_service.proto
                brpc/grpc_health_check.proto
                brpc/get_js.proto
                brpc/errno.proto
                brpc/nshead_meta.proto
                brpc/options.proto
                brpc/policy/baidu_rpc_meta.proto
                brpc/policy/hulu_pbrpc_meta.proto
                brpc/policy/public_pbrpc_meta.proto
                brpc/policy/sofa_pbrpc_meta.proto
                brpc/policy/mongo.proto
                brpc/trackme.proto
                brpc/streaming_rpc_meta.proto
                brpc/proto_base.proto)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/output/include/brpc)
set(PROTOC_FLAGS ${PROTOC_FLAGS} -I${PROTOBUF_INCLUDE_DIR})
compile_proto(PROTO_HDRS PROTO_SRCS ${PROJECT_BINARY_DIR}
                                    ${PROJECT_BINARY_DIR}/output/include
                                    ${PROJECT_SOURCE_DIR}/src
                                    "${PROTO_FILES}")
add_library(PROTO_LIB OBJECT ${PROTO_SRCS} ${PROTO_HDRS})

set(SOURCES
    ${BVAR_SOURCES}
    ${BTHREAD_SOURCES}
    ${JSON2PB_SOURCES}
    ${MCPACK2PB_SOURCES}
    ${BRPC_SOURCES}
    ${THRIFT_SOURCES}
    )

add_subdirectory(src)
if(BUILD_UNIT_TESTS)
    enable_testing()
    add_subdirectory(test)
endif()

if(BUILD_FUZZ_TESTS)
    if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        message(FATAL_ERROR "Fuzzing is only supported with clang")
    endif()
    if(NOT BUILD_UNIT_TESTS)
        message(FATAL_ERROR "BUILD_UNIT_TESTS must be enabled to build fuzz tests")
    endif()
endif()

if(BUILD_BRPC_TOOLS)
    add_subdirectory(tools)
endif()

file(COPY ${CMAKE_CURRENT_BINARY_DIR}/brpc/
        DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/output/include/brpc/
        FILES_MATCHING
        PATTERN "*.h"
        PATTERN "*.hpp"
        )
file(COPY ${PROJECT_SOURCE_DIR}/src/
        DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/output/include/
        FILES_MATCHING
        PATTERN "*.h"
        PATTERN "*.hpp"
        )
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/output/include/
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
        FILES_MATCHING
        PATTERN "*.h"
        PATTERN "*.hpp"
        )

# Install pkgconfig
configure_file(cmake/brpc.pc.in ${PROJECT_BINARY_DIR}/brpc.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/brpc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@brpc.apache.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: CONTRIBUTING.md
================================================
If you meet any problem or request a new feature, you're welcome to [create an issue](https://github.com/apache/brpc/issues/new/choose).

If you can solve any of [the issues](https://github.com/apache/brpc/issues), you're welcome to send the PR to us.

Before the PR:

* Make sure your code style conforms to [google C++ coding style](https://google.github.io/styleguide/cppguide.html). Indentation is preferred to be 4 spaces.
* The code appears where it should be. For example the code to support an extra protocol should not be put in general classes like server.cpp, channel.cpp, while a general modification would better not be hidden inside a very specific protocol.
* Has unittests.

After the PR:

* Make sure the [GitHub Actions](https://github.com/apache/brpc/actions) passed.

# Chinese version

如果你遇到问题或需要新功能,欢迎[创建issue](https://github.com/apache/brpc/issues/new/choose)。

如果你可以解决某个[issue](https://github.com/apache/brpc/issues), 欢迎发送PR。

发送PR前请确认:

* 你的代码符合[google C++代码规范](https://google.github.io/styleguide/cppguide.html)。缩进最好为4个空格。
* 代码出现的位置和其定位相符。比如对于某特定协议的扩展代码不该出现在server.cpp, channel.cpp这些较为通用的类中,而一些非常通用的改动也不该深藏在某个特定协议的cpp中。
* 有对应的单测代码。

提交PR后请确认:

* [GitHub Actions](https://github.com/apache/brpc/actions)成功通过。


================================================
FILE: MODULE.bazel
================================================
module(
  name = 'brpc',
  version = '1.16.0',
  compatibility_level = 1,
)

# --registry=https://bcr.bazel.build
bazel_dep(name = 'abseil-cpp', version = '20210324.2', repo_name = 'com_google_absl')
bazel_dep(name = 'bazel_skylib', version = '1.0.3')
bazel_dep(name = 'boringssl', version = '0.0.0-20211025-d4f1ab9')
bazel_dep(name = 'protobuf', version = '27.3', repo_name = 'com_google_protobuf')
bazel_dep(name = 'gflags', version = '2.2.2', repo_name = 'com_github_gflags_gflags')
bazel_dep(name = 'glog', version = '0.5.0', repo_name = 'com_github_google_glog')
bazel_dep(name = 'platforms', version = '0.0.4')
bazel_dep(name = "apple_support", version = "1.17.1")
bazel_dep(name = 'rules_cc', version = '0.0.1')
bazel_dep(name = 'rules_proto', version = '4.0.0')
bazel_dep(name = 'zlib', version = '1.3.1.bcr.5', repo_name = 'com_github_madler_zlib')
bazel_dep(name = 'libunwind', version = '1.8.1', repo_name = 'com_github_libunwind_libunwind')
bazel_dep(name = 'babylon', version = '1.4.4')

# --registry=https://baidu.github.io/babylon/registry
bazel_dep(name = 'leveldb', version = '1.23', repo_name = 'com_github_google_leveldb')
single_version_override(
    module_name = "leveldb",
    registry = "https://raw.githubusercontent.com/secretflow/bazel-registry/main",
)
bazel_dep(name = 'openssl', version = '3.3.2')
single_version_override(
    module_name = "openssl",
    version = "3.3.2.bcr.1",
    registry = "https://raw.githubusercontent.com/secretflow/bazel-registry/main",
)
bazel_dep(name = 'thrift', version = '0.21.0', repo_name = 'org_apache_thrift')

# test only
bazel_dep(name = 'googletest', version = '1.14.0.bcr.1', repo_name = 'com_google_googletest', dev_dependency = True)
bazel_dep(name = 'hedron_compile_commands', dev_dependency = True)
git_override(
    module_name = 'hedron_compile_commands',
    remote = 'https://github.com/hedronvision/bazel-compile-commands-extractor.git',
    commit = '1e08f8e0507b6b6b1f4416a9a22cf5c28beaba93', # Jun 28, 2024
)


================================================
FILE: README.md
================================================
[中文版](README_cn.md)

[![Linux Build Status](https://github.com/apache/brpc/actions/workflows/ci-linux.yml/badge.svg)](https://github.com/apache/brpc/actions/workflows/ci-linux.yml)
[![MacOs Build Status](https://github.com/apache/brpc/actions/workflows/ci-macos.yml/badge.svg)](https://github.com/apache/brpc/actions/workflows/ci-macos.yml)

![brpc logo (light)](docs/images/logo.png#gh-light-mode-only)
![brpc logo (dark)](docs/images/logo-white.png#gh-dark-mode-only)

[bRPC](https://brpc.apache.org/) is an Industrial-grade RPC framework using C++ Language, which is often used in  high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc.

### "bRPC" means "better RPC". 

You can use it to:
* Build a server that can talk in multiple protocols (**on same port**), or access all sorts of services
  * restful http/https, [h2](https://httpwg.org/specs/rfc9113.html)/[gRPC](https://grpc.io). using http/h2 in bRPC is much more friendly than [libcurl](https://curl.haxx.se/libcurl/). Access protobuf-based protocols with HTTP/h2+json, probably from another language.
  * [redis](docs/en/redis_client.md) and [memcached](docs/en/memcache_client.md), thread-safe, more friendly and performant than the official clients.
  * [rtmp](https://github.com/apache/brpc/blob/master/src/brpc/rtmp.h)/[flv](https://en.wikipedia.org/wiki/Flash_Video)/[hls](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), for building [streaming services](https://github.com/brpc/media-server).
  * hadoop_rpc (may be opensourced)
  * [rdma](https://en.wikipedia.org/wiki/Remote_direct_memory_access) support
  * [thrift](docs/en/thrift.md) support,  thread-safe, more friendly and performant than the official clients.
  * all sorts of protocols used in Baidu: [baidu_std](docs/cn/baidu_std.md), [streaming_rpc](docs/en/streaming_rpc.md), hulu_pbrpc, [sofa_pbrpc](https://github.com/baidu/sofa-pbrpc), nova_pbrpc, public_pbrpc, ubrpc and nshead-based ones.
  * Build [HA](https://en.wikipedia.org/wiki/High_availability) distributed services using an industrial-grade implementation of [RAFT consensus algorithm](https://raft.github.io) which is opensourced at [braft](https://github.com/brpc/braft)
* Servers can handle requests [synchronously](docs/en/server.md) or [asynchronously](docs/en/server.md#asynchronous-service).
* Clients can access servers [synchronously](docs/en/client.md#synchronus-call), [asynchronously](docs/en/client.md#asynchronous-call), [semi-synchronously](docs/en/client.md#semi-synchronous-call), or use [combo channels](docs/en/combo_channel.md) to simplify sharded or parallel accesses declaratively.
* Debug services [via http](docs/en/builtin_service.md), and run  [cpu](docs/cn/cpu_profiler.md), [heap](docs/cn/heap_profiler.md) and [contention](docs/cn/contention_profiler.md) profilers.
* Get [better latency and throughput](docs/en/overview.md#better-latency-and-throughput).
* [Extend bRPC](docs/en/new_protocol.md) with the protocols used in your organization quickly, or customize components, including [naming services](docs/cn/load_balancing.md#命名服务) (dns, zk, etcd), [load balancers](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)

# Try it!

* Read [overview](docs/en/overview.md) to know where bRPC can be used and its advantages.
* Read [getting started](docs/cn/getting_started.md) for building steps and play with [examples](https://github.com/apache/brpc/tree/master/example/).
* Docs:
  * [Performance benchmark](docs/cn/benchmark.md)
  * [bvar](docs/en/bvar.md)
    * [bvar_c++](docs/cn/bvar_c++.md)
  * [bthread](docs/cn/bthread.md)
    * [bthread or not](docs/cn/bthread_or_not.md)
    * [thread-local](docs/cn/thread_local.md)
    * [Execution Queue](docs/cn/execution_queue.md)
  * Client
    * [Basics](docs/en/client.md)
    * [Error code](docs/en/error_code.md)
    * [Combo channels](docs/en/combo_channel.md)
    * [Access http/h2](docs/en/http_client.md)
    * [Access gRPC](docs/en/http_derivatives.md#h2grpc)
    * [Access thrift](docs/en/thrift.md#client-accesses-thrift-server) 
    * [Access UB](docs/cn/ub_client.md)
    * [Streaming RPC](docs/en/streaming_rpc.md)
    * [Access redis](docs/en/redis_client.md)
    * [Access memcached](docs/en/memcache_client.md)
    * [Backup request](docs/en/backup_request.md)
    * [Dummy server](docs/en/dummy_server.md)
  * Server
    * [Basics](docs/en/server.md)
    * [Serve http/h2](docs/en/http_service.md)
    * [Serve gRPC](docs/en/http_derivatives.md#h2grpc)
    * [Serve thrift](docs/en/thrift.md#server-processes-thrift-requests)
    * [Serve Nshead](docs/cn/nshead_service.md)
    * [Debug server issues](docs/cn/server_debugging.md)
    * [Server push](docs/en/server_push.md)
    * [Avalanche](docs/cn/avalanche.md)
    * [Auto ConcurrencyLimiter](docs/cn/auto_concurrency_limiter.md)
    * [Media Server](https://github.com/brpc/media-server)
    * [json2pb](docs/cn/json2pb.md)
  * [Builtin Services](docs/en/builtin_service.md)
    * [status](docs/en/status.md)
    * [vars](docs/en/vars.md)
    * [connections](docs/cn/connections.md)
    * [flags](docs/cn/flags.md)
    * [rpcz](docs/cn/rpcz.md)
    * [cpu_profiler](docs/cn/cpu_profiler.md)
    * [heap_profiler](docs/cn/heap_profiler.md)
    * [contention_profiler](docs/cn/contention_profiler.md)
  * Tools
    * [rpc_press](docs/cn/rpc_press.md)
    * [rpc_replay](docs/cn/rpc_replay.md)
    * [rpc_view](docs/cn/rpc_view.md)
    * [benchmark_http](docs/cn/benchmark_http.md)
    * [parallel_http](docs/cn/parallel_http.md)
  * Others
    * [IOBuf](docs/en/iobuf.md)
    * [Streaming Log](docs/en/streaming_log.md)
    * [FlatMap](docs/cn/flatmap.md)
    * [bRPC introduction](docs/cn/brpc_intro.pptx)(training material)
    * [A tutorial on building large-scale services](docs/en/tutorial_on_building_services.pptx)(training material)
    * [bRPC internal](docs/en/brpc_internal.pptx)(training material)
  * RPC in depth
    * [New Protocol](docs/en/new_protocol.md)
    * [Atomic instructions](docs/en/atomic_instructions.md)
    * [IO](docs/en/io.md)
    * [Threading Overview](docs/en/threading_overview.md)
    * [Load Balancing](docs/cn/load_balancing.md)
    * [Locality-aware](docs/cn/lalb.md)
    * [Consistent Hashing](docs/cn/consistent_hashing.md)
    * [Memory Management](docs/cn/memory_management.md)
    * [Timer keeping](docs/cn/timer_keeping.md)
    * [bthread_id](docs/cn/bthread_id.md)
  * Use cases
    * [User cases](community/cases.md)

# Contribute code
Please refer to [here](CONTRIBUTING.md).

# Feedback and Getting involved
* Report bugs, ask questions or give suggestions by [Github Issues](https://github.com/apache/brpc/issues)
* Subscribe to the mailing list(dev-subscribe@brpc.apache.org) to get updated with the project

# Code of Conduct
We follow the code of conduct from Apache Software Foundation, please refer it here [Link](https://www.apache.org/foundation/policies/conduct)


================================================
FILE: README_cn.md
================================================
[English version](README.md)

[![Build Status](https://api.travis-ci.com/apache/brpc.svg?branch=master)](https://travis-ci.com/github/apache/brpc)

![brpc logo (light)](docs/images/logo.png#gh-light-mode-only)
![brpc logo (dark)](docs/images/logo-white.png#gh-dark-mode-only)

[bRPC](https://brpc.apache.org/)是用C++语言编写的工业级RPC框架,常用于搜索、存储、机器学习、广告、推荐等高性能系统。

### "bRPC"的含义是"better RPC"

你可以使用它:

* 搭建能在**一个端口**支持多协议的服务, 或访问各种服务
  * restful http/https, [h2](https://httpwg.org/specs/rfc9113.html)/[gRPC](https://grpc.io)。使用bRPC的http实现比[libcurl](https://curl.haxx.se/libcurl/)方便多了。从其他语言通过HTTP/h2+json访问基于protobuf的协议.
  * [redis](docs/cn/redis_client.md)和[memcached](docs/cn/memcache_client.md), 线程安全,比官方client更方便。
  * [rtmp](https://github.com/apache/brpc/blob/master/src/brpc/rtmp.h)/[flv](https://en.wikipedia.org/wiki/Flash_Video)/[hls](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), 可用于搭建[流媒体服务](https://github.com/brpc/media-server).
  * hadoop_rpc(可能开源)
  * 支持[rdma](https://en.wikipedia.org/wiki/Remote_direct_memory_access)
  * 支持[thrift](docs/cn/thrift.md) , 线程安全,比官方client更方便
  * 各种百度内使用的协议: [baidu_std](docs/cn/baidu_std.md), [streaming_rpc](docs/cn/streaming_rpc.md), hulu_pbrpc, [sofa_pbrpc](https://github.com/baidu/sofa-pbrpc), nova_pbrpc, public_pbrpc, ubrpc和使用nshead的各种协议.
  * 基于工业级的[RAFT算法](https://raft.github.io)实现搭建[高可用](https://en.wikipedia.org/wiki/High_availability)分布式系统,已在[braft](https://github.com/brpc/braft)开源。
* Server能[同步](docs/cn/server.md)或[异步](docs/cn/server.md#异步service)处理请求。
* Client支持[同步](docs/cn/client.md#同步访问)、[异步](docs/cn/client.md#异步访问)、[半同步](docs/cn/client.md#半同步),或使用[组合channels](docs/cn/combo_channel.md)简化复杂的分库或并发访问。
* [通过http界面](docs/cn/builtin_service.md)调试服务, 使用[cpu](docs/cn/cpu_profiler.md), [heap](docs/cn/heap_profiler.md), [contention](docs/cn/contention_profiler.md) profilers.
* 获得[更好的延时和吞吐](docs/cn/overview.md#更好的延时和吞吐).
* 把你组织中使用的协议快速地[加入bRPC](docs/cn/new_protocol.md),或定制各类组件, 包括[命名服务](docs/cn/load_balancing.md#命名服务) (dns, zk, etcd), [负载均衡](docs/cn/load_balancing.md#负载均衡) (rr, random, consistent hashing)

# 试一下!

* 通过[概述](docs/cn/overview.md)了解哪里可以用bRPC及其优势。
* 阅读[编译步骤](docs/cn/getting_started.md)了解如何开始使用, 之后可以运行一下[示例程序](https://github.com/apache/brpc/tree/master/example/).
* 文档:
  * [性能测试](docs/cn/benchmark.md)
  * [bvar](docs/cn/bvar.md)
    * [bvar_c++](docs/cn/bvar_c++.md)
  * [bthread](docs/cn/bthread.md)
    * [bthread or not](docs/cn/bthread_or_not.md)
    * [thread-local](docs/cn/thread_local.md)
    * [Execution Queue](docs/cn/execution_queue.md)
    * [bthread tracer](docs/cn/bthread_tracer.md)
  * Client
    * [基础功能](docs/cn/client.md)
    * [错误码](docs/cn/error_code.md)
    * [组合channels](docs/cn/combo_channel.md)
    * [访问http/h2](docs/cn/http_client.md)
    * [访问gRPC](docs/cn/http_derivatives.md#h2grpc)
    * [访问thrift](docs/cn/thrift.md#client端访问thrift-server)
    * [访问UB](docs/cn/ub_client.md)
    * [Streaming RPC](docs/cn/streaming_rpc.md)
    * [访问redis](docs/cn/redis_client.md)
    * [访问memcached](docs/cn/memcache_client.md)
    * [Backup request](docs/cn/backup_request.md)
    * [Dummy server](docs/cn/dummy_server.md)
  * Server
    * [基础功能](docs/cn/server.md)
    * [搭建http/h2服务](docs/cn/http_service.md)
    * [搭建gRPC服务](docs/cn/http_derivatives.md#h2grpc)
    * [搭建thrift服务](docs/cn/thrift.md#server端处理thrift请求)
    * [搭建Nshead服务](docs/cn/nshead_service.md)
    * [高效率排查server卡顿](docs/cn/server_debugging.md)
    * [推送](docs/cn/server_push.md)
    * [雪崩](docs/cn/avalanche.md)
    * [自适应限流](docs/cn/auto_concurrency_limiter.md)
    * [流媒体服务](https://github.com/brpc/media-server)
    * [json2pb](docs/cn/json2pb.md)
  * [内置服务](docs/cn/builtin_service.md)
    * [status](docs/cn/status.md)
    * [vars](docs/cn/vars.md)
    * [connections](docs/cn/connections.md)
    * [flags](docs/cn/flags.md)
    * [rpcz](docs/cn/rpcz.md)
    * [cpu_profiler](docs/cn/cpu_profiler.md)
    * [heap_profiler](docs/cn/heap_profiler.md)
    * [contention_profiler](docs/cn/contention_profiler.md)
  * 工具
    * [rpc_press](docs/cn/rpc_press.md)
    * [rpc_replay](docs/cn/rpc_replay.md)
    * [rpc_view](docs/cn/rpc_view.md)
    * [benchmark_http](docs/cn/benchmark_http.md)
    * [parallel_http](docs/cn/parallel_http.md)
  * 其他
    * [IOBuf](docs/cn/iobuf.md)
    * [Streaming Log](docs/cn/streaming_log.md)
    * [FlatMap](docs/cn/flatmap.md)
    * [bRPC外功修炼宝典](docs/cn/brpc_intro.pptx)(培训材料)
    * [搭建大型服务入门](docs/en/tutorial_on_building_services.pptx)(培训材料)
    * [bRPC内功修炼宝典](docs/en/brpc_internal.pptx)(培训材料)
  * 深入RPC
    * [New Protocol](docs/cn/new_protocol.md)
    * [Atomic instructions](docs/cn/atomic_instructions.md)
    * [IO](docs/cn/io.md)
    * [Threading Overview](docs/cn/threading_overview.md)
    * [Load Balancing](docs/cn/load_balancing.md)
    * [Locality-aware](docs/cn/lalb.md)
    * [Consistent Hashing](docs/cn/consistent_hashing.md)
    * [Memory Management](docs/cn/memory_management.md)
    * [Timer keeping](docs/cn/timer_keeping.md)
    * [bthread_id](docs/cn/bthread_id.md)
  * Use cases inside Baidu
    * [百度地图api入口](docs/cn/case_apicontrol.md)
    * [联盟DSP](docs/cn/case_baidu_dsp.md)
    * [ELF学习框架](docs/cn/case_elf.md)
    * [云平台代理服务](docs/cn/case_ubrpc.md)

# 贡献代码

请参考[这里](CONTRIBUTING.md#chinese-version)。

# 反馈和参与

* bug、疑惑、修改建议都欢迎提在[Github Issues](https://github.com/apache/brpc/issues)中
* 订阅邮件列表(dev-subscribe@brpc.apache.org)获得项目最新信息


# 行为准则
我们遵守Apache软件基金会的行为准则, 请参考如下 [链接](https://www.apache.org/foundation/policies/conduct)


================================================
FILE: WORKSPACE.bzlmod
================================================


================================================
FILE: config.h.in
================================================
// 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.

#ifndef  BUTIL_CONFIG_H
#define  BUTIL_CONFIG_H

#ifdef BRPC_WITH_GLOG
#undef BRPC_WITH_GLOG
#endif
#cmakedefine BRPC_WITH_GLOG @WITH_GLOG_VAL@

#endif  // BUTIL_CONFIG_H


================================================
FILE: config_brpc.sh
================================================
#!/usr/bin/env sh

# 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.

SYSTEM=$(uname -s)
if [ "$SYSTEM" = "Darwin" ]; then
    if [ -z "$BASH" ] || [ "$BASH" = "/bin/sh" ] ; then
        ECHO=echo
    else
        ECHO='echo -e'
    fi
    SO=dylib
    LDD="otool -L"
    if [ "$(getopt -V)" = " --" ]; then
        >&2 $ECHO "gnu-getopt must be installed and used"
        exit 1
    fi
else
    if [ -z "$BASH" ]; then
        ECHO=echo
    else
        ECHO='echo -e'
    fi
    SO=so
    LDD=ldd
fi

TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,nodebugsymbols,werror -n 'config_brpc' -- "$@"`
WITH_GLOG=0
WITH_THRIFT=0
WITH_RDMA=0
WITH_MESALINK=0
WITH_BTHREAD_TRACER=0
WITH_ASAN=0
BRPC_DEBUG_BTHREAD_SCHE_SAFETY=0
DEBUGSYMBOLS=-g
WERROR=
BRPC_DEBUG_LOCK=0

if [ $? != 0 ] ; then >&2 $ECHO "Terminating..."; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

if [ "$SYSTEM" = "Darwin" ]; then
    REALPATH=realpath
else
    REALPATH="readlink -f"
fi

# Convert to abspath always so that generated mk is include-able from everywhere
while true; do
    case "$1" in
        --headers ) HDRS_IN="$(${REALPATH} $2)"; shift 2 ;;
        --libs ) LIBS_IN="$(${REALPATH} $2)"; shift 2 ;;
        --cc ) CC=$2; shift 2 ;;
        --cxx ) CXX=$2; shift 2 ;;
        --with-glog ) WITH_GLOG=1; shift 1 ;;
        --with-thrift) WITH_THRIFT=1; shift 1 ;;
        --with-rdma) WITH_RDMA=1; shift 1 ;;
        --with-mesalink) WITH_MESALINK=1; shift 1 ;;
        --with-bthread-tracer) WITH_BTHREAD_TRACER=1; shift 1 ;;
        --with-debug-bthread-sche-safety ) BRPC_DEBUG_BTHREAD_SCHE_SAFETY=1; shift 1 ;;
        --with-debug-lock ) BRPC_DEBUG_LOCK=1; shift 1 ;;
        --with-asan) WITH_ASAN=1; shift 1 ;;
        --nodebugsymbols ) DEBUGSYMBOLS=; shift 1 ;;
        --werror ) WERROR=-Werror; shift 1 ;;
        -- ) shift; break ;;
        * ) break ;;
    esac
done

if [ -z "$CC" ]; then
    if [ ! -z "$CXX" ]; then
        >&2 $ECHO "--cc and --cxx must be both set or unset"
        exit 1
    fi
    CC=gcc
    CXX=g++
    if [ "$SYSTEM" = "Darwin" ]; then
        CC=clang
        CXX=clang++
    fi
elif [ -z "$CXX" ]; then
    >&2 $ECHO "--cc and --cxx must be both set or unset"
    exit 1
fi

GCC_VERSION=$(CXX=$CXX tools/print_gcc_version.sh)
if [ $GCC_VERSION -gt 0 ] && [ $GCC_VERSION -lt 40800 ]; then
    >&2 $ECHO "GCC is too old, please install a newer version supporting C++11"
    exit 1
fi

if [ -z "$HDRS_IN" ] || [ -z "$LIBS_IN" ]; then
    >&2 $ECHO "config_brpc: --headers=HDRPATHS --libs=LIBPATHS must be specified"
    exit 1
fi

find_dir_of_lib() {
    local lib=$(find ${LIBS_IN} -name "lib${1}.a" -o -name "lib${1}.$SO" 2>/dev/null | head -n1)
    if [ ! -z "$lib" ]; then
        dirname $lib
    fi
}
find_dir_of_lib_or_die() {
    local dir=$(find_dir_of_lib $1)
    if [ -z "$dir" ]; then
        >&2 $ECHO "Fail to find $1 from --libs"
        exit 1
    else
        $ECHO $dir
    fi
}

find_bin() {
    TARGET_BIN=$(find -L ${LIBS_IN} -type f -name "$1" 2>/dev/null | head -n1)
    if [ ! -z "$TARGET_BIN" ]; then
        $ECHO $TARGET_BIN
    else
        which "$1" 2>/dev/null
    fi
}
find_bin_or_die() {
    TARGET_BIN=$(find_bin "$1")
    if [ ! -z "$TARGET_BIN" ]; then
        $ECHO $TARGET_BIN
    else
        >&2 $ECHO "Fail to find $1"
        exit 1
    fi
}

find_dir_of_header() {
    find -L ${HDRS_IN} -path "*/$1" | head -n1 | sed "s|$1||g"
}

find_dir_of_header_excluding() {
    find -L ${HDRS_IN} -path "*/$1" | grep -v "$2\$" | head -n1 | sed "s|$1||g"
}

find_dir_of_header_or_die() {
    if [ -z "$2" ]; then
        local dir=$(find_dir_of_header $1)
    else
        local dir=$(find_dir_of_header_excluding $1 $2)
    fi
    if [ -z "$dir" ]; then
        >&2 $ECHO "Fail to find $1 from --headers"
        exit 1
    fi
    $ECHO $dir
}

if [ "$SYSTEM" = "Darwin" ]; then
    if [ -d "/usr/local/opt/openssl" ]; then
        LIBS_IN="/usr/local/opt/openssl/lib $LIBS_IN"
        HDRS_IN="/usr/local/opt/openssl/include $HDRS_IN"
    elif [ -d "/opt/homebrew/Cellar" ]; then
        LIBS_IN="/opt/homebrew/Cellar $LIBS_IN"
        HDRS_IN="/opt/homebrew/Cellar $HDRS_IN"
    fi
fi

# User specified path of openssl, if not given it's empty
OPENSSL_LIB=$(find_dir_of_lib ssl)
# Inconvenient to check these headers in baidu-internal
#PTHREAD_HDR=$(find_dir_of_header_or_die pthread.h)
OPENSSL_HDR=$(find_dir_of_header_or_die openssl/ssl.h mesalink/openssl/ssl.h)

if [ $WITH_MESALINK != 0 ]; then
    MESALINK_HDR=$(find_dir_of_header_or_die mesalink/openssl/ssl.h)
    OPENSSL_HDR="$OPENSSL_HDR\n$MESALINK_HDR"
fi

STATIC_LINKINGS=
DYNAMIC_LINKINGS="-lpthread -lssl -lcrypto -ldl -lz"

if [ $WITH_MESALINK != 0 ]; then
    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lmesalink"
fi

if [ "$SYSTEM" = "Linux" ]; then
    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lrt"
fi
if [ "$SYSTEM" = "Darwin" ]; then
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreFoundation"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreGraphics"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreData"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreText"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Security"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Foundation"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_MallocExtension_ReleaseFreeMemory"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStart"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStop"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,__Z13GetStackTracePPvii"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_RegisterThriftProtocol"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_mallctl"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_malloc_stats_print"
fi
append_linking() {
    if [ -f $1/lib${2}.a ]; then
        if [ "$SYSTEM" = "Darwin" ]; then
            # *.a must be explicitly specified in clang
            STATIC_LINKINGS="$STATIC_LINKINGS $1/lib${2}.a"
        else
            STATIC_LINKINGS="$STATIC_LINKINGS -l$2"
        fi
        export STATICALLY_LINKED_$2=1
    else
        DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -l$2"
        export STATICALLY_LINKED_$2=0
    fi
}

GFLAGS_LIB=$(find_dir_of_lib_or_die gflags)
append_linking $GFLAGS_LIB gflags

PROTOBUF_LIB=$(find_dir_of_lib_or_die protobuf)
append_linking $PROTOBUF_LIB protobuf

LEVELDB_LIB=$(find_dir_of_lib_or_die leveldb)
# required by leveldb
if [ -f $LEVELDB_LIB/libleveldb.a ]; then
    if [ -f $LEVELDB_LIB/libleveldb.$SO ]; then
        if $LDD $LEVELDB_LIB/libleveldb.$SO | grep -q libsnappy; then
            SNAPPY_LIB=$(find_dir_of_lib snappy)
            REQUIRE_SNAPPY="yes"
        fi
    fi
    if [ -z "$REQUIRE_SNAPPY" ]; then
        if [ "$SYSTEM" = "Darwin" ]; then
	        STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a"
        else
	        STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb"
        fi
    elif [ -f $SNAPPY_LIB/libsnappy.a ]; then
        if [ "$SYSTEM" = "Darwin" ]; then
	        STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a $SNAPPY_LIB/libsnappy.a"
        else
	        STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb -lsnappy"
        fi
    else
	    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
    fi
else
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
fi

PROTOC=$(find_bin_or_die protoc)

GFLAGS_HDR=$(find_dir_of_header_or_die gflags/gflags.h)

PROTOBUF_HDR=$(find_dir_of_header_or_die google/protobuf/message.h)
PROTOBUF_VERSION=$(grep '#define GOOGLE_PROTOBUF_VERSION [0-9]\+' $PROTOBUF_HDR/google/protobuf/stubs/common.h | awk '{print $3}')
if [ "$PROTOBUF_VERSION" -ge 4022000 ]; then
    # from v22, utf8_validity should be explicitly linked
    # https://github.com/protocolbuffers/protobuf/blob/a847a8dc4ba1d99e7ba917146c84438b4de7d085/cmake/libprotobuf.cmake#L47
    UTF8_VALIDITY_LIB=$(find_dir_of_lib utf8_validity)
    append_linking "$UTF8_VALIDITY_LIB" utf8_validity

    ABSL_HDR=$(find_dir_of_header_or_die absl/base/config.h)
    ABSL_LIB=$(find_dir_of_lib_or_die absl_strings)
    ABSL_TARGET_NAMES="
        absl_bad_optional_access
        absl_bad_variant_access
        absl_base
        absl_city
        absl_civil_time
        absl_cord
        absl_cord_internal
        absl_cordz_functions
        absl_cordz_handle
        absl_cordz_info
        absl_crc32c
        absl_crc_cord_state
        absl_crc_cpu_detect
        absl_crc_internal
        absl_debugging_internal
        absl_demangle_internal
        absl_die_if_null
        absl_examine_stack
        absl_exponential_biased
        absl_flags
        absl_flags_commandlineflag
        absl_flags_commandlineflag_internal
        absl_flags_config
        absl_flags_internal
        absl_flags_marshalling
        absl_flags_private_handle_accessor
        absl_flags_program_name
        absl_flags_reflection
        absl_graphcycles_internal
        absl_hash
        absl_hashtablez_sampler
        absl_int128
        absl_kernel_timeout_internal
        absl_leak_check
        absl_log_entry
        absl_log_globals
        absl_log_initialize
        absl_log_internal_check_op
        absl_log_internal_conditions
        absl_log_internal_format
        absl_log_internal_globals
        absl_log_internal_log_sink_set
        absl_log_internal_message
        absl_log_internal_nullguard
        absl_log_internal_proto
        absl_log_severity
        absl_log_sink
        absl_low_level_hash
        absl_malloc_internal
        absl_raw_hash_set
        absl_raw_logging_internal
        absl_spinlock_wait
        absl_stacktrace
        absl_status
        absl_statusor
        absl_str_format_internal
        absl_strerror
        absl_string_view
        absl_strings
        absl_strings_internal
        absl_symbolize
        absl_synchronization
        absl_throw_delegate
        absl_time
        absl_time_zone
    "
    for i in $ABSL_TARGET_NAMES; do
        # ignore interface targets
        if [ -n "$(find_dir_of_lib $i)" ]; then
            append_linking "$ABSL_LIB" "$i"
        fi
    done
    CXXFLAGS="-std=c++17"
else
    CXXFLAGS="-std=c++0x"
fi

CPPFLAGS=

if [ $WITH_ASAN != 0 ]; then
  CPPFLAGS="${CPPFLAGS} -fsanitize=address"
  DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -fsanitize=address"
fi

LEVELDB_HDR=$(find_dir_of_header_or_die leveldb/db.h)

if [ $WITH_BTHREAD_TRACER != 0 ]; then
    if [ "$SYSTEM" != "Linux" ] || [ "$(uname -m)" != "x86_64" ]; then
        >&2 $ECHO "bthread tracer is only supported on Linux x86_64 platform"
        exit 1
    fi
    LIBUNWIND_HDR=$(find_dir_of_header_or_die libunwind.h)
    LIBUNWIND_LIB=$(find_dir_of_lib_or_die unwind)
    ABSL_HDR=$(find_dir_of_header_or_die absl/base/config.h)
    ABSL_LIB=$(find_dir_of_lib_or_die absl_symbolize)

    CPPFLAGS="${CPPFLAGS} -DBRPC_BTHREAD_TRACER"

    if [ -f "$LIBUNWIND_LIB/libunwind.$SO" ]; then
        DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lunwind -lunwind-x86_64"
    else
        STATIC_LINKINGS="$STATIC_LINKINGS -lunwind -lunwind-x86_64"
    fi
    if [ -f "$ABSL_LIB/libabsl_base.$SO" ]; then
        DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -labsl_stacktrace -labsl_symbolize -labsl_debugging_internal -labsl_demangle_internal -labsl_malloc_internal -labsl_raw_logging_internal -labsl_spinlock_wait -labsl_base"
    else
        STATIC_LINKINGS="$STATIC_LINKINGS -labsl_stacktrace -labsl_symbolize -labsl_debugging_internal -labsl_demangle_internal -labsl_malloc_internal -labsl_raw_logging_internal -labsl_spinlock_wait -labsl_base"
    fi
fi

HDRS=$($ECHO "$LIBUNWIND_HDR\n$GFLAGS_HDR\n$PROTOBUF_HDR\n$ABSL_HDR\n$LEVELDB_HDR\n$OPENSSL_HDR" | sort | uniq)
LIBS=$($ECHO "$LIBUNWIND_LIB\n$GFLAGS_LIB\n$PROTOBUF_LIB\n$ABSL_LIB\n$LEVELDB_LIB\n$OPENSSL_LIB\n$SNAPPY_LIB" | sort | uniq)

absent_in_the_list() {
    TMP=`$ECHO "$1\n$2" | sort | uniq`
    if [ "${TMP}" = "$2" ]; then
        return 1
    fi
    return 0
}

OUTPUT_CONTENT="# Generated by config_brpc.sh, don't modify manually"
append_to_output() {
    OUTPUT_CONTENT="${OUTPUT_CONTENT}\n$*"
}
# $1: libname, $2: indentation
append_to_output_headers() {
    if absent_in_the_list "$1" "$HDRS"; then
        append_to_output "${2}HDRS+=$1"
        HDRS=`$ECHO "${HDRS}\n$1" | sort | uniq`
    fi
}
# $1: libname, $2: indentation
append_to_output_libs() {
    if absent_in_the_list "$1" "$LIBS"; then
        append_to_output "${2}LIBS+=$1"
        LIBS=`$ECHO "${LIBS}\n$1" | sort | uniq`
    fi
}
# $1: libdir, $2: libname, $3: indentation
append_to_output_linkings() {
    if [ -f $1/lib$2.a ]; then
        append_to_output_libs $1 $3
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "${3}STATIC_LINKINGS+=$1/lib$2.a"
        else
            append_to_output "${3}STATIC_LINKINGS+=-l$2"
        fi
        export STATICALLY_LINKED_$2=1
    else
        append_to_output_libs $1 $3
        append_to_output "${3}DYNAMIC_LINKINGS+=-l$2"
        export STATICALLY_LINKED_$2=0
    fi
}

#can't use \n in texts because sh does not support -e
append_to_output "SYSTEM=$SYSTEM"
append_to_output "HDRS=$($ECHO $HDRS)"
append_to_output "LIBS=$($ECHO $LIBS)"
append_to_output "PROTOC=$PROTOC"
append_to_output "PROTOBUF_HDR=$PROTOBUF_HDR"
append_to_output "CC=$CC"
append_to_output "CXX=$CXX"
append_to_output "GCC_VERSION=$GCC_VERSION"
append_to_output "STATIC_LINKINGS=$STATIC_LINKINGS"
append_to_output "DYNAMIC_LINKINGS=$DYNAMIC_LINKINGS"

# CPP means C PreProcessing, not C PlusPlus
CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_GLOG=$WITH_GLOG -DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=$BRPC_DEBUG_BTHREAD_SCHE_SAFETY -DBRPC_DEBUG_LOCK=$BRPC_DEBUG_LOCK"

# Avoid over-optimizations of TLS variables by GCC>=4.8
# See: https://github.com/apache/brpc/issues/1693
CPPFLAGS="${CPPFLAGS} -D__const__=__unused__"

if [ ! -z "$DEBUGSYMBOLS" ]; then
    CPPFLAGS="${CPPFLAGS} $DEBUGSYMBOLS"
fi
if [ ! -z "$WERROR" ]; then
    CPPFLAGS="${CPPFLAGS} $WERROR"
fi
if [ "$SYSTEM" = "Darwin" ]; then
    CPPFLAGS="${CPPFLAGS} -Wno-deprecated-declarations -Wno-inconsistent-missing-override"
    version=`sw_vers -productVersion | awk -F '.' '{print $1 "." $2}'`
    if [[ `echo "$version<10.12" | bc -l` == 1 ]]; then
        CPPFLAGS="${CPPFLAGS} -DNO_CLOCK_GETTIME_IN_MAC"
    fi
fi

if [ $WITH_THRIFT != 0 ]; then
    THRIFT_LIB=$(find_dir_of_lib_or_die thriftnb)
    THRIFT_HDR=$(find_dir_of_header_or_die thrift/Thrift.h)
    append_to_output_libs "$THRIFT_LIB"
    append_to_output_headers "$THRIFT_HDR"

    CPPFLAGS="${CPPFLAGS} -DENABLE_THRIFT_FRAMED_PROTOCOL"

    if [ -f "$THRIFT_LIB/libthriftnb.$SO" ]; then
        append_to_output "DYNAMIC_LINKINGS+=-lthriftnb -levent -lthrift"
    else
        append_to_output "STATIC_LINKINGS+=-lthriftnb"
    fi
    # get thrift version
    thrift_version=$(thrift --version | awk '{print $3}')
    major=$(echo "$thrift_version" | awk -F '.' '{print $1}')
    minor=$(echo "$thrift_version" | awk -F '.' '{print $2}')
    if [ $((major)) -eq 0 -a $((minor)) -lt 11 ]; then
        CPPFLAGS="${CPPFLAGS} -D_THRIFT_VERSION_LOWER_THAN_0_11_0_"
        echo "less"
    else
        echo "greater"
    fi
fi

if [ $WITH_RDMA != 0 ]; then
    RDMA_LIB=$(find_dir_of_lib_or_die ibverbs)
    RDMA_HDR=$(find_dir_of_header_or_die infiniband/verbs.h)
    append_to_output_libs "$RDMA_LIB"
    append_to_output_headers "$RDMA_HDR"

    CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_RDMA"

    append_to_output "DYNAMIC_LINKINGS+=-libverbs"
    append_to_output "WITH_RDMA=1"
fi

if [ $WITH_MESALINK != 0 ]; then
    CPPFLAGS="${CPPFLAGS} -DUSE_MESALINK"
fi

append_to_output "CPPFLAGS=${CPPFLAGS}"
append_to_output "# without the flag, linux+arm64 may crash due to folding on TLS.
ifeq (\$(CC),gcc)
  ifeq (\$(shell uname -p),aarch64) 
    CPPFLAGS+=-fno-gcse
  endif
endif
"

append_to_output "CXXFLAGS=${CXXFLAGS}"

append_to_output "ifeq (\$(NEED_LIBPROTOC), 1)"
PROTOC_LIB=$(find $PROTOBUF_LIB -name "libprotoc.*" | head -n1)
if [ -z "$PROTOC_LIB" ]; then
    append_to_output "   \$(error \"Fail to find libprotoc\")"
else
    # libprotobuf and libprotoc must be linked same statically or dynamically
    # otherwise the bin will crash.
    if [ $STATICALLY_LINKED_protobuf -gt 0 ]; then
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "    STATIC_LINKINGS+=$(find $PROTOBUF_LIB -name "libprotoc.a" | head -n1)"
        else
            append_to_output "    STATIC_LINKINGS+=-lprotoc"
        fi
    else
        append_to_output "    DYNAMIC_LINKINGS+=-lprotoc"
    fi
fi
append_to_output "endif"

OLD_HDRS=$HDRS
OLD_LIBS=$LIBS
append_to_output "ifeq (\$(NEED_GPERFTOOLS), 1)"
# required by cpu/heap profiler
TCMALLOC_LIB=$(find_dir_of_lib tcmalloc_and_profiler)
if [ -z "$TCMALLOC_LIB" ]; then
    append_to_output "    \$(error \"Fail to find gperftools\")"
elif [ $WITH_ASAN != 0 ]; then
    append_to_output "    \$(error \"gperftools is not compatible with ASAN\")"
else
    append_to_output "    CPPFLAGS+=-DBRPC_ENABLE_CPU_PROFILER"
    append_to_output_libs "$TCMALLOC_LIB" "    "
    if [ -f $TCMALLOC_LIB/libtcmalloc.$SO ]; then
        append_to_output "    DYNAMIC_LINKINGS+=-ltcmalloc_and_profiler"
    else
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "    STATIC_LINKINGS+=$TCMALLOC_LIB/libtcmalloc.a"
        else
            append_to_output "    STATIC_LINKINGS+=-ltcmalloc_and_profiler"
        fi
    fi
fi
append_to_output "endif"

if [ $WITH_GLOG != 0 ]; then
    GLOG_LIB=$(find_dir_of_lib_or_die glog)
    GLOG_HDR=$(find_dir_of_header_or_die glog/logging.h windows/glog/logging.h)
    append_to_output_libs "$GLOG_LIB"
    append_to_output_headers "$GLOG_HDR"
    if [ -f "$GLOG_LIB/libglog.$SO" ]; then
        append_to_output "DYNAMIC_LINKINGS+=-lglog"
    else
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "STATIC_LINKINGS+=$GLOG_LIB/libglog.a"
        else
            append_to_output "STATIC_LINKINGS+=-lglog"
        fi
    fi
fi

# required by UT
#gtest
GTEST_LIB=$(find_dir_of_lib gtest)
HDRS=$OLD_HDRS
LIBS=$OLD_LIBS
append_to_output "ifeq (\$(NEED_GTEST), 1)"
if [ -z "$GTEST_LIB" ]; then
    append_to_output "    \$(error \"Fail to find gtest\")"
else
    GTEST_HDR=$(find_dir_of_header_or_die gtest/gtest.h)
    append_to_output_libs $GTEST_LIB "    "
    append_to_output_headers $GTEST_HDR "    "
    append_to_output_linkings $GTEST_LIB gtest "    "
    append_to_output_linkings $GTEST_LIB gtest_main "    "
fi
append_to_output "endif"

# generate src/butil/config.h
cat << EOF > src/butil/config.h
// This file is auto-generated by $(basename "$0"). DON'T edit it!
#ifndef  BUTIL_CONFIG_H
#define  BUTIL_CONFIG_H

#ifdef BRPC_WITH_GLOG
#undef BRPC_WITH_GLOG
#endif
#define BRPC_WITH_GLOG $WITH_GLOG

#endif  // BUTIL_CONFIG_H
EOF

# write to config.mk
$ECHO "$OUTPUT_CONTENT" > config.mk
Download .txt
gitextract_27i_xhfr/

├── BUILD.bazel
├── CHANGES.md
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── MODULE.bazel
├── README.md
├── README_cn.md
├── WORKSPACE.bzlmod
├── config.h.in
└── config_brpc.sh
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (88K chars).
[
  {
    "path": "BUILD.bazel",
    "chars": 18132,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE f"
  },
  {
    "path": "CHANGES.md",
    "chars": 2284,
    "preview": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the N"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 23955,
    "preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE f"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3216,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1234,
    "preview": "If you meet any problem or request a new feature, you're welcome to [create an issue](https://github.com/apache/brpc/iss"
  },
  {
    "path": "MODULE.bazel",
    "chars": 1991,
    "preview": "module(\n  name = 'brpc',\n  version = '1.16.0',\n  compatibility_level = 1,\n)\n\n# --registry=https://bcr.bazel.build\nbazel_"
  },
  {
    "path": "README.md",
    "chars": 6932,
    "preview": "[中文版](README_cn.md)\n\n[![Linux Build Status](https://github.com/apache/brpc/actions/workflows/ci-linux.yml/badge.svg)](ht"
  },
  {
    "path": "README_cn.md",
    "chars": 5463,
    "preview": "[English version](README.md)\n\n[![Build Status](https://api.travis-ci.com/apache/brpc.svg?branch=master)](https://travis-"
  },
  {
    "path": "WORKSPACE.bzlmod",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "config.h.in",
    "chars": 965,
    "preview": "// Licensed to the Apache Software Foundation (ASF) under one or more\n// contributor license agreements.  See the NOTICE"
  },
  {
    "path": "config_brpc.sh",
    "chars": 19580,
    "preview": "#!/usr/bin/env sh\n\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements"
  }
]

About this extraction

This page contains the full source code of the apache/brpc GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (81.8 KB), approximately 24.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!