我正在尝试在最新的 Android Studio 中使用 CMake 构建我的原生库。我为此准备了 gradle 脚本,没有任何问题,但我发现了一个小问题 - 我无法为 x86 arch 编译我的库。
前一段时间...
我的图书馆使用 OpenSSL AES/DES 加密/解密。我按原样编译了 OpenSSL 1.0.2k(静态库),将它链接到我的共享库,一切都很好,除了 x86 arch - 出现错误 shared library text segment is not shareable
while dlopen
在当时的设备上。然后我用 -fPIC
标志重新编译 OpenSSL,再次链接它,错误消失了。我正在使用 NDK 13b 进行构建。
现在...
我正在尝试从 NDK 迁移到 CMake,因为它对我来说有更多功能,Android Studio 通常只能使用 CMake 自动完成和 lint C/C++ 代码。我编写了 CMakeList.txt
并且它有效,但是 shared library text segment is not shareable
的问题再次出现,但是在 CMake 构建过程的链接步骤中。错误:
D:/User/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: warning: shared library text segment is not shareable
D:/User/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: treating warnings as errors
我禁用了将此警告视为错误,并且 shared library text segment is not shareable
在设备上再次出现 dlopen
时出现。
问题是什么?为什么 NDK 构建没有任何问题而 CMake 没有?
附言我尝试了不同的 CMAKE
标志(例如 CMAKE_POSITION_INDEPENDENT_CODE
)但没有任何效果。此问题仅发生在 x86
arch 上。
CMakeLists.txt(x86 构建失败,所有其他 - 没问题):
cmake_minimum_required(VERSION 3.4.1)
include_directories(include/)
find_library(log-lib log)
add_library(libcrypto STATIC IMPORTED)
add_library(libssl STATIC IMPORTED)
add_library(testlib SHARED test.c)
set_target_properties(libcrypto
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/static/${ANDROID_ABI}/libcrypto.a)
set_target_properties(libssl
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/static/${ANDROID_ABI}/libssl.a)
target_link_libraries(testlib libcrypto libssl ${log-lib})
set (CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fPIC")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -fPIC")
Android.mk(NDK14b,所有架构 - 没问题):
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/static/$(TARGET_ARCH_ABI)/libcrypto.a
LOCAL_MODULE := crypto
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := $(LOCAL_PATH)/static/$(TARGET_ARCH_ABI)/libssl.a
LOCAL_MODULE := ssl
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LCOAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := test.c
LOCAL_MODULE := testlib
LOCAL_STATIC_LIBRARIES := crypto ssl
include $(BUILD_SHARED_LIBRARY)
在此先感谢您的帮助!
最佳答案
解决方案是我需要使用 no-asm
标志编译 OpenSSL。之后 OpenSSL 链接并在 x86 arch 上正常工作。
关于android - CMake 链接静态库错误,而 NDK 工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43128655/