Android NDK库.a文件中的gnustl_shared和gnustl_static有什么区别?
What is the difference between gnustl_shared and gnustl_static in Android NDK library .a file?
我想使用 c++ stl 创建 android 库。
我的构建工具是 visual studio 2015,Visual GDB。
源代码是
.cpp
#include <jni.h>
#include "AndroidProject2.h"
#include <vector>
void foo() { std::vector<int> aaa; aaa.push_back(1); }
Android.mk
# Generated by VisualGDB
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := AndroidProject2-shared
LOCAL_SRC_FILES := AndroidProject2.cpp
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := AndroidProject2-static
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)
Application.mk
APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION :=4.9
我构建成功,因此,创建了 lib 文件 libAndroidProject2-static.a、libAndroidProject2-static.so
然后,我尝试更改 Application.mk
中的 APP_STL 选项
APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_shared
NDK_TOOLCHAIN_VERSION :=4.9
当然,构建成功。因此,创建了 lib 文件 libAndroidProject2-shared.a、libAndroidProject2-shared.so
然后,我将它与以前的构建输出进行比较。
我发现 .so 文件的不同之处。 gnustl_static 选项的 .so 文件比 gnustl_shared 选项的 .so 文件大。
但是.a是一样的。
为什么?
我使用了 nm、readelf 但找不到区别。
什么是差异???
不同的是,当你使用static
时,std的代码被编译到生成的.so文件中,而使用shared
时,生成的so文件需要在单独的so文件中包含std
这里有两个问题:
为什么使用 gnustl_static 比 gnustl_shared 生成更大的共享库?
当您使用静态库时,您是将该库中的代码直接包含到您的共享库中,因此您的库会不断增长。当您使用共享库时,您加载了本应从其他共享库中包含的代码,而不是包含它。您需要比较的大小是 libAndroidProject2-static.so + libgnustl_shared.so,因为两者都必须在运行时存在。
为什么不使用gnustl_static做一个更大的静态库?
静态库(在本例中为 libAndroidProject2-static.a)未 linked;它们只是编译源的档案。 libgnustl_static.a 不会被包含,直到你实际上 link libAndroidProject-static.a 进入某些东西,此时你还需要 link libgnustl_static.a。
将 libAndroidProject2-static.a(和 libgnustl_static.a)link编辑到共享库或可执行文件中时,您会看到大小差异。
我想使用 c++ stl 创建 android 库。
我的构建工具是 visual studio 2015,Visual GDB。
源代码是
.cpp
#include <jni.h>
#include "AndroidProject2.h"
#include <vector>
void foo() { std::vector<int> aaa; aaa.push_back(1); }
Android.mk
# Generated by VisualGDB
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := AndroidProject2-shared
LOCAL_SRC_FILES := AndroidProject2.cpp
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := AndroidProject2-static
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)
Application.mk
APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION :=4.9
我构建成功,因此,创建了 lib 文件 libAndroidProject2-static.a、libAndroidProject2-static.so
然后,我尝试更改 Application.mk
中的 APP_STL 选项APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_shared
NDK_TOOLCHAIN_VERSION :=4.9
当然,构建成功。因此,创建了 lib 文件 libAndroidProject2-shared.a、libAndroidProject2-shared.so
然后,我将它与以前的构建输出进行比较。
我发现 .so 文件的不同之处。 gnustl_static 选项的 .so 文件比 gnustl_shared 选项的 .so 文件大。 但是.a是一样的。
为什么? 我使用了 nm、readelf 但找不到区别。 什么是差异???
不同的是,当你使用static
时,std的代码被编译到生成的.so文件中,而使用shared
时,生成的so文件需要在单独的so文件中包含std
这里有两个问题:
为什么使用 gnustl_static 比 gnustl_shared 生成更大的共享库?
当您使用静态库时,您是将该库中的代码直接包含到您的共享库中,因此您的库会不断增长。当您使用共享库时,您加载了本应从其他共享库中包含的代码,而不是包含它。您需要比较的大小是 libAndroidProject2-static.so + libgnustl_shared.so,因为两者都必须在运行时存在。
为什么不使用gnustl_static做一个更大的静态库?
静态库(在本例中为 libAndroidProject2-static.a)未 linked;它们只是编译源的档案。 libgnustl_static.a 不会被包含,直到你实际上 link libAndroidProject-static.a 进入某些东西,此时你还需要 link libgnustl_static.a。
将 libAndroidProject2-static.a(和 libgnustl_static.a)link编辑到共享库或可执行文件中时,您会看到大小差异。