HIDL调试中的链接问题

链接时出现错误:

/home/huangzhen/work/ffv2/projects/tcl/a3agl/vendor/focaltech/src/ff_hal/src/service/hidlservice.cpp:39: error: undefined reference to 'vendor::mediatek::hardware::focalfingerprint::V1_0::IFocalFingerprint::registerAsService(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&)'

 

而查看vendor.mediatek.hardware.focalfingerprint@1.0_vendor.so的符号表,该so为a3agl项目下编译得出:

huangzhen@FPRSVR02:~/work/ffv2/prebuilts/android/8.x/libs/32$ nm -CD vendor.mediatek.hardware.focalfingerprint@1.0_vendor.so | grep registerAs*

0000d171 T vendor::mediatek::hardware::focalfingerprint::V1_0::IFocalFingerprint::registerAsService(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)

注意绿色部分.ffv2在链接时使用的命名空间为std::__ndk1

而编译so时使用的命名空间为 std::__1

stackoverflow上的问题:

https://stackoverflow.com/questions/36127404/error-undefined-reference-to-std-ndk1-after-update-ndk-revision-11

Q:

undefined reference to 'webrtc::CreateSessionDescription(std::__ndk1::basic_string, std::__ndk1::allocator > const&, std::__ndk1::basic_string, std::__ndk1::allocator > const&, webrtc::SdpParseError*)'

After updating android ndk revision 11, I get some problems. I could not build my project because of above it.

In Android Developer, I found that 'Changed libc++’s inline namespace to std::__ndk1 to prevent ODR issues with platform libc++.', but I cannot understand.

How can I fix it?

Thanks for helping me.

A:

I think my way is more or less tricky, but it works. I went into /ndk-root-path//sources/cxx-stl/llvm-libc++/libcxx/include, there is a file named '__config'. open it and find out all lines with '_LIBCPP_BEGIN_NAMESPACE_STD', this is where the inline namespace '__ndk1' added. So I just comment out all inline namespaces, like:

352 #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {//inline namespace _LIBCPP_NAMESPACE { 353 #define _LIBCPP_END_NAMESPACE_STD } //} 354 #define _VSTD std//::_LIBCPP_NAMESPACE 356 namespace std { // inline namespace _LIBCPP_NAMESPACE { // } }

There should be 4 or 5 pieces of these codes. after comment that, you can rebuild your ndk project, it should works.

Q:

I have some pre-compiled so files, so who knows what flags were used to generate them. I'm curious to know which runtime/version of the STL they were compiled with (gnustl_shared? stlport_shared?) to avoid clashes with my own code.

How can I find out from the compiled so files which runtime they were compiled to use?

This is all Android NDK C++ code.

A:

Another trick that can help you identify if libc++ was used even if it was c++_static: readelf -sW path/to/lib | grep __ndk1. All the libc++ symbols are in an internal namespace (std::__ndk1 instead of just std) to support versioning the STL and avoiding clashes with the system STL. If it's a very old (r10 or older) libc++, it will be just __1. I don't know of a good way to spot gnustl vs stlport, but that will help with libc++ vs not-libc++.

这里需要判断a3a项目中使用libc++版本,使用的namespace是__ndk1还是__1.

 

A:

Like Alex said, you can use readelf to figure out some of this. The following can let you know if the library depends on a shared STL, and which one:

$ readelf -dW path/to/libfoo.so | grep NEEDED 0x00000001 (NEEDED) Shared library: [libc++_shared.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libdl.so]

As you can see, this library depends on libc++_shared. Ignore the libstdc++.so that you also see. That's https://github.com/android-ndk/ndk/issues/105.

If it depends on a static STL (or your library is a static library) and wasn't built with -fvisibility=hidden, that method won't work. In this case you can still identify if the library was built against libc++ or not-libc++. All the libc++ symbols are in an internal namespace (std::__ndk1instead of just std) to support versioning the STL and avoiding clashes with the system STL. If it's a very old (r10 or older) libc++, it will be just __1.

$ readelf -sW path/to/libfoo.so | grep __ndk1 6: 000008bf 86 FUNC WEAK DEFAULT 12 _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj 7: 000008a9 22 FUNC WEAK DEFAULT 12 _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev

If you're trying to figure out which version of the NDK a library was built with, you can usehttps://android.googlesource.com/platform/ndk/+/master/parse_elfnote.py.

$ python parse_elfnote.py foo/libs/armeabi-v7a/libfoo.so ----------ABI INFO---------- ABI_NOTETYPE: 1 ABI_VENDOR: Android ABI_ANDROID_API: 14 ABI_NDK_VERSION: r17-canary ABI_NDK_BUILD_NUMBER: dev

Most of this information will only be available for libraries built with a relatively new NDK (r14? I don't remember when we added this).

应该是ffv2的编译使用了libstdc++.so的缘故

 

解决办法:

 

1.依靠stackoverflow的方式,修改NDK的命名空间配置:

下__config文件:

改为

 

2.为了适配客户,hidl的库不在android项目中产生,将hidl-gen自动生成的XXXXAll.cpp文件以及相关头文件导入到ffv2项目中

通过NDK产生

 

1)使用hidl-gen工具,通过IBase,IServiceManager hal文件生成模块所需的头文件

生成的头文件位于:

 

2)使用hidl-gen工具,通过IFocalFingerprintService.hal与type.hal文件生成types.cpp与FocalFingerprintServiceAll.cpp文件和相关头文件.并参加编译.

3)以上两步骤相当于在项目中编译生成vendor.mediatek.hardware.focalfingerprintservice@1.0.so

所以修改ndk配置的目的主要在于适配诸如libhidl.so之类来自于a3agl项目的so库.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值