有没有什么方法可以强制编译出静态的二进制文件?

2018-02-22 16:11:56 +08:00
 yuzenan888

今天打算在树莓派上编译一个 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 开发完全不懂,谢谢了!

6263 次点击
所在节点    Linux
21 条回复
robertgenius
2018-02-22 16:26:27 +08:00
肯定可以了的,gcc -static -static-libgcc -static-libstdc++ *.c
Nitroethane
2018-02-22 16:27:00 +08:00
先添加 -static 参数使 GCC 强制静态链接,然后 -l 参数指定要静态链接的库。没记错的话应该是这样
Nitroethane
2018-02-22 16:28:43 +08:00
上面说的有些问题,LZ 可以看看这个 https://www.zhihu.com/question/22940048
smallzhan
2018-02-22 16:51:41 +08:00
这个程序用到了 libdl, 估计没办法编译成纯静态的。
0ZXYDDu796nVCFxq
2018-02-22 17:27:07 +08:00
建议用 -Wl,-rpath 指定库路径,这里可以用相对路径
然后把这些库一起打包

好处就是可以单独更新一些库
一般建议用相同版本的 gcc 编译
we000
2018-02-22 17:30:30 +08:00
比较复杂, 出状况的可能性也很大, 完全不懂的话可能没法一节课说明白或者期待别人免费帮你搞定, 建议 workaround 或者找人.

另外编译出来也不一定能用, 安卓机网卡一般不支持 AP 模式, 一般也不是兼容的通用接口.
linyinma
2018-02-22 17:33:28 +08:00
这应该不是编译静态库的问题,目的是移植到安卓机,故要找到对应处理器(是 ARM ?)的交叉编译工具链,如果这些概念不熟悉,这个就是白谈了~
xupefei
2018-02-22 17:34:21 +08:00
前四楼真的知道 LZ 在干啥吗? LZ 想要在树莓派的 Linux 上本地编译一个 elf 去安卓上运行。

正确答案是用 PC 开个虚拟机交叉编译才对。不过就算编译成了也不一定能用。
yuzenan888
2018-02-22 17:41:06 +08:00
@Nitroethane 谢谢回复,刚试了,不行。

@linyinma @xupefei 之前在 x86 上交叉编译过,可以运行。这次由于换电脑了,交叉编译的环境没保存丢了,所以我为了省点事想在树莓派上弄,看来省不了了。我想问下就是为什么静态库一定要交叉编译,同架构本地编译不行吗?
linyinma
2018-02-22 17:47:52 +08:00
@yuzenan888 不是静态库一定要交叉编译,是必须编译在对应处理器能识别的 CPU 指令~~
choury
2018-02-22 17:52:08 +08:00
首先你需要把这些动态库对应的静态库找到,就是.a 文件
zhaoxiting1997
2018-02-22 17:54:49 +08:00
或许考虑 android 上装个 termux,直接在 android 删编译?
updateing
2018-02-22 20:52:28 +08:00
hostapd 里面已经有 Android.mk 了,应该是可以直接在 NDK 中编译。可以试试在这个文件里引用静态库……

此外,Android 不是自带 hostapd 么?
vuuv
2018-02-22 22:31:20 +08:00
pi 是 arm v5 ?现在安卓一般都是 v7a 或者 v8 了,应该可以向前兼容。
但是即便能运行 elf 不代表能正常使用,毕竟 api 不一样。
icedx
2018-02-22 22:39:26 +08:00
CMake 是在库名后加.a
yuzenan888
2018-02-22 23:09:36 +08:00
@zhaoxiting1997 如果能这样那就好了,关键是……很多库都没有。

@updateing Android.mk 是啥啊?我根本没接触过,可以编译出 ELF 吗?我想编译一个带 Radius 服务器功能的,想开 EAP-TLS 的 Wi-Fi。

@vuuv 我用的是 pi3,貌似是 armv7。
updateing
2018-02-23 00:40:48 +08:00
@yuzenan888 看到 Android.mk 思路就给带偏了,抱歉 😂 这个文件是配合 Android NDK 给 Android 编译 C/C++ 代码用的。但是 NDK 一般是运行在 x86 平台交叉编译用的……

可以试试看 Android 自带的 hostapd 能不能用 EAP-TLS 的配置文件。不能的话,就只能像楼上各位说的一样找齐所有的 .a 再加 -static 了。
yuzenan888
2018-02-23 09:17:59 +08:00
@zhaoxiting1997 @updateing 我试着在安卓机上编译,卡在这了……
```
/data/data/com.termux/files/usr/include/syslog.h:119: undefined reference to `__android_log_print'
/data/data/com.termux/files/usr/include/syslog.h:116: undefined reference to `__android_log_vprint'
```
fgodt
2018-02-23 09:50:22 +08:00
@yuzenan888 没有找到 log 库 你编译选项添加-llog
yuzenan888
2018-02-23 11:48:55 +08:00
@fgodt 编译好了。删掉这两个函数调用就好了,谢谢。

```
//__android_log_vprint(a, "syslog", format, ap);
//__android_log_print(a, "syslog", "%s - %s", __progname, syslog_text);
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/431686

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX