英文:
CMake how to install shared STL libraries for Android?
问题
根据Android NDK文档(https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#STL)。
"如果使用共享变体,必须将libc++_shared.so包含在APK中。"
因此,作为我的CMake安装的一部分,如果CMAKE_ANDROID_STL_TYPE
等于c++_shared
,我想在我的CMake安装中安装libc++_shared.so
。
我尝试使用install(RUNTIME_DEPENDENCY_SET
,但似乎不适用于Android构建。截至CMake 3.27
。
请注意,file(GET_RUNTIME_DEPENDENCIES)仅支持在Windows、Linux和macOS平台上收集运行时依赖项,因此install(RUNTIME_DEPENDENCY_SET)具有相同的限制。
我有一个解决方法,涉及到一个Python脚本,用于找到我正在编译的ABI的适当的libc++_shared.so
。但我希望能找到一个更优雅的解决方案来解决这个问题。
英文:
According to the Android NDK documentation (https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#STL).
"If using the shared variant, libc++_shared.so must be included in the APK."
Therefore as part of my CMake installation I'd like to install libc++_shared.so
during my CMake installation if CMAKE_ANDROID_STL_TYPE
is equal to c++_shared
.
I tried using install(RUNTIME_DEPENDENCY_SET
but it doesn't seem to work with Android builds. As of CMake 3.27
.
> Note that file(GET_RUNTIME_DEPENDENCIES) only supports collecting the runtime dependencies for Windows, Linux and macOS platforms, so install(RUNTIME_DEPENDENCY_SET) has the same limitation.
I have a workaround involving a python script to find the appropriate libc++_shared.so
for the ABI I'm compiling against. But I'm hoping for a more elegant solution to the problem.
答案1
得分: 0
以下是我想出的解决方案:
注意事项:
- 解析
abis.json
以获取三元组,因为 CMake Android 工具链不提供它。这种方法足够健壮,可以处理将来的 ABI(s)。 - 至少需要 CMake 版本
3.19
,因为使用了string(JSON
。 CMAKE_SYSROOT
由 Android 工具链设置为适当的位置。
支持文档:
- https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#architectures
abis.json
允许我们基于CMAKE_ANDROID_ARCH_ABI
查询三元组。
- https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#STL
- "此库安装到
<NDK>/sysroot/usr/lib/<triple>
。"
- "此库安装到
if ("${CMAKE_ANDROID_STL_TYPE}" MATCHES "shared")
file(READ "${CMAKE_ANDROID_NDK}/meta/abis.json" JSON_FILE)
string(JSON TRIPLE GET "${JSON_FILE}" "${CMAKE_ANDROID_ARCH_ABI}" "triple")
install(FILES "${CMAKE_SYSROOT}/usr/lib/${TRIPLE}/libc++_shared.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
编辑:
似乎目前的惯用做法是使用 Android Gradle 插件来处理此问题。
相关的与 Android NDK 开发人员的对话链接:https://github.com/android/ndk/issues/1905
因此,上面的代码仅在您不想使用 Android Gradle 插件时才有用。
英文:
Here is the solution I came up with:
NOTES:
abis.json
is parsed to get the triple since the CMake Android toolchain doesn't provide it. This approach is robust enough to handle future ABI(s).- Requires at least CMake
3.19
due tostring(JSON
usage CMAKE_SYSROOT
is set by the android toolchain to the appropriate location
Supporting documetnation:
- https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#architectures
abis.json
lets us get query the triple based onCMAKE_ANDROID_ARCH_ABI
- https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#STL
- "This library is installed to
<NDK>/sysroot/usr/lib/<triple>
."
- "This library is installed to
if ("${CMAKE_ANDROID_STL_TYPE}" MATCHES "shared")
file(READ "${CMAKE_ANDROID_NDK}/meta/abis.json" JSON_FILE)
string(JSON TRIPLE GET "${JSON_FILE}" "${CMAKE_ANDROID_ARCH_ABI}" "triple")
install(FILES "${CMAKE_SYSROOT}/usr/lib/${TRIPLE}/libc++_shared.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
EDIT:
It seems like the current idiomatic answer is to use the Android Gradle Plugin to handle this for you.
Link to relevant conversation with an Android NDK developer: https://github.com/android/ndk/issues/1905
So the above code is only useful if you don't want to use the Android Gradle Plugin.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论