最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Protobuf在Cmake中的正確使用方法詳解

 更新時間:2021年03月15日 10:13:59   作者:老潘博客  
這篇文章主要介紹了Protobuf在Cmake中的正確使用方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

Protobuf是google開發(fā)的一個序列化和反序列化的協(xié)議庫,我們可以自己設計傳遞數(shù)據(jù)的格式,通過.proto文件定義我們的要傳遞的數(shù)據(jù)格式。例如,在深度學習中常用的ONNX交換模型就是使用.proto編寫的。我們可以通過多種前端(MNN、NCNN、TVM的前端)去讀取這個.onnx這個模型,但是首先你要安裝protobuf。

在之前的博文中已經簡單介紹了onnx,其中onnx.proto就代表了onnx模型的基本數(shù)據(jù)結構。一般來說,protobuf經常搭配Cmake使用,Cmake有官方的modules,可以通過簡單的幾個命令protobuf_generate_cpp來生成對應的.pb.cc.pb.h

簡單的例子:

find_package(Protobuf REQUIRED)
include_directories(${Protobuf_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
protobuf_generate_python(PROTO_PY foo.proto)
add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
target_link_libraries(bar ${Protobuf_LIBRARIES})

但是這個例子太簡單了,如果我們的.proto文件只有一個或者說都只在一個目錄里,那用這個命令沒什么毛病...

但如果是這種情況,我們的文件目錄如下:

├── CMakeLists.txt
├── README.md
├── meta
│  └── proto
│    ├── CMakeLists.txt
│    └── common
│      ├── bar
│      │  ├── CMakeLists.txt
│      │  └── bar.proto
│      └── foo
│        ├── CMakeLists.txt
│        └── foo.proto
└── src
  ├── CMakeLists.txt
  ├── c_proto.cc
  └── c_proto.hh

其中foo.proto文件如下:

message foo_msg 
{
 optional string name = 1;
}

bar.proto的文件如下:

import "common/foo/foo.proto";
 
message bar_msg 
{
 optional foo_msg foo = 1;
 optional string name = 2;
}

如上,bar文件引用foo,而且這兩個不在一個目錄,如果直接使用protobuf_generate_cpp來生成,直接會報錯。(這個例子取自Yu的一篇博文

也想過把他倆放到同一個目錄...然后bar.proto中import的代碼就要修改,雖然這樣可以,但顯然是不適合大型的項目。

而這個大型項目顯然就是mediapipe...折磨了我好久。

關于mediapipe的詳細介紹在另一篇文章。mediapipe中使用了大量的ProtoBuf技術來表示圖結構,而且mediapipe原生并不是采用cmake來構建項目,而是使用google自家研發(fā)的bazel,這個項目構建系統(tǒng)我就不評價了,而現(xiàn)在我需要使用Cmake來對其進行構建。

這也是噩夢的開始,mediapipe的.proto文件很多,核心的framework的目錄下存在很多的.proto文件,根目錄和子目錄都有.proto文件:

而且每個proto文件之間存在引用的順序,framework根目錄下的calculator.proto文件:

// mediapipe/framework/calculator.proto
syntax = "proto3";

package mediapipe;

import public "mediapipe/framework/calculator_options.proto";

import "google/protobuf/any.proto";
import "mediapipe/framework/mediapipe_options.proto";
import "mediapipe/framework/packet_factory.proto";
import "mediapipe/framework/packet_generator.proto";
import "mediapipe/framework/status_handler.proto";
import "mediapipe/framework/stream_handler.proto";

每個.proto文件都import了其他目錄下的文件,這里的import類似于C++中的include,但是這里的import又可以相互引用,例如上述的status_handler.proto也引用了mediapipe_options.proto。

如果直接對上述所有的.proto文件直接使用protobuf_generate_cpp命令,會直接報錯,因為這些文件不在一個目錄,而且import的相對目錄也無法分析。另外,不同目錄內的.cc文件會引用相應目錄生成的.pb.h文件,我們需要生成的.pb.cc.pb.h在原始的目錄中,這樣才可以正常引用,要不然需要修改其他源代碼的include地址,比較麻煩。

CLion中Cmake來編譯proto生成的.pb.cc.pb.h不在原始目錄,而是集中在cmake-build-debug(release)中,我們額外需要將其中生成的.pb.cc.pb.h文件移動到原始地址(Clion的情況是這樣)。

正確修改cmake

對于這種情況,比較合適的做法是直接使用命令進行生成。

首先找到所有需要編譯的.proto文件:

file(GLOB protobuf_files
    mediapipe/framework/*.proto
    mediapipe/framework/tool/*.proto
    mediapipe/framework/deps/*.proto
    mediapipe/framework/testdata/*.proto
    mediapipe/framework/formats/*.proto
    mediapipe/framework/formats/annotation/*.proto
    mediapipe/framework/formats/motion/*.proto
    mediapipe/framework/formats/object_detection/*.proto
    mediapipe/framework/stream_handler/*.proto
    mediapipe/util/*.proto
    mediapipe/calculators/internal/*.proto
    )

接下來,定義相關的目錄地址,PROTO_META_BASE_DIR為編譯之后生成文件的目錄。PROTO_FLAGS很重要,指定編譯.proto文件時的總的尋找路徑,.proto中的import命令根據(jù)根據(jù)這個地址去連接其他的.proto文件:

SET(PROTO_META_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
LIST(APPEND PROTO_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR})

設置好之后,通過FOREACH去循環(huán)之前的.proto文件,依次編譯每個文件,然后將生成的.pb.cc.pb.h移動回原始的目錄,至此就可以正常工作了。

FOREACH(FIL ${protobuf_files})

  GET_FILENAME_COMPONENT(FIL_WE ${FIL} NAME_WE)

  string(REGEX REPLACE ".+/(.+)\\..*" "\\1" FILE_NAME ${FIL})
  string(REGEX REPLACE "(.+)\\${FILE_NAME}.*" "\\1" FILE_PATH ${FIL})

  string(REGEX MATCH "(/mediapipe/framework.*|/mediapipe/util.*|/mediapipe/calculators/internal/)" OUT_PATH ${FILE_PATH})

  set(PROTO_SRCS "${CMAKE_CURRENT_BINARY_DIR}${OUT_PATH}${FIL_WE}.pb.cc")
  set(PROTO_HDRS "${CMAKE_CURRENT_BINARY_DIR}${OUT_PATH}${FIL_WE}.pb.h")

  EXECUTE_PROCESS(
      COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --cpp_out=${PROTO_META_BASE_DIR} ${FIL}
  )
  message("Copying " ${PROTO_SRCS} " to " ${FILE_PATH})

  file(COPY ${PROTO_SRCS} DESTINATION ${FILE_PATH})
  file(COPY ${PROTO_HDRS} DESTINATION ${FILE_PATH})

ENDFOREACH()

參考鏈接

http://blog.argcv.com/articles/3884.c
https://www.v2ex.com/t/602363
https://stackoverflow.com/questions/29720410/no-member-found-when-use-cmake-construct-proto/29817843

到此這篇關于Protobuf在Cmake中的正確使用方法的文章就介紹到這了,更多相關Protobuf使用Cmake內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 關于解決?“Error:?listen?EACCES:?permission?denied?0.0.0.0:80“?錯誤的方法

    關于解決?“Error:?listen?EACCES:?permission?denied?0.0.0.0:

    這篇文章主要介紹了在開發(fā)過程中常見的錯誤Error:listenEACCES:permissiondenied0.0.0.0:80,并提供了兩種解決方法,大家可以根據(jù)需求選擇對應的方法,需要的朋友可以參考下
    2024-12-12
  • 最新Listary?v5.00.2843注冊碼?親測可用

    最新Listary?v5.00.2843注冊碼?親測可用

    listary是?windows?下一款可以快速搜索所有程序、文件,并且可以快速啟動程序和打開相應文件的優(yōu)秀的搜索軟件,絕對比系統(tǒng)自帶搜索速度快很多,而且查詢功能豐富,本文給大家分享Listary?v5.00.2843注冊碼,感興趣的朋友一起看看吧
    2022-07-07
  • 每個程序員需掌握的20個代碼命名小貼士

    每個程序員需掌握的20個代碼命名小貼士

    這篇文章主要介紹了每個程序員需掌握的20個代碼命名小貼士,需要的朋友可以參考下
    2015-03-03
  • 好玩的vbs微信小程序之語言播報功能

    好玩的vbs微信小程序之語言播報功能

    這篇文章主要介紹了好玩的vbs微信小程序之語言播報功能,非常好玩有趣,需要的朋友跟隨小編一起看看吧
    2019-09-09
  • Ceph集群CephFS文件存儲核心概念及部署使用詳解

    Ceph集群CephFS文件存儲核心概念及部署使用詳解

    這篇文章主要為大家介紹了Ceph集群CephFS文件存儲核心概念及部署使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 使用八爪魚采集器采集滾動加載和點擊加載數(shù)據(jù)的教程

    使用八爪魚采集器采集滾動加載和點擊加載數(shù)據(jù)的教程

    現(xiàn)在很多網站的列表,需要向下滾動頁面,才能加載出新數(shù)據(jù)?;蛘唿c擊“查看更多”加載新數(shù)據(jù)。使用廣泛的火車頭采集器相對無力,使用八爪魚采集器可以采集滾動刷新和點擊刷新。
    2023-05-05
  • MobaXterm遠程登錄工具功能與應用小結

    MobaXterm遠程登錄工具功能與應用小結

    MobaXterm是一款功能強大的遠程終端軟件,主要支持SSH登錄,擁有多種遠程協(xié)議,實現(xiàn)跨平臺訪問,它包括多會話管理、本地命令行執(zhí)行、圖形化界面集成和文件傳輸?shù)裙δ?提供豐富的自定義選項和安全特性,感興趣的朋友一起看看吧
    2025-02-02
  • jenkins通過sshPut傳輸文件時報錯Permission?denied的SftpException的問題及解決方案

    jenkins通過sshPut傳輸文件時報錯Permission?denied的SftpException的問題及解決

    使用jenkins的ssh插件傳輸文件至遠程機器的指定目錄,php程序打包后,經過zip壓縮為oms.zip,這篇文章主要介紹了jenkins通過sshPut傳輸文件的時候,報錯Permission?denied的SftpException,需要的朋友可以參考下
    2023-08-08
  • 數(shù)據(jù)分析2020年全國各省高考成績分布情況

    數(shù)據(jù)分析2020年全國各省高考成績分布情況

    這篇文章主要介紹了數(shù)據(jù)分析2020年全國各省高考成績分布情況,順便可以用這個數(shù)據(jù)看每個省市的一本線劃分比率,還有其他相關的數(shù)據(jù),需要的朋友可以參考下
    2020-07-07
  • MobaXterm 安裝使用圖文教程

    MobaXterm 安裝使用圖文教程

    MobaXterm是一款SSH客戶端,連接并操作Linux服務器,這篇文章主要介紹了MobaXterm安裝使用圖文教程,本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05

最新評論

会理县| 麻栗坡县| 城市| 宁武县| 陆良县| 永丰县| 丽江市| 永吉县| 郸城县| 轮台县| 开封县| 都兰县| 怀仁县| 永和县| 四平市| 金坛市| 晋江市| 敦化市| 商河县| 宁化县| 阿荣旗| 麦盖提县| 闵行区| 富裕县| 萝北县| 九龙城区| 哈尔滨市| 富川| 鄂伦春自治旗| 乌兰察布市| 嘉祥县| 麟游县| 巨野县| 威海市| 台北县| 渝北区| 鄢陵县| 嘉义市| 常山县| 深圳市| 循化|