我正在尝试从c_speech_features C库中为不同的Android ABI创建共享库。我已经下载了Android NDK,并尝试按照"交叉编译Android"的cmake说明来创建.so
库。
尝试的步骤:
-
下载了库源代码
-
已将
CMakeLists.txt
文件更改为cmake_minimum_required (VERSION 3.6) project (c_speech_features) include(GNUInstallDirs) ### I ADDED THESE VARIABLES TO COMPILE FOR ANDROID ### set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 23) set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) set(CMAKE_ANDROID_NDK /path_to/android-ndk-r18b/) option (ENABLE_DOUBLE "Enable double-precision floats" OFF) if (ENABLE_DOUBLE) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dkiss_fft_scalar=double") endif () configure_file ("c_speech_features_config.h.in" "c_speech_features_config.h") add_library (objlib OBJECT c_speech_features.c kiss_fft130/kiss_fft.c kiss_fft130/tools/kiss_fftr.c) set_property (TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1) include_directories (kiss_fft130 kiss_fft130/tools) add_library (c_speech_features SHARED $<TARGET_OBJECTS:objlib>) add_library (c_speech_features_static STATIC $<TARGET_OBJECTS:objlib>)
- 在终端中打开源目录
- 冉
cmake
- 冉
make
但是,无论我将ANDROID_ARCH_ABI
设置为什么,在运行cmake
然后make
生成的.so
库的 ABI 始终与未在CMakeLists.txt
文件中设置上述变量时相同。结果如下:
~$ readelf -h libc_speech_features.so | grep 'Class|File|Machine'
Class: ELF64
Machine: Advanced Micro Devices X86-64
我尝试在库存储库的全新下载上执行此操作,因此不认为这是缓存的 CMake 文件的问题。
是否可以以这种方式为不同的 ABI 架构创建.so
库?如果是这样,我应该如何改变我的方法?如果有其他方法来编译库,我也很乐意尝试。以下是我所做的其他一些尝试。
齐瓦列夫评论后编辑
我已经从CMakeLists.txt
文件中删除了设置变量,现在正在尝试通过运行命令来使用工具链文件
cmake -DCMAKE_TOOLCHAIN_FILE=/path_to/android-ndk-r18b/build/cmake/android.toolchain.cmake
-DCMAKE_ANDROID_NDK=/path_to/android-ndk-r18b
-DANDROID_PLATFORM=android-24 -DCMAKE_ANDROID_ARCH_ABI=x86
.
然后我运行make
来构建.so
文件。但是现在生成的.so
库始终是:
Class: ELF32
Machine: ARM
我是否错误地设置了所需的体系结构?使用 cmake 工具链时应该如何更改架构?
其他尝试
我已经看到还有许多其他方法可以在Android应用程序中包含C库:
我未能成功直接添加 C 代码并构建 库使用安卓工作室(文档描述),因为我不能 访问任何方法。我确信这种方式是可能的,但现在已经了解如何包含和使用预先存在的
.so
库,因此创建一个库可能会更容易。安卓NDK独立工具链我还没懂怎么做 在此 C 库上运行,其
CMakeLists.txt
定义如何 图书馆建成
我经常看到android-cmake被提及,我可能很愚蠢 在这里,但可以从自述文件中看到如何使用它(它也很旧 所以可能不比直接使用 cmake 更好)。
我不认为使用 Android.mk 更容易看到,因为我有一个图书馆 已经有了
CMakeLists.txt
文件,所以转换它似乎 喜欢更多工作
我是否错误地设置了所需的架构?使用 cmake 工具链时应该如何更改架构?
是的。不幸的是,Android和CMake同时添加了对另一个的支持,因此有两个工作流程,您正在混合和匹配它们。
为了获得对新 NDK 的最佳支持,您需要使用 NDK 的内置支持(工具链文件,就像您正在使用的那样),但您需要使用ANDROID_*
变量而不是CMAKE_ANDROID_*
变量。
请参阅 CMake 的 Android 文档,了解可用标志的细分:https://developer.android.com/ndk/guides/cmake。
要修复您的特定调用,您需要:
$ cmake -DCMAKE_TOOLCHAIN_FILE=/path_to/android-ndk-r18b/build/cmake/android.toolchain.cmake
-DANDROID_PLATFORM=android-24 -DANDROID_ABI=x86
.
(显然ANDROID_ABI
没有列在第一个表中,因为用户在通过 gradle 使用 CMake 时不必担心,但它在页面下方有记录)
如果您使用的是 r18 之前的 NDK(您不是,但也许其他人会登陆这里),则该页面上不再列出一些其他标志(例如ANDROID_TOOLCHAIN
)。工具链文件本身的顶部有一个注释,列出了它支持的所有选项,如果你需要沿着这条路走下去。