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