How can I use a NDK prebuilt library in Android

786 views
Skip to first unread message

FranzKafka Yu

unread,
Apr 17, 2023, 11:17:16 AM4/17/23
to android-ndk
Hello everyone:

Recently I am trying to migrate some third-party open-sourced project in Android,and I already compiled it with NDK toolchain suceessfully.Then I create two some source files for calling the library,here is my Android.bp:

cc_library {
    name: "libevsadas",
    srcs:[
        "utils/EvsLog.cpp",
        "adas/AdasManager.cpp",
        "adas/AdasMessageReader.cpp",
        "adas/proto/*.cc"
    ],

    include_dirs: [
        "packages/services/Car/cpp/evs/apps/default/utils/",
        "packages/services/Car/cpp/evs/apps/default/adas/",
    ],

    cppflags: [
        "-Wall",
        "-Werror",
        "-Wunused",
        "-Wunreachable-code",
        "-Wno-unknown-pragmas",
        "-Wno-unused-parameter",
        "-Wno-non-virtual-dtor",
        "-Wno-macro-redefined",
        "-Wno-unused-lambda-capture",
        "-fexceptions",
        "-fPIE",
        "-fPIC"
    ],

    shared_libs: [
        "libcutils",
        "libutils",
        "liblog",
        "libbase",
        "libcyber",
        "libfastcdr",
        "libfastrtps",
        "libc++_shared",
        "libads_log",
        "libcyber_proto",
        "libprotobufcyber",
        "libfoonathan_memory-0.7.1"
    ],

    rtti: true
}

these libraries are all third-party libraries compiled with NDK toolchain:
        "libcyber",
        "libfastcdr",
        "libfastrtps",
        "libc++_shared",
        "libads_log",
        "libcyber_proto",
        "libprotobufcyber",
        "libfoonathan_memory-0.7.1"

I defined these libraries in Android.bp like this:

cc_prebuilt_library_shared {
    name: "libcyber",
    arch: {
        x86: {
            srcs: ["libs/x86/libcyber.so"],
        },  
        arm64: {
            srcs: ["libs/arm64-v8a/libcyber.so"],
        },  
    },  
    check_elf_files: false,
}

and  my source files are these:
        "utils/EvsLog.cpp",
        "adas/AdasManager.cpp",
        "adas/AdasMessageReader.cpp",
        "adas/proto/*.cc"

And my new library should named "libevsadas",the output should be libevsadas.so.

But now I got these errors:

ld.lld: error: undefined symbol: apollo::cyber::Init(char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
>>> referenced by AdasMessageReader.cpp:84 (packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.cpp:84)
>>>               out/soong/.intermediates/packages/services/Car/cpp/evs/apps/default/libevsadas/android_x86_static/obj/packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.o:(AdasMessageReader::init())

ld.lld: error: undefined symbol: apollo::cyber::CreateNode(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
>>> referenced by AdasMessageReader.cpp:86 (packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.cpp:86)
>>>               out/soong/.intermediates/packages/services/Car/cpp/evs/apps/default/libevsadas/android_x86_static/obj/packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.o:(AdasMessageReader::init())

ld.lld: error: undefined symbol: autoplt::log::Logger::CreateLogger(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, autoplt::log::LogLevel)
>>> referenced by node.h:441 (packages/services/Car/cpp/evs/apps/default/adas/cyber/node/node.h:441)
>>>               out/soong/.intermediates/packages/services/Car/cpp/evs/apps/default/libevsadas/android_x86_static/obj/packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.o:(std::__1::shared_ptr<apollo::cyber::Reader<autoplt::canfd::AdasMsg> > apollo::cyber::Node::CreateReader<autoplt::canfd::AdasMsg>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<void (std::__1::shared_ptr<autoplt::canfd::AdasMsg> const&)> const&))
>>> referenced by node_channel_impl.h:207 (packages/services/Car/cpp/evs/apps/default/adas/cyber/node/node_channel_impl.h:207)
>>>               out/soong/.intermediates/packages/services/Car/cpp/evs/apps/default/libevsadas/android_x86_static/obj/packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.o:(std::__1::shared_ptr<apollo::cyber::Reader<autoplt::canfd::AdasMsg> > apollo::cyber::NodeChannelImpl::CreateReader<autoplt::canfd::AdasMsg>(apollo::cyber::proto::RoleAttributes const&, std::__1::function<void (std::__1::shared_ptr<autoplt::canfd::AdasMsg> const&)> const&, unsigned int))
>>> referenced by node_channel_impl.h:223 (packages/services/Car/cpp/evs/apps/default/adas/cyber/node/node_channel_impl.h:223)
>>>               out/soong/.intermediates/packages/services/Car/cpp/evs/apps/default/libevsadas/android_x86_static/obj/packages/services/Car/cpp/evs/apps/default/adas/AdasMessageReader.o:(std::__1::shared_ptr<apollo::cyber::Reader<autoplt::canfd::AdasMsg> > apollo::cyber::NodeChannelImpl::CreateReader<autoplt::canfd::AdasMsg>(apollo::cyber::proto::RoleAttributes const&, std::__1::function<void (std::__1::shared_ptr<autoplt::canfd::AdasMsg> const&)> const&, unsigned int))
>>> referenced 19 more times


it seems that when linker link libevsadas.so with other shared libraries,the linker can't the needed symbols.

I have googled some time,the problem maybe the STL,all the third-party libraries are compiled with NDK toochain and use the STL:libc++_shared.so,which has the namespace std::__ndk1 while libc++.so‘s namespace will be std::__1,so linker can't find the right symbol from my prebuilt libraries.

while When I compiled libevsadas.so,the  default STL is libc++.so,this may be the problem.

I have tried set stl in Android.bp like this:

stl: "c++_shared",


can somebody give me some advices?

Dan Albert

unread,
Apr 17, 2023, 6:13:50 PM4/17/23
to andro...@googlegroups.com
App C++ binaries (libraries built with the NDK) are not compatible with platform C++ binaries (those built by soong). The C++ stdlib used by Android has changed over time, and C++ itself is not ABI stable. The only supported use of the NDK is for building apps. Everything else is not supported, and unsupported use cases like this one are unsupported because they cannot work reliably. Apps and the OS are not the same environment.

You must either provide a C ABI to your NDK-built libraries or you must build those libraries as part of the platform build. The second option is far, far safer. This build breakage is protecting you from runtime bugs.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/9a4a30c8-bbd2-4e13-9b1d-13ce33ffba68n%40googlegroups.com.

FranzKafka Yu

unread,
Apr 18, 2023, 10:32:43 AM4/18/23
to andro...@googlegroups.com
Thanks for your reply,I got it!

'Dan Albert' via android-ndk <andro...@googlegroups.com> 于2023年4月18日周二 06:13写道:
Reply all
Reply to author
Forward
0 new messages