moetayuko / openwrt-passwall-build

Binary distribution of https://github.com/xiaorouji/openwrt-passwall built with official OpenWRT SDK.
MIT License
265 stars 60 forks source link

关于passwall packages SDK版本的问题 #10

Closed nftbty closed 1 year ago

nftbty commented 1 year ago

看到你刚刚在passwall自动编译那边的评论,正好有个问题想问下。 我觉得,其实passwall弄个luci的自动编译就行了,没必要每次编译还要带上packages。一个是你说的版本不全的问题,还有一个用户下载安装也不方便,需要下整个压缩包,再把需要的解压出来。而且每次passwall更新版本号都编译一次packages,但packages可能几天都不更新,而passwall有时候一天要更新几个版本,会造成多个相同版本的重复编译。 我觉得利用好openwrt-passwall-build的opkg源,要方便很多。所以我打算把这个源仓库在passwall安装时就添加到系统,有2个问题想问下:

  1. readme里使用的仓库地址是https://free.nchc.org.tw/osdn,是否台湾镜像就是大陆访问最快的源了,还有其他备用的稳定的源吗,osdn官网mirrors有个香港的xtom,但是用浏览器访问的话是403。不知道nchc的镜像一般落后官方几个小时。
  2. 按你评论说的,不同SDK编译出来可能ABI不兼容。国内的一些第三方op,比如lean的,是要添加snapshots的源吗? 好像这些op除了luci是老的,其他都是跟官方master分支来的,/etc/openwrt-release里面也是DISTRIB_RELEASE='SNAPSHOT'

PS:刚刚看了一下passwall_packages,发现大部分代理软件都是Go程序了,少数几个c/c++的依赖包,都停更好久了,没有更新的需要。唯一还在更新的C程序就是ChinaDNS-NG。只从packages更新而不是新装passwall的角度来看,应该是不会出现这个兼容性问题的。新安装的麻烦些,确实要考虑这个问题,之后做个测试验证下。

moetayuko commented 1 year ago

readme里使用的仓库地址是https://free.nchc.org.tw/osdn,是否台湾镜像就是大陆访问最快的源了,还有其他备用的稳定的源吗,osdn官网mirrors有个香港的xtom,但是用浏览器访问的话是403。不知道nchc的镜像一般落后官方几个小时。

从 osdn 官网直接下载会有个更改镜像的选项,里面只剩 3 个了,nchc 是最快的。时效性不清楚

按你评论说的,不同SDK编译出来可能ABI不兼容。国内的一些第三方op,比如lean的,是要添加snapshots的源吗? 好像这些op除了luci是老的,其他都是跟官方master分支来的,/etc/openwrt-release里面也是DISTRIB_RELEASE='SNAPSHOT'

用魔改 op 跟源码一块编译才能杜绝兼容性问题。他们跟官方进度不同步,跟的是 master 但并不是每天都 merge,如果基础库版本恰好跟当前的官方 master 相同的话倒是能兼容,但没有机制去保证这个东西。

此外官方 snapshot 是日更的,今天的 sdk 编译的包完全有可能在昨天的 snapshot rom 上跑不起来,而且也不会有正常用户去用官方的 snapshot rom。所以做 snapshot 的源主要是为了测试 passwall 跟最新 op 的兼容性,而不是真的希望有人去用。

PS:刚刚看了一下passwall_packages,发现大部分代理软件都是Go程序了,少数几个c/c++的依赖包,都停更好久了,没有更新的需要。唯一还在更新的C程序就是ChinaDNS-NG。只从packages更新而不是新装passwall的角度来看,应该是不会出现这个兼容性问题的。新安装的麻烦些,确实要考虑这个问题,之后做个测试验证下。

非也,go 也是 native 程序,libc 是链接到系统的。本仓库一开始也是只用了一个版本的 sdk,后来发现编译的 v2ray 运行不了才换到了现在的多 sdk 架构 https://github.com/MoetaYuko/openwrt-passwall-build/commit/c96945bfea0b2aecba305b3927330b3dda532526

nftbty commented 1 year ago

刚刚用ldd查了下系统上openwrt编译的xray,果然有动态链接到libc。我印象中golang后来应该是全静态链接所有库的。 查了一下资料,golang链接到libc应该是cgo的原因,cgo默认开启的,即使程序完全没用到cgo的功能,也会默认动态链接到libc。当然,没有用到cgo的可以关掉。即使用到了cgo,也可以通过参数把libc也一起静态链接。 动态链接libc的程序在有些机器上跑不了倒也不是abi的问题,而是程序使用较新版本的libc编译,然后运行机器上的libc版本低于编译时的libc版本,程序运行时会查找版本号不低于编译时libc的动态链接库,没找到所以无法运行。c运行时库是向下兼容的,只要运行机器上的libc版本大于等于程序编译所用libc版本,就可以正常运行。 另外有找到这么一篇文章,情况基本一样。从作者的解决过程,可以印证,就是libc的版本问题。而根据运行时的向下兼容,只要编译不出错,使用尽可能低的libc版本编译,可以保证绝大多数设备都能正常运行。

说到现在go程序都是全静态链接,做了个测试。把系统上原来xray改名为xray_,然后从组件更新下载所有组件的官方编译发布版。使用ldd查看,brook、hysteria、trojan-go、v2ray、xray都没有任何动态链接,显示Not a valid dynamic program。对比2个版本的xray文件,动态链接到libc的版本 23.16MB,官方发布的全静态版 23.44MB,并没有大多少。感觉这些go程序完全可以改成全静态链接。

moetayuko commented 1 year ago

go 静态链接能在包自己的 makefile 里改吗,会不会涉及 openwrt 内部的某些编译脚本

nftbty commented 1 year ago

go 静态链接能在包自己的 makefile 里改吗,会不会涉及 openwrt 内部的某些编译脚本

应该是可以的,只不过编译参数加点东西,就是看openwrt的go编译参数怎么设置了。看xray的Makefile里面有include feeds/packages/lang/golang/golang-package.mk这个文件,分析这个文件应该就能知道怎么加编译参数了。

刚刚去查了静态链接libc的参数,就是增加个-extldflags '-static'的 -ldflags 参数。在openwrt应该就是 GO_PKG_LDFLAGS:= -extldflags '-static'。还有,我去看了下ssr+那边的xray,那边比passwall这边要多一行GO_PKG_LDFLAGS:= -s -w,查了一下,这里是文章链接。这两个标记很有用啊,passwall也可以加上,反正符号表和调试信息对openwrt上运行来说也没有作用,去掉还可以减少一定的大小。 可以看看ssr+那边xray的Makefile,在passwall这边Makefile相同位置加上GO_PKG_LDFLAGS:= -s -w -extldflags '-static'应该就可以静态编译并且减小体积了,当然编译机器上或者sdk要带有libc的静态链接库,这个我想应该是有的吧。

nftbty commented 1 year ago

另外,翻看了下xray和v2ray的提交记录,其实原来也是有-s -w选项的,不过一年前一次drop upx的提交把这个去掉了。另外ssr+那边也翻了下,同一时间也因为drop upx的提交去掉了,不过紧接着下一个提交,大雕又把GO_PKG_LDFLAGS:= -s -w这句加回去了。毕竟这只是去除了binary里面用不上的信息来减小体积,不像upx压缩会影响性能、增大内存。

moetayuko commented 1 year ago

符号表和调试信息确实没啥用

nftbty commented 1 year ago

来回修改测试,发现GO_PKG_LDFLAGS:=后面加的参数全部无效,不管是 -s -w,还是 -extldflags '-static'。 看到golang-package.mk 里面有CGO_LDFLAGS="$(TARGET_LDFLAGS)"以及这么一段

GO_PKG_DEFAULT_LDFLAGS= \
    ......
    -extldflags '$(patsubst -z%,-Wl$(comma)-z$(comma)%,$(TARGET_LDFLAGS))'

于是试着在Makefile里定义TARGET_LDFLAGS:=-static,再重新编译,成功得到全静态链接的xray程序,大小只增加了60KB。

又经过多次尝试,甚至直接修改 golang-package.mk来测试,发现 因为目前golang-package.mk结构原因,-extldflags '-static'没法直接加在GO_PKG_LDFLAGS:=后面使用,只能直接将-static添加到TARGET_LDFLAGS,或者在include golang-package.mk的后面加上GO_PKG_DEFAULT_LDFLAGS+= -extldflags '-static',实测只有这两种方式可以生效。 至于-s -w,后来看到这段注释,

# GO_PKG_LDFLAGS - list of options, default empty
#
#   Additional go tool link options to use when building targets.
#
#   Note that the OpenWrt build system has an option to strip binaries
#   (enabled by default), so -s (Omit the symbol table and debug
#   information) and -w (Omit the DWARF symbol table) flags are not
#   necessary.

才知道openwrt默认就对二进制做了strip,-s -w参数是不必的。