我正在尝试使用最新Android Studio中的CMake构建我的本机库。我为此准备了gradle脚本,没有任何问题,但我发现了一个小问题 - 我无法为x86 arch编译我的库。
前一段时间......
我的库使用OpenSSL AES / DES加密/解密。我按原样编译了OpenSSL 1.0.2k(静态库),将它链接到我的共享库,除了x86 arch之外一切都很好 - 当时设备上有shared library text segment is not shareable
而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没有?
P.S。我尝试了不同的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,All archs - 没问题):
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)
提前感谢您的帮助!
答案 0 :(得分:1)
解决方案是我需要使用no-asm
标志编译OpenSSL。之后,OpenSSL在x86 arch上正常链接并正常工作。
答案 1 :(得分:0)
set(CMAKE_SHARED_LINKER_FLAGS "-Wall -v -Wl, --no-warn-shared-textrel")
这个确切的工具包是treating warnings as errors
,所以只需添加它来抑制警告。 - no-warn-shared-textrel 是关键
答案 2 :(得分:0)
只需在x86中添加--no-warn-shared-textrel,你应该将它添加到CMakeList.txt:
if($ {ANDROID_ABI} STREQUAL“x86”)
设置(CMAKE_SHARED_LINKER_FLAGS“$ {CMAKE_SHARED_LINKER_FLAGS} -Wl, - no-warn-shared-textrel”)
endif()