【问题标题】:Building Shared Library from static Library *.a file从静态库 *.a 文件构建共享库
【发布时间】:2013-09-19 07:49:33
【问题描述】:

我已经阅读了其他类似的堆栈溢出问题,但他们没有相同的场景。

我有 FreeImage.a(23 MB 文件)文件,它为 android 预编译静态库。 我也有 FreeImage 项目的源代码,其中有头文件。

我想用我的 JNI 代码 (FreeImageCompilation.cpp) 从 (.a) 文件构建 .SO 文件 下面的代码编译得很好,但它确实产生了(5KB only)whre(*.a 文件是 23 MB)的 SO 文件?

有人可以检查我下面使用 *.a 文件的代码是否正确吗?

在我的 Android.mk 中,我有以下代码。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := FreeImage
LOCAL_SRC_FILES := libFreeImage.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/FreeImage/Source/
include $(PREBUILT_STATIC_LIBRARY)

#My Own SO file

LOCAL_STATIC_LIBRARIES := FreeImage
include $(CLEAR_VARS)
LOCAL_MODULE    := FreeImageSo
LOCAL_SRC_FILES := FreeImageCompilation.cpp
LOCAL_STATIC_LIBRARIES := FreeImage
include $(BUILD_SHARED_LIBRARY)

【问题讨论】:

    标签: android c++ android-ndk shared-libraries static-libraries


    【解决方案1】:

    要回答标题中的问题,以下是如何从静态库创建共享库:

    # static library 1
    include $(CLEAR_VARS)
    LOCAL_MODULE := lib1
    LOCAL_SRC_FILES := lib1.cpp
    include $(BUILD_STATIC_LIBRARY)
    
    # static library 2
    include $(CLEAR_VARS)
    LOCAL_MODULE := lib2
    LOCAL_SRC_FILES := lib2.cpp
    include $(BUILD_STATIC_LIBRARY)
    
    # this shared library will have all symbols from two above libraries
    include $(CLEAR_VARS)
    LOCAL_MODULE := lib_shared
    LOCAL_SRC_FILES := empty.cpp
    LOCAL_WHOLE_STATIC_LIBRARIES := lib1 lib2
    include $(BUILD_SHARED_LIBRARY)
    

    需要注意的重要选项是LOCAL_WHOLE_STATIC_LIBRARIES。如果你使用常规的LOCAL_STATIC_LIBRARIES,因为你没有在 lib_shared 中使用来自lib1lib2 的任何符号,它们将在链接时被剥离。为了防止这种情况发生,LOCAL_WHOLE_STATIC_LIBRARIES 在链接行中添加了以下选项,以确保符号不会被剥离:

    -Wl,--whole-archive -llib1 -llib2 -Wl,--no-whole-archive
    

    更多信息在我的博文中:http://gosuwachu.io/

    【讨论】:

      【解决方案2】:

      这完全正确,但您似乎对概念感到困惑。正如您所期望的那样,您的静态库未包含在您的共享库中。您的静态库只是链接到共享库。最后,您的程序需要一个 .so 文件和一个 .a 才能正常运行,而不仅仅是一个包含所有内容的大 .so。

      【讨论】:

      • 表示编译后的 SO 文件是正确的,我需要将 . *.a 打包 apk 时带有 SO 文件的文件?
      • 根据 WinGDB 网站:“静态库是一个实用程序库,可用作创建共享库的组件。它不存在于 APK 文件中,也未安装到设备上。Java 代码无法在运行时加载它。静态库构建到 {output dir}/obj/local/{ABI name} 文件夹。这也是共享库的中间文件夹,但后者会自动复制到它们的最终目的地 {输出目录}/libs/{ABI 名称}。静态库保留在中间文件夹中,链接器可以在其中构建共享库。"
      • 因此您不必将 .a 文件放入 APK。这应该在链接过程中处理。
      猜你喜欢
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多