【问题标题】:CMake link static library error, while with NDK works fineCMake 链接静态库错误,而使用 NDK 工作正常
【发布时间】:2017-03-30 21:26:20
【问题描述】:

我正在尝试在最新的 Android Studio 中使用 CMake 构建我的本机库。我为此准备了 gradle 脚本,没有任何问题,但我发现了一个小问题 - 我无法为 x86 arch 编译我的库。

之前... 我的图书馆使用 OpenSSL AES/DES 加密/解密。我按原样编译了 OpenSSL 1.0.2k(静态库),将其链接到我的共享库,除了 x86 架构之外一切都很好 - 在当时的设备上出现错误 shared library text segment is not shareabledlopen。然后我用-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),但没有任何效果。仅x86arch 会出现此问题。

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)

提前感谢您的帮助!

【问题讨论】:

    标签: android c++ c android-ndk cmake


    【解决方案1】:

    解决方案是我需要使用 no-asm 标志编译 OpenSSL。之后 OpenSSL 链接并在 x86 架构上正常工作。

    【讨论】:

      【解决方案2】:
      set(CMAKE_SHARED_LINKER_FLAGS "-Wall -v -Wl, --no-warn-shared-textrel")
      

      这个确切的工具箱是treating warnings as errors,所以只需添加它来抑制警告。 --no-warn-shared-textrel 是关键

      【讨论】:

      • 1. --no-warn-shared-textrel 是 CMake 2 的未知选项。如果我从链接器标志中删除将警告视为错误,我会在 x86 设备上得到 library has text rellocations,而 System.loadLibrary 调用。这就是为什么不是我的解决方案。
      • 在链接器标志之前添加set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
      • set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") 没有帮助
      • 如果您的目标是较新版本的 Android,这将生成不会加载的二进制文件:android.googlesource.com/platform/bionic/+/master/…
      【解决方案3】:

      只是在 x86 中,添加 --no-warn-shared-textrel,您应该将其添加到 CMakeList.txt:

      如果 (${ANDROID_ABI} STREQUAL "x86")
      设置(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-shared-textrel")
      endif()

      祝你好运。

      【讨论】:

      • 此库编译后,但在 x86 设备上运行时出现崩溃:java.lang.UnsatisfiedLinkError: dlopen failed: has text relocations
      猜你喜欢
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多