Protobuf 가 Cmake 에서 의 정확 한 사용 방법 에 대한 상세 한 설명
.proto
을 통 해 전달 할 데이터 형식 을 정의 할 수 있 습 니 다.예 를 들 어 심도 있 는 학습 에서 자주 사용 하 는ONNX교환 모델 은.proto
로 작 성 된 것 이다.우 리 는 다양한 전단(MNN,NCNN,TVM 의 전단)을 통 해 이.onx 모델 을 읽 을 수 있 지만,우선 protobuf 를 설치 해 야 합 니 다.이전의 블 로그 에서 간단하게 소개onnx했 는데 그 중에서onnx.proto는 onnx 모델 의 기본 데이터 구 조 를 대표 했다.일반적으로 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나 를 오랫동안 괴 롭 혔 다.
미디어 파이프 에 대한 상세 한 소 개 는 다른 글 에 있 습 니 다.미디어 파이프 에서 대량의 ProtoBuf 기술 을 사용 하여 그림 구 조 를 표 시 했 습 니 다.그리고 미디어 파이프 의 원생 은 cmake 로 프로젝트 를 구축 하 는 것 이 아니 라 구 글 이 자체 개발 한bazel을 사 용 했 습 니 다.이 프로젝트 의 구축 시스템 은 평가 하지 않 겠 습 니 다.지금 은 Cmake 를 사용 하여 구축 해 야 합 니 다.
이것 도 악몽 의 시작 입 니 다.미디어 파이프 의.proto 파일 이 많 습 니 다.핵심 프레임 워 크 의 디 렉 터 리 에는.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 명령 은 이 주소 에 따라 다른.proto
파일 을 연결 합 니 다.
SET(PROTO_META_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
LIST(APPEND PROTO_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR})
설정 한 후FOREACH
를 통 해 이전.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 를 사용 하 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Protobuf 가 Cmake 에서 의 정확 한 사용 방법 에 대한 상세 한 설명위 와 같이 bar 파일 은 foo 를 참조 하고 이 두 개 는 한 디 렉 터 리 에 없습니다.protobuf 를 직접 사용 하면generate_cpp 가 생 성 되면 바로 오류 가 발생 합 니 다.(이 예 는 Yu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.