[英]Undefined reference to vtable for grpc::experimental when adding --coverage flag
I have a C++ project based on CMake. The starting point of the project was created using cmake-init.我有一个基于 CMake 的 C++ 项目。该项目的起点是使用 cmake-init 创建的。 I am trying to add gRPC to the project.我正在尝试将 gRPC 添加到项目中。 However, when using coverage flags, a linker error occurs:但是,当使用覆盖标志时,会出现 linker 错误:
build] /usr/bin/ld: CMakeFiles/demo_lib.dir/source/lib.cpp.o: warning: relocation against `_ZTVN4grpc12experimental38FileWatcherAuthorizationPolicyProviderE' in read-only section `.text._ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC2EP34grpc_authorization_policy_provider[_ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC5EP34grpc_authorization_policy_provider]'
[build] /usr/bin/ld: /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: warning: relocation against `_ZTVN4grpc12experimental38FileWatcherAuthorizationPolicyProviderE' in read-only section `.text._ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC2EP34grpc_authorization_policy_provider[_ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC5EP34grpc_authorization_policy_provider]'
[build] /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::StaticDataAuthorizationPolicyProvider::StaticDataAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:48: undefined reference to `vtable for grpc::experimental::StaticDataAuthorizationPolicyProvider'
[build] /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::FileWatcherAuthorizationPolicyProvider::FileWatcherAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:73: undefined reference to `vtable for grpc::experimental::FileWatcherAuthorizationPolicyProvider'
[build] CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::StaticDataAuthorizationPolicyProvider::StaticDataAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:48: undefined reference to `vtable for grpc::experimental::StaticDataAuthorizationPolicyProvider'
[build] /usr/bin/ld: CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::FileWatcherAuthorizationPolicyProvider::FileWatcherAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:73: undefined reference to `vtable for grpc::experimental::FileWatcherAuthorizationPolicyProvider'
The thing that differs from similar questions here is that without the coverage flags, this does not happen + I do not use AuthorizationPolicy in any way.与这里的类似问题不同的是,如果没有覆盖标志,这不会发生 + 我不以任何方式使用 AuthorizationPolicy。 The code I am using right now is essentially what you can find in https://github.com/faaxm/exmpl-cmake-grpc我现在使用的代码基本上是您可以在https://github.com/faaxm/exmpl-cmake-grpc中找到的代码
Here is the relevant flags from the CMakePresets.json:这是 CMakePresets.json 中的相关标志:
{
"name": "flags-unix",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wformat=2 -Wundef -Werror=float-equal -Wshadow -Wcast-align -Wunused -Wnull-dereference -Wdouble-promotion -Wimplicit-fallthrough -Wextra-semi -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast -Wl,--whole-archive -Wl,--allow-multiple-definition"
}
},
{
"name": "coverage-unix",
"binaryDir": "${sourceDir}/build/coverage",
"inherits": "ci-unix",
"hidden": true,
"cacheVariables": {
"ENABLE_COVERAGE": "ON",
"CMAKE_BUILD_TYPE": "Coverage",
"CMAKE_CXX_FLAGS_COVERAGE": "-Og -g --coverage -fkeep-inline-functions -fkeep-static-functions",
"CMAKE_EXE_LINKER_FLAGS_COVERAGE": "--coverage",
"CMAKE_SHARED_LINKER_FLAGS_COVERAGE": "--coverage",
"CMAKE_MAP_IMPORTED_CONFIG_COVERAGE": "Coverage;RelWithDebInfo;Release;Debug;"
}
},
Edit:编辑:
The header that is referenced is here: https://grpc.github.io/grpc/cpp/authorization__policy__provider_8h_source.html (it's only 80 lines).引用的header在这里: https://grpc.github.io/grpc/cpp/authorization__policy__provider_8h_source.html (只有80行)。 it does not seem to me that any pure-virtual method are not defined.在我看来,没有定义任何纯虚拟方法。 Am I wrong?我错了吗?
This is what the source file look like: https://github.com/faaxm/exmpl-cmake-grpc/blob/master/server/src/main.cpp except that in my case, it's a void launch_server()
function instead of int main()
, and the actual int main()
calls launch_server()
.这是源文件的样子: https://github.com/faaxm/exmpl-cmake-grpc/blob/master/server/src/main.cpp除了在我的例子中,它是一个void launch_server()
function int main()
,而实际的int main()
调用launch_server()
。 One (maybe) hint that I have is that the ServerBuilder
class ('grpcpp/server_builder.h') has:我得到的一个(可能)提示是ServerBuilder
class ('grpcpp/server_builder.h') 具有:
class ServerBuilder {
public:
ServerBuilder();
virtual ~ServerBuilder();
// (...)
/// NOTE: class experimental_type is not part of the public API of this class.
/// TODO(yashykt): Integrate into public API when this is no longer
/// experimental.
class experimental_type {
public:
// (...)
/// Sets server authorization policy provider in
/// GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER channel argument.
void SetAuthorizationPolicyProvider(
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
provider);
private:
ServerBuilder* builder_;
};
//(...)
private:
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
authorization_provider_;
This is the only way that the AuthorizationPolicyProvider somehow gets into my code, through the gRPC ServerBuilder
class. What should I do then?这是 AuthorizationPolicyProvider 通过 gRPC ServerBuilder
class 以某种方式进入我的代码的唯一方法。那我该怎么办?
IIRC this is related to something called Position Independent Code . IIRC 这与称为Position Independent Code的东西有关。 You essentially have a static library that you wish to link in a shared library (this is most likely caused by the --coverage
flag), you can't do that without position independent code.您基本上有一个 static 库,您希望将其链接到共享库中(这很可能是由--coverage
标志引起的),如果没有 position 独立代码,您将无法做到这一点。 What you need to do is recompile the static libraries by passing -fPIC
.您需要做的是通过传递-fPIC
重新编译 static 库。
Then you can recompile your project and it should work.然后你可以重新编译你的项目,它应该可以工作。
EDIT: Here is a link to a stackoverflow question with an explanation on how to figure out if the library was compiled with -fPIC
.编辑: 这里是一个 stackoverflow 问题的链接,其中解释了如何确定库是否是使用-fPIC
编译的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.