今天打算在树莓派上编译一个 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 开发完全不懂,谢谢了!
2
Nitroethane 2018-02-22 16:27:00 +08:00 via Android 1
先添加 -static 参数使 GCC 强制静态链接,然后 -l 参数指定要静态链接的库。没记错的话应该是这样
|
3
Nitroethane 2018-02-22 16:28:43 +08:00 via Android
上面说的有些问题,LZ 可以看看这个 https://www.zhihu.com/question/22940048
|
4
smallzhan 2018-02-22 16:51:41 +08:00 1
这个程序用到了 libdl, 估计没办法编译成纯静态的。
|
5
0ZXYDDu796nVCFxq 2018-02-22 17:27:07 +08:00 via iPhone
建议用 -Wl,-rpath 指定库路径,这里可以用相对路径
然后把这些库一起打包 好处就是可以单独更新一些库 一般建议用相同版本的 gcc 编译 |
6
we000 2018-02-22 17:30:30 +08:00
比较复杂, 出状况的可能性也很大, 完全不懂的话可能没法一节课说明白或者期待别人免费帮你搞定, 建议 workaround 或者找人.
另外编译出来也不一定能用, 安卓机网卡一般不支持 AP 模式, 一般也不是兼容的通用接口. |
7
linyinma 2018-02-22 17:33:28 +08:00
这应该不是编译静态库的问题,目的是移植到安卓机,故要找到对应处理器(是 ARM ?)的交叉编译工具链,如果这些概念不熟悉,这个就是白谈了~
|
8
xupefei 2018-02-22 17:34:21 +08:00
前四楼真的知道 LZ 在干啥吗? LZ 想要在树莓派的 Linux 上本地编译一个 elf 去安卓上运行。
正确答案是用 PC 开个虚拟机交叉编译才对。不过就算编译成了也不一定能用。 |
9
yuzenan888 OP @Nitroethane 谢谢回复,刚试了,不行。
@linyinma @xupefei 之前在 x86 上交叉编译过,可以运行。这次由于换电脑了,交叉编译的环境没保存丢了,所以我为了省点事想在树莓派上弄,看来省不了了。我想问下就是为什么静态库一定要交叉编译,同架构本地编译不行吗? |
10
linyinma 2018-02-22 17:47:52 +08:00
@yuzenan888 不是静态库一定要交叉编译,是必须编译在对应处理器能识别的 CPU 指令~~
|
11
choury 2018-02-22 17:52:08 +08:00
首先你需要把这些动态库对应的静态库找到,就是.a 文件
|
12
zhaoxiting1997 2018-02-22 17:54:49 +08:00
或许考虑 android 上装个 termux,直接在 android 删编译?
|
13
updateing 2018-02-22 20:52:28 +08:00 via Android
|
14
vuuv 2018-02-22 22:31:20 +08:00 via Android
pi 是 arm v5 ?现在安卓一般都是 v7a 或者 v8 了,应该可以向前兼容。
但是即便能运行 elf 不代表能正常使用,毕竟 api 不一样。 |
15
icedx 2018-02-22 22:39:26 +08:00 via Android
CMake 是在库名后加.a
|
16
yuzenan888 OP @zhaoxiting1997 如果能这样那就好了,关键是……很多库都没有。
@updateing Android.mk 是啥啊?我根本没接触过,可以编译出 ELF 吗?我想编译一个带 Radius 服务器功能的,想开 EAP-TLS 的 Wi-Fi。 @vuuv 我用的是 pi3,貌似是 armv7。 |
17
updateing 2018-02-23 00:40:48 +08:00 via Android
@yuzenan888 看到 Android.mk 思路就给带偏了,抱歉 😂 这个文件是配合 Android NDK 给 Android 编译 C/C++ 代码用的。但是 NDK 一般是运行在 x86 平台交叉编译用的……
可以试试看 Android 自带的 hostapd 能不能用 EAP-TLS 的配置文件。不能的话,就只能像楼上各位说的一样找齐所有的 .a 再加 -static 了。 |
18
yuzenan888 OP @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' ``` |
19
fgodt 2018-02-23 09:50:22 +08:00
@yuzenan888 没有找到 log 库 你编译选项添加-llog
|
20
yuzenan888 OP @fgodt 编译好了。删掉这两个函数调用就好了,谢谢。
``` //__android_log_vprint(a, "syslog", format, ap); //__android_log_print(a, "syslog", "%s - %s", __progname, syslog_text); ``` |
21
Osk 2018-02-23 13:06:59 +08:00 via Android
可以直接把对应架构的 so 库和可执行文件拷贝过去,然后
export LD_LIBRARY_PATH=`pwd`/usr/lib ./usr/lib/ld-linux-aarch64.so.1 ./usr/bin/XXX 这样运行,反正我一直这么使用一些 linux 下面的命令,直接从 archlinuxarm 里面拷贝过来的,不需要自己编译 |