对`example :: note :: 〜note()&#x27的未定义引用。 Protobuf

发布于 2025-02-02 17:34:02 字数 2603 浏览 3 评论 0原文

我在Protobuf中写了一个非常简单的程序,根本没有服务,但是当我运行代码时,它会像示例那样投掷erros :: note :: 〜note :: 〜note()所有信息都在下面给出,请告诉我我在哪里犯错。

example.proto

syntax = "proto3";

package Example;

message Note {
    int32 id = 1;
    string title = 2;
    string description = 3;
}

i使用protoc -cpp_out =。 example.proto命令生成自动生成的文件

main.cpp

#include "example.pb.h"
#include <iostream>

int main(int argc, char const *argv[])
{
    Example::Note note;
    note.set_id(1);
    note.set_title("This is Title");
    note.set_description("This is Description");

    std::cout << "Note Information: " << note.DebugString() << std::endl;
    return 0;
}

cmakelists.txt

cmake_minimum_required(VERSION 3.14)

project(EXAMPLE LANGUAGES CXX)

# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")

set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)

# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_GRPC_GRPCPP gRPC::grpc++)
set(_REFLECTION gRPC::grpc++_reflection)
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
add_executable(Example
  main.cpp
)
target_link_libraries(Example
    Threads::Threads
    ${_REFLECTION}
    ${_GRPC_GRPCPP}
    ${_PROTOBUF_LIBPROTOBUF}
)

错误

.
.
.
-- Build files have been written to: /home/react-vision/dev/workingWithProtobuff/simpleExample/build
[ 50%] Building CXX object CMakeFiles/Example.dir/main.cpp.o
[100%] Linking CXX executable Example
/usr/bin/ld: CMakeFiles/Example.dir/main.cpp.o: in function `main':
main.cpp:(.text+0xf4): undefined reference to `Example::Note::~Note()'
/usr/bin/ld: main.cpp:(.text+0x12f): undefined reference to `Example::Note::~Note()'
/usr/bin/ld: CMakeFiles/Example.dir/main.cpp.o: in function `Example::Note::Note()':
main.cpp:(.text._ZN7Example4NoteC2Ev[_ZN7Example4NoteC5Ev]+0x22): undefined reference to `Example::Note::Note(google::protobuf::Arena*, bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Example.dir/build.make:153: Example] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Example.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

I Written a very simple program in protobuf without services at all but when i run the code it throws erros like Example::Note::~Note() all information are given below please tell me where i'm making mistake.

example.proto

syntax = "proto3";

package Example;

message Note {
    int32 id = 1;
    string title = 2;
    string description = 3;
}

i use protoc --cpp_out=. example.proto command to generate auto generated files

main.cpp

#include "example.pb.h"
#include <iostream>

int main(int argc, char const *argv[])
{
    Example::Note note;
    note.set_id(1);
    note.set_title("This is Title");
    note.set_description("This is Description");

    std::cout << "Note Information: " << note.DebugString() << std::endl;
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

project(EXAMPLE LANGUAGES CXX)

# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
set(protobuf_MODULE_COMPATIBLE TRUE)
find_package(Protobuf CONFIG REQUIRED)
message(STATUS "Using protobuf ${Protobuf_VERSION}")

set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_PROTOBUF_PROTOC 
lt;TARGET_FILE:protobuf::protoc>)

# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_GRPC_GRPCPP gRPC::grpc++)
set(_REFLECTION gRPC::grpc++_reflection)
set(_GRPC_CPP_PLUGIN_EXECUTABLE 
lt;TARGET_FILE:gRPC::grpc_cpp_plugin>)
add_executable(Example
  main.cpp
)
target_link_libraries(Example
    Threads::Threads
    ${_REFLECTION}
    ${_GRPC_GRPCPP}
    ${_PROTOBUF_LIBPROTOBUF}
)

Error

.
.
.
-- Build files have been written to: /home/react-vision/dev/workingWithProtobuff/simpleExample/build
[ 50%] Building CXX object CMakeFiles/Example.dir/main.cpp.o
[100%] Linking CXX executable Example
/usr/bin/ld: CMakeFiles/Example.dir/main.cpp.o: in function `main':
main.cpp:(.text+0xf4): undefined reference to `Example::Note::~Note()'
/usr/bin/ld: main.cpp:(.text+0x12f): undefined reference to `Example::Note::~Note()'
/usr/bin/ld: CMakeFiles/Example.dir/main.cpp.o: in function `Example::Note::Note()':
main.cpp:(.text._ZN7Example4NoteC2Ev[_ZN7Example4NoteC5Ev]+0x22): undefined reference to `Example::Note::Note(google::protobuf::Arena*, bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Example.dir/build.make:153: Example] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Example.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单挑你×的.吻 2025-02-09 17:34:02

以下cmakelists.txt足以让您的example.protomain.cpp文件。它不使用GRPC,因为这与测试无关。

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Protobuf REQUIRED)
protobuf_generate_cpp(example_srcs example_hdrs example.proto)

add_executable(main main.cpp ${example_srcs} ${example_hdrs})
target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
target_link_libraries(main PRIVATE protobuf::libprotobuf)

以下是该构建的逐线解释以及它为什么起作用。


让我们按行行:

cmake_minimum_required(VERSION 3.23)

这必须始终是您的顶级cmakelists.txt文件的第一行。它告诉cmake哪个 policies> policies 这是为了确保向后兼容性,但不能向前的兼容性,即cmake不会模仿较旧版本,但在某些情况下只会简单地回到旧行为。特别是,它不会阻止您使用对所陈述的最低版本太新的功能,因此您 必须始终在此处列出的版本 中测试您的构建。我使用3.23写了这个答案,但它可能与较旧的版本一起使用。

project(example)

非常少数例外,这将是您的cmakelists.txt的第二行。您可以选择所需的任何项目名称。我在这里选择示例,因为,这是一个示例。此命令是启动CMAKE的编译器检测例程的原因。在此之前,做大多数事情是无效的。

find_package(Protobuf REQUIRED)

该项目使用ProToBuf,因此我们使用find_package访问CMAKE的第一部分ProtoBuf支持(请参见此处的文档)。因为没有ProtoBuf的项目可能无法正常工作,所以我们添加了必需的参数。

protobuf_generate_cpp(example_srcs example_hdrs example.proto)

现在,我们调用find_package(Protobuf ...)模块提供的功能。这将打电话给Protobuf编译器并定义两个变量,example_srcsexample_hdrs(名称是任意的),以保留从example.proto example.proto < /代码>。这不是记载的,但是生成的文件放置在$ {cmake_current_binary_dir}中。

add_executable(main main.cpp ${example_srcs} ${example_hdrs})

现在,我们从您的源文件(main.cpp)和上述生成的源文件创建可执行目标。

target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

main的源文件需要查看生成的源,因此我们添加$ {cmake_current_binary_dir} 添加到Inclubly Directories的列表中。

target_link_libraries(main PRIVATE protobuf::libprotobuf)

最后,应用程序需要链接到Protobuf库,因此我们链接到导入的ProtoBuf :: libprotobuf target。这也是由find_package(protobuf ...)命令创建的。


要调整此构建以使用Protobuf自己的CMAKE支持并跳过CMAKE的模块,您将需要进行以下更改:

  1. 添加config to find_package
  2. protobuf_generate_cppprotobuf_generate替换使用。

这就是构建的样子:

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Protobuf CONFIG REQUIRED)

add_executable(main main.cpp)
protobuf_generate(TARGET main PROTOS example.proto)
target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
target_link_libraries(main PRIVATE protobuf::libprotobuf)

config参数告诉cmake忽略匹配的任何查找模块(包括其自己的第一方模块)。然后新命令protobuf_generate替换protobuf_generate_cpp。现在,您没有填充源变量,而是将其赋予您生成源的目标。 Protos参数是要编译的Protobuf文件列表。

因为它将目标作为参数,所以它必须遵循add_exectuable,而不是在它之前。

这是我从来源构建Protobuf的方式来测试以下方式:

$ git clone --recursive [email protected]:protocolbuffers/protobuf.git
$ cmake -G Ninja -S protobuf -B _build/protobuf -DCMAKE_BUILD_TYPE=Release -Dprotobuf_BUILD_TESTS=NO -DCMAKE_INSTALL_PREFIX=$PWD/_local
$ cmake --build _build/protobuf/ --target install

现在我可以在此示例中编译该程序:

alex@alex-ubuntu:~/test$ cmake -G Ninja -S . -B _build/project -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PWD/_local
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/_build/project
alex@alex-ubuntu:~/test$ cmake --build _build/project/ --verbose
[1/4] cd /home/alex/test/_build/project && /home/alex/test/_local/bin/protoc-3.21.0.2 --cpp_out :/home/alex/test/_build/project -I /home/alex/test /home/alex/test/example.proto
[2/4] /usr/bin/c++  -I/home/alex/test/_build/project -isystem /home/alex/test/_local/include -O3 -DNDEBUG -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/alex/test/main.cpp
[3/4] /usr/bin/c++  -I/home/alex/test/_build/project -isystem /home/alex/test/_local/include -O3 -DNDEBUG -MD -MT CMakeFiles/main.dir/example.pb.cc.o -MF CMakeFiles/main.dir/example.pb.cc.o.d -o CMakeFiles/main.dir/example.pb.cc.o -c /home/alex/test/_build/project/example.pb.cc
[4/4] : && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/main.dir/main.cpp.o CMakeFiles/main.dir/example.pb.cc.o -o main  ../../_local/lib/libprotobuf.a  -lpthread  /usr/lib/x86_64-linux-gnu/libz.so && :
alex@alex-ubuntu:~/test$ ./_build/project/main 
Note Information: id: 1
title: "This is Title"
description: "This is Description"

The following CMakeLists.txt is enough for your example.proto and main.cpp file. It does not use gRPC because that wasn't relevant to testing.

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Protobuf REQUIRED)
protobuf_generate_cpp(example_srcs example_hdrs example.proto)

add_executable(main main.cpp ${example_srcs} ${example_hdrs})
target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
target_link_libraries(main PRIVATE protobuf::libprotobuf)

Below is a line-by-line explanation of this build and why it works.


Let's go line by line:

cmake_minimum_required(VERSION 3.23)

This must always be the first line of your top-level CMakeLists.txt file. It tells CMake which policies to enable. This is to ensure backwards compatibility, but not forwards compatibility, i.e. CMake will not emulate older versions, but will simply toggle back to old behaviors in certain cases. In particular, it will not stop you from using features that are too new for the stated minimum version, so you must always test your build with the version listed here. I wrote this answer using 3.23, but it will probably work with older versions.

project(example)

With very few exceptions, this will be the second line for your CMakeLists.txt. You can pick any project name you want. I chose example here because, well, this is an example. This command is what kicks off CMake's compiler detection routines. It is invalid to do most things before that has happened.

find_package(Protobuf REQUIRED)

This project uses protobuf so we use find_package to access CMake's first-party protobuf support (see documentation here). Because the project cannot possibly work without protobuf, we add the REQUIRED argument.

protobuf_generate_cpp(example_srcs example_hdrs example.proto)

Now we call a function provided by the find_package(Protobuf ...) module. This wraps a call to the protobuf compiler and defines two variables, example_srcs and example_hdrs (the names are arbitrary), to hold the files generated from example.proto. This isn't well-documented, but the generated files are placed in ${CMAKE_CURRENT_BINARY_DIR}.

add_executable(main main.cpp ${example_srcs} ${example_hdrs})

Now we create an executable target from your source file (main.cpp) and the aforementioned generated source files.

target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")

The source files for main need to see the generated sources, so we add ${CMAKE_CURRENT_BINARY_DIR} to the list of include directories.

target_link_libraries(main PRIVATE protobuf::libprotobuf)

Finally, the application needs to link to the protobuf library, so we link to the imported protobuf::libprotobuf target. This, too, was created by the find_package(Protobuf ...) command.


To adjust this build to use Protobuf's own CMake support and to skip CMake's module, you will need to make the following changes:

  1. Add CONFIG to find_package.
  2. Replace the use of protobuf_generate_cpp with protobuf_generate.

This is what the build would look like:

cmake_minimum_required(VERSION 3.23)
project(example)

find_package(Protobuf CONFIG REQUIRED)

add_executable(main main.cpp)
protobuf_generate(TARGET main PROTOS example.proto)
target_include_directories(main PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
target_link_libraries(main PRIVATE protobuf::libprotobuf)

The CONFIG argument tells CMake to ignore any find modules that match (including its own first-party modules). Then the new command protobuf_generate replaces protobuf_generate_cpp. Now instead of populating source variables, you give it the target for which you're generating sources. The PROTOS argument is the list of protobuf files to compile.

Because it takes the target as an argument, it must follow add_exectuable, rather than precede it.

Here's how I built protobuf from sources to test this:

$ git clone --recursive [email protected]:protocolbuffers/protobuf.git
$ cmake -G Ninja -S protobuf -B _build/protobuf -DCMAKE_BUILD_TYPE=Release -Dprotobuf_BUILD_TESTS=NO -DCMAKE_INSTALL_PREFIX=$PWD/_local
$ cmake --build _build/protobuf/ --target install

Now I can compile the program in this example:

alex@alex-ubuntu:~/test$ cmake -G Ninja -S . -B _build/project -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PWD/_local
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/_build/project
alex@alex-ubuntu:~/test$ cmake --build _build/project/ --verbose
[1/4] cd /home/alex/test/_build/project && /home/alex/test/_local/bin/protoc-3.21.0.2 --cpp_out :/home/alex/test/_build/project -I /home/alex/test /home/alex/test/example.proto
[2/4] /usr/bin/c++  -I/home/alex/test/_build/project -isystem /home/alex/test/_local/include -O3 -DNDEBUG -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/alex/test/main.cpp
[3/4] /usr/bin/c++  -I/home/alex/test/_build/project -isystem /home/alex/test/_local/include -O3 -DNDEBUG -MD -MT CMakeFiles/main.dir/example.pb.cc.o -MF CMakeFiles/main.dir/example.pb.cc.o.d -o CMakeFiles/main.dir/example.pb.cc.o -c /home/alex/test/_build/project/example.pb.cc
[4/4] : && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/main.dir/main.cpp.o CMakeFiles/main.dir/example.pb.cc.o -o main  ../../_local/lib/libprotobuf.a  -lpthread  /usr/lib/x86_64-linux-gnu/libz.so && :
alex@alex-ubuntu:~/test$ ./_build/project/main 
Note Information: id: 1
title: "This is Title"
description: "This is Description"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文