最近因为想给Llama.cpp加一个grpc入口,折腾了一圈GRPC运行时的安装,起初参考GRPC官方的Build from source,未果。
主要原因是基于cmake的安装和调用遭遇到几次大的问题。
一是vscode编译器集成的问题,二是cmake的find_package的查找路径问题等,最终没有成功,后来进一步搜索,找到一个很简单的方法:
使用vcpkg安装
vcpkg是微软官方出的包管理器,可以配合cmake来使用
microsoft/vcpkg: C++ Library Manager for Windows, Linux, and MacOS (github.com)https://github.com/microsoft/vcpkg首先我们需要完成安装(建议阅读官方中文指引),在完成基础软件包下载之后,依次执行以下操作
git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat
就可以完成下载和安装。最好选一个空间比较大的磁盘来执行这个命令,因为这个目录也会作为vcpkg下载的各个包的安装路径。
执行完之后,把.\vcpkg加入环境变量里的PATH里,下一次就可以直接执行了。
使用vcpkg安装grpc
安装grpc
vcpkg install grpc:x64-windows
最新版本是默认x64了,也可以直接输入
vcpkg install grpc
这个默认设置似乎是最近才改的,我看网上很多材料是要加x64-windows后缀的,大家可以注意以下安装过程中的提示。
安装protobuf
vcpkg install protobuf protobuf:x64-windows
在cpp项目中使用安装包
安装完之后,如果想在cmake项目中直接通过find_package找到这个包,需要有两个工作要做。
执行以下操作
vcpkg integrate install
执行之后,会有提示出现
Applied user-wide integration for this vcpkg root.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=E:/xxx/vcpkg.cmake"
All MSBuild C++ projects can now #include any installed libraries. Linking will be handled automatically. Installing new libraries will make them instantly available.
绿色部分是我们执行cmake构建的时候需要附加的参数,例如我运行llama会需要做
cmake .. -DCMAKE_TOOLCHAIN_FILE=E:/xxx/vcpkg.cmake
构建完成之后的编译阶段就和原始的一样了。
引用相关头文件
grpc的cmakefile里主要要包含以下部分,这是我为llama.cpp加的grpc-server的cmakefile
# 生成文件的名称
set(TARGET grpc-server)
# 引入包
find_package(Protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)
# 引入protoc和grpc_cpp_plugin程序,在编译proto文件的阶段需要使用
find_program(_PROTOBUF_PROTOC protoc)
find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
# 引入必要的头文件搜索路径
# 生成路径,因为proto编译后的c和h文件在这个目录,所以必须包含
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# protobuf头文件路径
include_directories(${Protobuf_INCLUDE_DIRS})
message(STATUS "Using protobuf ${Protobuf_VERSION} ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}")
# 寻找proto文件,按你的文件名称修改
get_filename_component(hw_proto "./message.proto" ABSOLUTE)
# 寻找路径
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/message.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/message.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/message.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/message.grpc.pb.h")
# 编译proto得到h和c文件
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out "${CMAKE_CURRENT_BINARY_DIR}"
-I "${hw_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${hw_proto}"
DEPENDS "${hw_proto}")
# 添加生成的文件,作为类库
add_library(hw_grpc_proto
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto_srcs}
${hw_proto_hdrs})
add_executable(${TARGET} grpc-server.cpp)
target_link_libraries(${TARGET} PRIVATE common llama ${CMAKE_THREAD_LIBS_INIT} hw_grpc_proto absl::flags
absl::flags_parse
gRPC::grpc++_reflection
gRPC::grpc++
protobuf::libprotobuf)
target_compile_features(${TARGET} PRIVATE cxx_std_11)
if(TARGET BUILD_INFO)
add_dependencies(${TARGET} BUILD_INFO)
endif()