对`example :: note :: 〜note()&#x27的未定义引用。 Protobuf
我在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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下cmakelists.txt足以让您的
example.proto
和main.cpp
文件。它不使用GRPC,因为这与测试无关。以下是该构建的逐线解释以及它为什么起作用。
让我们按行行:
这必须始终是您的顶级cmakelists.txt文件的第一行。它告诉cmake哪个 policies> policies 这是为了确保向后兼容性,但不能向前的兼容性,即cmake不会模仿较旧版本,但在某些情况下只会简单地回到旧行为。特别是,它不会阻止您使用对所陈述的最低版本太新的功能,因此您 必须始终在此处列出的版本 中测试您的构建。我使用3.23写了这个答案,但它可能与较旧的版本一起使用。
非常少数例外,这将是您的cmakelists.txt的第二行。您可以选择所需的任何项目名称。我在这里选择
示例
,因为,这是一个示例。此命令是启动CMAKE的编译器检测例程的原因。在此之前,做大多数事情是无效的。该项目使用ProToBuf,因此我们使用
find_package
访问CMAKE的第一部分ProtoBuf支持(请参见此处的文档)。因为没有ProtoBuf的项目可能无法正常工作,所以我们添加了必需的
参数。现在,我们调用
find_package(Protobuf ...)
模块提供的功能。这将打电话给Protobuf编译器并定义两个变量,example_srcs
和example_hdrs
(名称是任意的),以保留从example.proto
example.proto < /代码>。这不是记载的,但是生成的文件放置在
$ {cmake_current_binary_dir}
中。现在,我们从您的源文件(
main.cpp
)和上述生成的源文件创建可执行目标。main
的源文件需要查看生成的源,因此我们添加$ {cmake_current_binary_dir}
添加到Inclubly Directories的列表中。最后,应用程序需要链接到Protobuf库,因此我们链接到导入的
ProtoBuf :: libprotobuf
target。这也是由find_package(protobuf ...)
命令创建的。要调整此构建以使用Protobuf自己的CMAKE支持并跳过CMAKE的模块,您将需要进行以下更改:
config
tofind_package
。protobuf_generate_cpp
用protobuf_generate
替换使用。这就是构建的样子:
config
参数告诉cmake忽略匹配的任何查找模块(包括其自己的第一方模块)。然后新命令protobuf_generate
替换protobuf_generate_cpp
。现在,您没有填充源变量,而是将其赋予您生成源的目标。Protos
参数是要编译的Protobuf文件列表。因为它将目标作为参数,所以它必须遵循
add_exectuable
,而不是在它之前。这是我从来源构建Protobuf的方式来测试以下方式:
现在我可以在此示例中编译该程序:
The following CMakeLists.txt is enough for your
example.proto
andmain.cpp
file. It does not use gRPC because that wasn't relevant to testing.Below is a line-by-line explanation of this build and why it works.
Let's go line by line:
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.
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.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 theREQUIRED
argument.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
andexample_hdrs
(the names are arbitrary), to hold the files generated fromexample.proto
. This isn't well-documented, but the generated files are placed in${CMAKE_CURRENT_BINARY_DIR}
.Now we create an executable target from your source file (
main.cpp
) and the aforementioned generated source files.The source files for
main
need to see the generated sources, so we add${CMAKE_CURRENT_BINARY_DIR}
to the list of include directories.Finally, the application needs to link to the protobuf library, so we link to the imported
protobuf::libprotobuf
target. This, too, was created by thefind_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:
CONFIG
tofind_package
.protobuf_generate_cpp
withprotobuf_generate
.This is what the build would look like:
The
CONFIG
argument tells CMake to ignore any find modules that match (including its own first-party modules). Then the new commandprotobuf_generate
replacesprotobuf_generate_cpp
. Now instead of populating source variables, you give it the target for which you're generating sources. ThePROTOS
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:
Now I can compile the program in this example: