笔者继续学习一下链接的依赖库。
1、起因
Android下面需要需要一个日志解码库,所以笔者就编译了一个parse.so来进行解码,
- 编译器:Clang,基于llvm后端的编译器
- 平台:交叉编译,linux -> aarch64 linux Android,目标平台是这样处理器,arm64位的。
多说几句,该编译器同时也可以编译出其他目标平台的,比如x86_64、x86、armv7a等平台,每个平台都有每个平台下面的库,比如C库等。
比如下图,有四个平台的编译库,如果编译会选择对应平台的库。有我们常见的c库以及c++库。libc、libm、libdl、libstdc++ 、libc++_static、libc++_shared
接下来的问题,就与上面的问题有关,笔者编译出来的库,一运行,发现有依赖。
然后笔者一查看,发现确实有依赖相应的库,检查依赖看上篇文章ARM学习(26)链接库的依赖查看。
如果将该库放到本地,则可以正常运行,
如果发布还必须要带着这一个库,确实麻烦,所以必须要静态编译出一个不依赖C++的库。
注意:
- 如果放到本地,需要添加环境变量,因为默认调用库只是找(/lib 、usr/lib)Linux系统、(system/lib64、system/lib)Android系统。
- export LD_LIBRARY_PATH=xxxx ,目录最好写完整,你要写相对目录。
- 还要注意32位库和64位库的区别,否则会报错,。
如果不加环境变量,则提示找不到对应的库,当然也可以放到系统目录下面,就不用设置环境变量了。
libc++_shared.so搞成32位,然后本机试64位,需要导入64位的库文件。
经过测试,确实只是依赖这一个库(libc++_shared.so),其他库在android目录下面军可以找到(libc.so 和lib.dl.so)。
2、问题解决
尝试一(失败)
笔者经过查询资料发现,c++_shared.so 动态库,其静态库是c++_static.a,于是笔者就去链接,但是失败了,还是有依赖。
尝试二(失败)
明明已经是指明了链接静态库,为什么不行呢,
于是笔者经过查询资料,尝试全部静态链接,通过-static,但是也失败了,看起来静态库需要有main函数才可以链接成功。但是笔者只是一个函数,并没有main函数,无法链接成功。
尝试三(失败)
笔者从网上搜索到,需要使用静态链接C++库,选项,-static-libstdc++,但是依然失败,提示其编译期间没有用
尝试四(失败)
笔者又搜索网上,可以指定链接静态库选项,-Wl,-Bstatic,但是依然没有效果。
尝试五(成功)
笔者经过搜索查到,网上都是使用ndk-build去编译,可以指明静态链接c++的库,就不会有依赖了,于是尝试。
Android.mk
Application.mk,其里面指明了静态链接,
然后编译,可以看到没有c++_shared的依赖了。
于是笔者查看ndk build的编译选项,bdk-build V=1,V=1是显示编译选项,-B是清除原来的编译。
尝试六(成功)
然后笔者就尝试全路径编译,竟然也可以,
然后笔者将全路径改为-lc++_static,也可以了,原来是-lstdc++的原因,笔者后来尝试加上-lstdc++,又不行了,看来需要搞清楚这些库是做什么的,不能随便写依赖。
然后再Andoroid下面测试,也可以正常导入了。
总结
-
加-lc++_static可以静态链接c++的库,前面不要加-lstdc++,不然就无法静态链接c++的库。以上的测试都说明了只要增加-lstdc++,必然会链接c++_shared.so.
-
c++_shared.so 不是android里面的标准库,所以目标target设备一般不会有,
-
且在Android12 源码中,也能找到其为了避开libc++_shared.so,而使用libc++_static.a的例子;
3、附录
一些库的文件组成,便于我们了解库的内容。
libc
包括c库,必然字符串操作(比较、宽字符wchar等),内存拷贝操作,文件操作,网络操作,posix相关、线程操作(pthread)等等
jemalloc.o
arena.o
background_thread.o
base.o
bin.o
bitmap.o
ckh.o
ctl.o
div.o
extent.o
extent_dss.o
extent_mmap.o
hash.o
hooks.o
large.o
log.o
malloc_io.o
mutex.o
mutex_pool.o
nstime.o
pages.o
prng.o
prof.o
rtree.o
stats.o
sz.o
tcache.o
ticker.o
tsd.o
witness.o
libc_init_static.o
getauxval.o
sysconf.o
vdso.o
setjmp_cookie.o
android_set_abort_message.o
strrchr.o
memchr.o
memcmp.o
memcpy.o
memmove.o
memset.o
stpcpy.o
strchr.o
strcmp.o
strcpy.o
strlen.o
strncmp.o
strnlen.o
wmemmove.o
__bionic_clone.o
_exit_with_stack_teardown.o
setjmp.o
syscall.o
vfork.o
property_info_parser.o
context_node.o
contexts_split.o
contexts_serialized.o
prop_area.o
prop_info.o
system_properties.o
NetdClientDispatch.o
__bionic_get_shell_path.o
__cmsg_nxthdr.o
__errno.o
__gnu_basename.o
__libc_current_sigrtmax.o
__libc_current_sigrtmin.o
abort.o
accept.o
accept4.o
access.o
arpa_inet.o
assert.o
atof.o
bionic_allocator.o
bionic_arc4random.o
bionic_futex.o
bionic_netlink.o
bionic_systrace.o
bionic_time_conversions.o
brk.o
c16rtomb.o
c32rtomb.o
chmod.o
chown.o
clearenv.o
clock.o
clock_getcpuclockid.o
clock_nanosleep.o
clone.o
connect.o
ctype.o
dirent.o
dup2.o
environ.o
error.o
eventfd_read.o
eventfd_write.o
exec.o
faccessat.o
fchmod.o
fchmodat.o
fdsan.o
ffs.o
fgetxattr.o
flistxattr.o
flockfile.o
fpclassify.o
fsetxattr.o
ftruncate.o
ftw.o
futimens.o
getcwd.o
getdomainname.o
getentropy.o
gethostname.o
getloadavg.o
getpagesize.o
getpgrp.o
getpid.o
getpriority.o
gettid.o
get_device_api_level.o
grp_pwd.o
grp_pwd_file.o
iconv.o
icu_wrappers.o
ifaddrs.o
inotify_init.o
ioctl.o
killpg.o
langinfo.o
lchown.o
lfs64_support.o
libc_init_common.o
libgen.o
link.o
locale.o
lockf.o
lstat.o
mblen.o
mbrtoc16.o
mbrtoc32.o
memmem.o
mempcpy.o
mkdir.o
mkfifo.o
mknod.o
mntent.o
mremap.o
net_if.o
netdb.o
netinet_in.o
nl_types.o
open.o
pathconf.o
pause.o
pipe.o
poll.o
posix_fadvise.o
posix_fallocate.o
posix_madvise.o
posix_timers.o
ptrace.o
pty.o
raise.o
rand.o
readlink.o
reboot.o
recv.o
rename.o
rmdir.o
scandir.o
sched_getaffinity.o
sched_getcpu.o
semaphore.o
send.o
setegid.o
seteuid.o
setpgrp.o
sigaction.o
signal.o
sigprocmask.o
socket.o
spawn.o
stat.o
statvfs.o
stdlib_l.o
strchrnul.o
strerror.o
string_l.o
strings_l.o
strsignal.o
strtol.o
strtold.o
swab.o
symlink.o
sync_file_range.o
sys_epoll