在window下使用visual studio + cmake gui 源码编译 gRPC
本文介绍了在Windows环境下使用CMake GUI和Visual Studio编译gRPC库的完整步骤。首先需要准备Visual Studio、CMake GUI、gRPC源码和NASM工具。通过git拉取指定版本分支并初始化子模块后,在CMake GUI中配置源码路径、输出目录及关键参数(如动态/静态库选项、安装路径和语言支持)。完成配置后,在Visual Studio中生成解决方案并安装。
·
准备工作
- 下载visual studio
- 下载cmake gui
- 拉取gRPC源码
- 下载nasm
- 仓库处理
git clone git@github.com:grpc/grpc.git #切换到你想要的一个版本分支,如下 git checkout -b v1.6 origin/v1.60.x #初始化并拉取子仓库 git submodule update --init --recursive #要是一起拉不下就一个个拉 #使用status查看状态 git submodule status
cmake gui 配置

- 按照上述步骤
- 选择源码文件夹
- 选择配置后的文件夹
- 开始配置
- 完成配置
- 开始编译
- 说一些重要的配置参数

- 勾选编译为动态库,不勾就是为静态库
- 安装后的路径

- grpc默认的配置是build各种语言,这样会导致编译出来的库非常大,这里我们只选择我们的开发语言
- 构建proto库
visual studio 操作
- 上述步骤5后打开vs,右键生成

- 生成的时间有点久,生成完成后没有报错全部成功后,就可以安装了

- 这步完成后就可以到我们在cmake gui时配置的文件路径下找到对应的库了,结构如下

cmakelist 编写
- 这里我直接贴上我的demo
- 新建一个
grpc.cmake的文件,代码如下
cmake_minimum_required(VERSION 3.16)
if(MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
endif()
find_package(Threads REQUIRED)
if(GRPC_AS_SUBMODULE)
add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL)
message(STATUS "Using gRPC via add_subdirectory.")
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_ORCA_SERVICE grpcpp_orca_service)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
elseif(GRPC_FETCHCONTENT)
message(STATUS "Using gRPC via add_subdirectory (FetchContent).")
include(FetchContent)
FetchContent_Declare(
grpc
GIT_REPOSITORY https://github.com/grpc/grpc.git
GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE)
FetchContent_MakeAvailable(grpc)
set(_PROTOBUF_LIBPROTOBUF libprotobuf)
set(_REFLECTION grpc++_reflection)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()
else()
option(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_REFLECTION gRPC::grpc++_reflection)
if(CMAKE_CROSSCOMPILING)
find_program(_PROTOBUF_PROTOC protoc)
else()
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_GRPC_GRPCPP gRPC::grpc++)
if(CMAKE_CROSSCOMPILING)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
else()
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
endif()
endif()
# ================== gRPC生成函数 ==================
function(grpc_generate_cpp SRC_FILES HDR_FILES)
if(NOT ARGN)
message(SEND_ERROR "Error: grpc_generate_cpp() called without any proto files")
return()
endif()
set(${SRC_FILES})
set(${HDR_FILES})
foreach(proto_file ${ARGN})
get_filename_component(proto_name ${proto_file} NAME_WE)
get_filename_component(proto_full_path ${proto_file} ABSOLUTE)
file(RELATIVE_PATH proto_relative_path ${CMAKE_CURRENT_SOURCE_DIR} ${proto_full_path})
get_filename_component(relative_directory ${proto_relative_path} DIRECTORY)
if(NOT relative_directory)
set(proto_name_full "${proto_name}")
else()
set(proto_name_full "${relative_directory}/${proto_name}")
endif()
set(generated_pb_cc "${CMAKE_CURRENT_BINARY_DIR}/${proto_name_full}.pb.cc")
set(generated_pb_h "${CMAKE_CURRENT_BINARY_DIR}/${proto_name_full}.pb.h")
set(generated_grpc_pb_cc "${CMAKE_CURRENT_BINARY_DIR}/${proto_name_full}.grpc.pb.cc")
set(generated_grpc_pb_h "${CMAKE_CURRENT_BINARY_DIR}/${proto_name_full}.grpc.pb.h")
list(APPEND ${SRC_FILES} "${generated_pb_cc}")
list(APPEND ${HDR_FILES} "${generated_pb_h}")
list(APPEND ${SRC_FILES} "${generated_grpc_pb_cc}")
list(APPEND ${HDR_FILES} "${generated_grpc_pb_h}")
add_custom_command(
OUTPUT "${generated_pb_cc}" "${generated_pb_h}"
"${generated_grpc_pb_cc}" "${generated_grpc_pb_h}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out=${CMAKE_CURRENT_BINARY_DIR}
--cpp_out=${CMAKE_CURRENT_BINARY_DIR}
--plugin=protoc-gen-grpc=${_GRPC_CPP_PLUGIN_EXECUTABLE}
-I ${CMAKE_CURRENT_SOURCE_DIR}
${proto_relative_path}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${proto_file}
COMMENT "Generating gRPC sources for ${proto_file}"
)
endforeach()
set_source_files_properties(${${SRC_FILES}} ${${HDR_FILES}} PROPERTIES GENERATED TRUE)
set(${SRC_FILES} ${${SRC_FILES}} PARENT_SCOPE)
set(${HDR_FILES} ${${HDR_FILES}} PARENT_SCOPE)
endfunction()
# ================== 自动查找所有proto文件 ==================
file(GLOB_RECURSE PROTO_FILES "${CMAKE_CURRENT_SOURCE_DIR}/proto/*.proto")
if(NOT PROTO_FILES)
message(WARNING "No proto files found in ${CMAKE_CURRENT_SOURCE_DIR}/proto/")
endif()
# ================== 生成所有proto文件 ==================
grpc_generate_cpp(GRPC_PROTO_SRC GRPC_PROTO_HDR ${PROTO_FILES})
# ================== 创建gRPC库 ==================
add_library(hmi_grpc_proto STATIC
${GRPC_PROTO_SRC}
)
target_include_directories(hmi_grpc_proto PUBLIC
${CMAKE_CURRENT_BINARY_DIR} # 生成的pb.h文件位置
)
target_link_libraries(hmi_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF}
)
cmakelist如下
cmake_minimum_required(VERSION 3.16)
project(gRPC_test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置gRPC根目录
set(GRPC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/third_party/grpc")
# 添加自定义查找路径
list(APPEND CMAKE_PREFIX_PATH "${GRPC_ROOT}")
include(grpc.cmake)
# 添加可执行文件
add_executable(server src/server.cpp)
add_executable(client src/client.cpp)
# 包含目录
target_include_directories(server PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/proto
)
target_include_directories(client PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/proto
)
# 链接库
target_link_libraries(server PRIVATE
hmi_grpc_proto
)
target_link_libraries(client PRIVATE
hmi_grpc_proto
)
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)