从静态库*.a文件构建共享库

3

我已经在Stack Overflow上阅读了其他类似的问题,但它们和我的情况不相同。

我有一个FreeImage.a(23 MB文件)文件,这是一个预编译的静态库,用于Android。我还有FreeImage项目的源代码,其中包含头文件。

我想要从我拥有的(.a)文件和JNI代码(FreeImageCompilation.cpp)构建.SO文件。下面的代码编译得很好,但是它只产生5KB的SO文件,而(*.a文件为23 MB)?

请问是否有人可以检查我下面使用*.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)
2个回答

3
要回答标题中的问题,以下是如何从静态库创建共享库的方法:
# 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/


0

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


这意味着编译后的SO文件是正确的,当打包APK时,我需要将*.a文件与SO文件一起放置吗? - Kirtan
根据WinGDB网站的说法:“静态库是一个实用程序库,可用作创建共享库的组件。它不在APK文件中,也不安装到设备上。Java代码无法在运行时加载它。 静态库构建到{output dir}/obj/local/{ABI name}文件夹中。这也是共享库的中间文件夹,但后者会自动复制到它们的最终目标{output dir}/libs/{ABI name}中。静态库仍然留在中间文件夹中,供链接器构建共享库使用。” - eozgonul
所以你不必将 .a 文件放入 APK 中,这应该在链接过程中处理。 - eozgonul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接