技术解析

有没有什么方法可以强制编译出静态的二进制文件?
0
2021-06-24 20:29:01
idczone

今天打算在树莓派上编译一个 hostapd 给安卓机用,结果发现里面没有 /configure 脚本,只有 Makefile。

我编译一下,然后用 file 命令看了一下,是动态的二进制文件。

	linux-vdso.so.1 =>  (0x00007ffec77ce000)
	librt.so.1 => /lib64/librt.so.1 (0x00007f782ab23000)
	libssl.so.10 => /lib64/libssl.so.10 (0x00007f782a8b1000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f782a450000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f782a08d000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7829e71000)
	libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f7829c24000)
	libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f782993c000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f7829738000)
	libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f7829505000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f7829301000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f78290eb000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f782ad2b000)
	libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f7828edd000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f7828cd9000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f7828abf000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f7828898000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f7828636000)

由于安卓机没有这些库文件,所以不能使用动态库。有什么方法可以强制将它编译成静态二进制文件吗?

我对 Linux 开发完全不懂,谢谢了!


先添加 -static 参数使 GCC 强制静态链接,然后 -l 参数指定要静态链接的库。没记错的话应该是这样

上面说的有些问题,LZ 可以看看这个 https://www.zhihu.com/question/22940048

这个程序用到了 libdl, 估计没办法编译成纯静态的。

建议用 -Wl,-rpath 指定库路径,这里可以用相对路径
然后把这些库一起打包
好处就是可以单独更新一些库
一般建议用相同版本的 gcc 编译

比较复杂, 出状况的可能性也很大, 完全不懂的话可能没法一节课说明白或者期待别人免费帮你搞定, 建议 workaround 或者找人.
另外编译出来也不一定能用, 安卓机网卡一般不支持 AP 模式, 一般也不是兼容的通用接口.

这应该不是编译静态库的问题,目的是移植到安卓机,故要找到对应处理器(是 ARM ?)的交叉编译工具链,如果这些概念不熟悉,这个就是白谈了~

前四楼真的知道 LZ 在干啥吗? LZ 想要在树莓派的 Linux 上本地编译一个 elf 去安卓上运行。
正确答案是用 PC 开个虚拟机交叉编译才对。不过就算编译成了也不一定能用。

谢谢回复,刚试了,不行。
之前在 x86 上交叉编译过,可以运行。这次由于换电脑了,交叉编译的环境没保存丢了,所以我为了省点事想在树莓派上弄,看来省不了了。我想问下就是为什么静态库一定要交叉编译,同架构本地编译不行吗?

不是静态库一定要交叉编译,是必须编译在对应处理器能识别的 CPU 指令~~

首先你需要把这些动态库对应的静态库找到,就是.a 文件

或许考虑 android 上装个 termux,直接在 android 删编译?

hostapd 里面已经有 Android.mk 了,应该是可以直接在 NDK 中编译。可以试试在这个文件里引用静态库……
此外,Android 不是自带 hostapd 么?

pi 是 arm v5 ?现在安卓一般都是 v7a 或者 v8 了,应该可以向前兼容。
但是即便能运行 elf 不代表能正常使用,毕竟 api 不一样。

CMake 是在库名后加.a

如果能这样那就好了,关键是……很多库都没有。
Android.mk 是啥啊?我根本没接触过,可以编译出 ELF 吗?我想编译一个带 Radius 服务器功能的,想开 EAP-TLS 的 Wi-Fi。
我用的是 pi3,貌似是 armv7。

看到 Android.mk 思路就给带偏了,抱歉
数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服