简体   繁体   English

NDK Clang 错误:未定义对“localeconv”的引用

[英]NDK Clang error: undefined reference to 'localeconv'

I am trying to build C++ NDK lib inside Android Studio.I have an external lib called json and the Clang compiler faild on localeconv.我正在尝试在 Android Studio 中构建 C++ NDK 库。我有一个名为json的外部库,Clang 编译器在 localeconv 上失败。

json.hpp:11867: error: undefined reference to 'localeconv' json.hpp:11867: 错误:未定义对“localeconv”的引用

The locale.h header exists and located inside ndk dir sysroot/usr/include. locale.h 标头存在并位于 ndk dir sysroot/usr/include 中。

My toolchain looks like this:我的工具链如下所示:

Gradle: (Showing only the part relevant to NDK) Gradle:(仅显示与 NDK 相关的部分)

 externalNativeBuild {
        cmake {

            arguments "-DANDROID_PLATFORM_LEVEL=${platformVersion}",
                    '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
        }

        ndk {
            abiFilters 'armeabi-v7a'

        }
    }

Cmake制作

 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -Wall")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -frtti  -fexceptions  -Wall")

  //'native-lib' is the final .so that's packaged into apk
       target_link_libraries(native-lib
                   OPENAL
                   FREETYPE
                   android
                    EGL
                    ${OPENGL_LIB}
                    log
                    m
                    z
                    atomic
                    gnustl_static
                    ) 

And here is the linker command line:这是链接器命令行:

[1/1] Linking CXX shared library ........\\build\\intermediates\\cmake\\debug\\obj\\armeabi-v7a\\libnative-lib.so FAILED: cmd.exe /C "cd . && D:\\Android\\android-sdk\\ndk-bundle\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\clang++.exe --target=armv7-none-linux-androideabi --gcc-toolchain=D:/Android/android-sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=D:/Android/android-sdk/ndk-bundle/sysroot -fPIC -isystem D:/Android/android-sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=19 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -frtti -fexceptions -Wall -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a --sysroot D:/Android/android-sdk/ndk-bundle/platforms/android-19/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix- [1/1] 链接 CXX 共享库........\\build\\intermediates\\cmake\\debug\\obj\\armeabi-v7a\\libnative-lib.so FAILED: cmd.exe /C "cd . && D: \\Android\\android-sdk\\ndk-bundle\\toolchains\\llvm\\prebuilt\\windows-x86_64\\bin\\clang++.exe --target=armv7-none-linux-androideabi --gcc-toolchain=D:/Android/android- sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=D:/Android/android-sdk/ndk-bundle/sysroot -fPIC -isystem D:/Android/android- sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=19 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7- a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -frtti -fexceptions -Wall -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a --sysroot D:/Android/android-sdk/ndk-bundle/platforms/android-19/arch-arm -Wl,-- build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix- cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so

The complete error:完整的错误:

"D:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a" && cd ." D:\\XXXXX\\XXXXXX\\windows....\\thirdparty\\json/json.hpp:11867: error: undefined reference to 'localeconv' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed. :app:externalNativeBuildDebug FAILED "D:/Android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a" && cd ." D:\\XXXXX\\XXXXXX\\windows.. ..\\thirdparty\\json/json.hpp:11867:错误:未定义对“localeconv” clang++.exe 的引用:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) ninja:构建停止:子命令失败。 :app:externalNativeBuildDebug 失败

The target SDK is 21.Minimum SDK is 19.NDK Version: 15.0.4075724目标SDK是21.Minimum SDK是19.NDK版本:15.0.4075724

The same code base is compiled fine in Visual Studio Android project which uses the same toolchain.相同的代码库在使用相同工具链的 Visual Studio Android 项目中编译得很好。

The answer is - NDK version for SDK 19 doesn't implement the whole C++11 standard in the STL.答案是 - SDK 19 的 NDK 版本没有在 STL 中实现整个 C++11 标准。 locale.h header has stubs for localeconv() method, but the library doesn't implement it.The closest Android SDK that implement localeconv() is SDK 21.This is implicitly stated in the header <locale.h> locale.h头文件包含localeconv()方法的存根,但库没有实现它。实现localeconv()最接近的 Android SDK 是 SDK 21。这在头文件<locale.h>隐式说明

struct lconv* localeconv(void) __INTRODUCED_IN(21) __VERSIONER_NO_GUARD;

#if __ANDROID_API__ >= 21
locale_t duplocale(locale_t) __INTRODUCED_IN(21);
void freelocale(locale_t) __INTRODUCED_IN(21);
locale_t newlocale(int, const char*, locale_t) __INTRODUCED_IN(21);
#endif /* __ANDROID_API__ >= 21 */

char* setlocale(int, const char*);

#if __ANDROID_API__ >= 21
locale_t uselocale(locale_t) __INTRODUCED_IN(21);
#endif /* __ANDROID_API__ >= 21 */


#define LC_GLOBAL_LOCALE __BIONIC_CAST(reinterpret_cast, locale_t, -1L)

__END_DECLS

#endif /* _LOCALE_H_ */

For me, trying to use Lua 5.4.0, I have to define the API level to 21对我来说,尝试使用 Lua 5.4.0,我必须将 API 级别定义为 21

Cmake file as: Cmake文件为:

set(ANDROID_NATIVE_API_LEVEL    21)

I had a similar problem, and unfortunaletly changing API level couldn't work for me --I was working with an old tablet which runs API16.我遇到了类似的问题,不幸的是,更改 API 级别对我不起作用——我正在使用运行 API16 的旧平板电脑。 You can try Crystax NDK or you can write an ugly function that mimics the localeconv() .您可以尝试Crystax NDK,或者您可以编写一个模仿localeconv()的丑陋函数。 The latter had solved my problem since I was building Lua for Android Terminal Emulator for hobby.后者解决了我的问题,因为我正在为业余爱好为 Android 终端模拟器构建 Lua。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM