按照How to successfully build packages for WD My Cloud from source中的介绍,搭建完成WDMyCloud
的编译环境
整个 WD MyCloud
的编译项目,可以直接在树莓派中进行编译。只是编译4KB
分页(主要用于编译过程)的高版本应用的时候,需要在 raspbian-wheezy
系统中进行编译。
在树莓派中编译 WD MyCloud
代码的时候,由于都是 ARM
环境,因此,不需要 QEMU
的介入,以前由于 QEMU
导致的问题可以规避。
推荐在树莓派4B版本上搭建编译环境,效果来看,速度还是不错的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
root@debian:~/git-lfs# DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc dpkg-buildpackage: source package git-lfs dpkg-buildpackage: source version 2.9.0 dpkg-buildpackage: source changed by brian m. carlson <bk2204@github.com> dpkg-buildpackage: host architecture armhf dpkg-source --before-build git-lfs debian/rules clean mkdir -p /tmp/gocache GO111MODULE=on GOFLAGS=-mod=vendor GOCACHE=/tmp/gocache dh clean --buildsystem=golang --with=golang dh_testdir -O--buildsystem=golang dh_auto_clean -O--buildsystem=golang debian/rules override_dh_clean make[1]: Entering directory `/root/git-lfs' rm -f debian/debhelper.log rm -rf man dh_clean make[1]: Leaving directory `/root/git-lfs' debian/rules build mkdir -p /tmp/gocache GO111MODULE=on GOFLAGS=-mod=vendor GOCACHE=/tmp/gocache dh build --buildsystem=golang --with=golang dh_testdir -O--buildsystem=golang dh_auto_configure -O--buildsystem=golang debian/rules override_dh_auto_build make[1]: Entering directory `/root/git-lfs' dh_auto_build runtime: failed to create new OS thread (have 2 already; errno=22) throw: runtime.newosproc goroutine 1 [syscall]: syscall.Syscall6() /build/buildd-golang_1.0.2-1.1-armhf-ygST23/golang-1.0.2/src/pkg/syscall/asm_linux_arm.s:42 +0x8 syscall.setsockopt(0x3, 0x29, 0x1a, 0x10960248, 0x4, ...) /usr/lib/go/src/pkg/syscall/zsyscall_linux_arm.go:1101 +0x68 syscall.SetsockoptInt(0x3, 0x29, 0x1a, 0x0, 0x0, ...) /usr/lib/go/src/pkg/syscall/syscall_linux.go:478 +0x6c net.probeIPv6Stack(0xff0000, 0x10960240) /usr/lib/go/src/pkg/net/ipsock_posix.go:41 +0x2a0 net.init() /usr/lib/go/src/pkg/net/unixsock_posix.go:-2932 +0x7d4 net/http.init() /usr/lib/go/src/pkg/net/http/transport.go:753 +0x84 main.init() /usr/lib/go/src/cmd/go/vet.go:37 +0xa8 goroutine 2 [runnable]: created by runtime.main /build/buildd-golang_1.0.2-1.1-armhf-ygST23/golang-1.0.2/src/pkg/runtime/proc.c:221 runtime: failed to create new OS thread (have 2 already; errno=22) throw: runtime.newosproc goroutine 1 [syscall]: syscall.Syscall6() /build/buildd-golang_1.0.2-1.1-armhf-ygST23/golang-1.0.2/src/pkg/syscall/asm_linux_arm.s:42 +0x8 syscall.setsockopt(0x3, 0x29, 0x1a, 0x10960248, 0x4, ...) /usr/lib/go/src/pkg/syscall/zsyscall_linux_arm.go:1101 +0x68 syscall.SetsockoptInt(0x3, 0x29, 0x1a, 0x0, 0x0, ...) /usr/lib/go/src/pkg/syscall/syscall_linux.go:478 +0x6c net.probeIPv6Stack(0xff0000, 0x10960240) /usr/lib/go/src/pkg/net/ipsock_posix.go:41 +0x2a0 net.init() /usr/lib/go/src/pkg/net/unixsock_posix.go:-2932 +0x7d4 net/http.init() /usr/lib/go/src/pkg/net/http/transport.go:753 +0x84 main.init() /usr/lib/go/src/cmd/go/vet.go:37 +0xa8 goroutine 2 [runnable]: created by runtime.main /build/buildd-golang_1.0.2-1.1-armhf-ygST23/golang-1.0.2/src/pkg/runtime/proc.c:221 dh_auto_build: go install -v returned exit code 2 make[1]: *** [override_dh_auto_build] Error 2 make[1]: Leaving directory `/root/git-lfs' make: *** [build] Error 2 dpkg-buildpackage: error: debian/rules build gave error exit status 2 |
这个问题产生的原因是在qemu
中创建线程/进程的时候,要求增加CLONE_SYSVSEM
标志,否则会出现异常。 go
在创建线程/进程的时候,没有指定这个标记。解决方法就是修改src/pkg/runtime/os_linux.c
中的void runtime·newosproc(M *mp, void *stk)
函数,在flag
中增加CLONE_SYSVSEM
标志。
这个问题解决起来比较复杂,我们在x86
下面直接进行交叉编译的时候,是没办法通过编译的,我们可以通过树莓派下进行编译。树莓派使用2015-05-05-raspbian-wheezy
版本的镜像来进行编译。
树莓派这个版本的系统问题在于 wheezy
的源已经被移动地址,因此更新安装软件的时候会报告 404
错误,我们需要手工修改一下源地址。
1 |
$ sed -i "s/wheezy/oldoldstable/g" /etc/apt/source.list |
安装编译依赖
1 2 3 4 5 |
$ sudo apt-get update $ sudo apt-get install vim $ sudo apt-get install devscripts |
下载并编译代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ wget http://security.debian.org/debian-security/pool/updates/main/g/golang/golang_1.3.3.orig.tar.gz # 也可本站下载 wget https://www.mobibrw.com/wp-content/uploads/2019/11/golang_1.3.3.orig_.tar.gz -O golang_1.3.3.orig.tar.gz $ mkdir golang_1.3.3 $ tar xvf golang_1.3.3.orig.tar.gz -C golang_1.3.3 $ cd golang_1.3.3/go $ wget http://security.debian.org/debian-security/pool/updates/main/g/golang/golang_1.3.3-1+deb8u2.debian.tar.xz # 也可本站下载 wget https://www.mobibrw.com/wp-content/uploads/2019/11/golang_1.3.3-1deb8u2.debian.tar.xz $ tar xvf golang_1.3.3-1*.debian.tar.xz # BUG `runtime: failed to create new OS thread (have 2 already; errno=22)` $ sed -i "s/| CLONE_THREAD/| CLONE_THREAD | CLONE_SYSVSEM/g" src/pkg/runtime/os_linux.c $ export GOARCH=arm $ export GOOS=linux $ DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc |
完成之后,拷贝到编译环境中并执行安装
1 2 3 4 5 6 7 |
$ dpkg -i golang-src_1.3.3-1*_armhf.deb $ dpkg -i golang-go-linux-arm_1.3.3-1*_armhf.deb $ dpkg -i golang-go_1.3.3-1*_armhf.deb $ dpkg -i golang-doc_1.3.3-1*_all.deb |
继续编译,报告如下错误信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
root@debian:~/git-lfs# DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc dpkg-buildpackage: source package git-lfs dpkg-buildpackage: source version 2.9.0 dpkg-buildpackage: source changed by brian m. carlson <bk2204@github.com> dpkg-buildpackage: host architecture armhf dpkg-source --before-build git-lfs debian/rules clean mkdir -p /tmp/gocache GO111MODULE=on GOFLAGS=-mod=vendor GOCACHE=/tmp/gocache dh clean --buildsystem=golang --with=golang dh_testdir -O--buildsystem=golang dh_auto_clean -O--buildsystem=golang debian/rules override_dh_clean make[1]: Entering directory `/root/git-lfs' rm -f debian/debhelper.log rm -rf man dh_clean make[1]: Leaving directory `/root/git-lfs' debian/rules build mkdir -p /tmp/gocache GO111MODULE=on GOFLAGS=-mod=vendor GOCACHE=/tmp/gocache dh build --buildsystem=golang --with=golang dh_testdir -O--buildsystem=golang dh_auto_configure -O--buildsystem=golang debian/rules override_dh_auto_build make[1]: Entering directory `/root/git-lfs' dh_auto_build fatal error: rt_sigaction failure runtime stack: runtime.throw(0x51f24d) /usr/lib/go/src/pkg/runtime/panic.c:520 +0x5c runtime.setsig(0x40, 0x7d5ec, 0x523901) /usr/lib/go/src/pkg/runtime/os_linux.c:309 +0xbc runtime.initsig() /usr/lib/go/src/pkg/runtime/signal_unix.c:39 +0x94 runtime.mstart() /usr/lib/go/src/pkg/runtime/proc.c:621 +0x80 goroutine 16 [runnable]: runtime.main() /usr/lib/go/src/pkg/runtime/proc.c:207 runtime.goexit() /usr/lib/go/src/pkg/runtime/proc.c:1445 fatal error: rt_sigaction failure runtime stack: runtime.throw(0x51f24d) /usr/lib/go/src/pkg/runtime/panic.c:520 +0x5c runtime.setsig(0x40, 0x7d5ec, 0x523901) /usr/lib/go/src/pkg/runtime/os_linux.c:309 +0xbc runtime.initsig() /usr/lib/go/src/pkg/runtime/signal_unix.c:39 +0x94 runtime.mstart() /usr/lib/go/src/pkg/runtime/proc.c:621 +0x80 goroutine 16 [runnable]: runtime.main() /usr/lib/go/src/pkg/runtime/proc.c:207 runtime.goexit() /usr/lib/go/src/pkg/runtime/proc.c:1445 dh_auto_build: go install -v returned exit code 2 make[1]: *** [override_dh_auto_build] Error 2 make[1]: Leaving directory `/root/git-lfs' make: *** [build] Error 2 dpkg-buildpackage: error: debian/rules build gave error exit status 2 |
这个问题产生的原因是在qemu
中无法处理编号为 64 的信号(Qemu rejects rt_sigaction of SIGRTMAX (64).
),我们需要忽略这个信号。解决方法就是修改src/pkg/runtime/os_linux.c
中的void
函数,忽略这个信号。
runtime·setsig(int32 i, GoSighandler *fn, bool restart)
1 2 3 4 5 6 7 8 |
# BUG `fatal error: rt_sigaction failure` $ sed -i "s/runtime·rt_sigaction(i, \&sa, nil, sizeof(sa.sa_mask)) != 0/runtime·rt_sigaction(i, \&sa, nil, sizeof(sa.sa_mask)) != 0 \&\& i != 64/g" src/pkg/runtime/os_linux.c $ export GOARCH=arm $ export GOOS=linux $ DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc |
完成之后,拷贝到编译环境中并执行安装
1 2 3 4 5 6 7 |
$ dpkg -i golang-src_1.3.3-1*_armhf.deb $ dpkg -i golang-doc_1.3.3-1*_all.deb $ dpkg -i golang-go-linux-arm_1.3.3-1*_armhf.deb $ dpkg -i golang-go_1.3.3-1*_armhf.deb |
编译环境安装完成之后,可以成功编译golang-1.3.3
,中途可能会失败,失败之后,重新编译可以通过。
编译 golang-1.4
,由于 golang-1.4
的特殊性,任何高于 golang-1.4
版本的 golang
,都需要 golang-1.4
的编译环境才能开始编译安装!
我们依旧需要在树莓派环境中 raspbian-wheezy
&& WD MyCloud
编译,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
$ git clone https://salsa.debian.org/go-team/compiler/golang.git -b debian/2%1.4.3-3 # 也可下载一份拷贝 wget https://salsa.debian.org/go-team/compiler/golang/-/archive/debian/2%251.4.3-3/golang-debian-2%251.4.3-3.tar.gz # 也可本站下载一份代码拷贝 wget https://www.mobibrw.com/wp-content/uploads/2019/11/golang-debian-21.4.3-3.tar.gz -O golang-debian-2%251.4.3-3.tar.gz # tar xvf golang-debian-2%1.4.3-3.tar.gz # mv golang-debian-2%1.4.3-3 golang $ cd golang # BUG `fatal error: rt_sigaction failure` $ sed -i "s/runtime·rt_sigaction(i, \&sa, nil, sizeof(sa.sa_mask)) != 0/runtime·rt_sigaction(i, \&sa, nil, sizeof(sa.sa_mask)) != 0 \&\& i != 64/g" src/runtime/os_linux.c # BUG `runtime: failed to create new OS thread (have 2 already; errno=22)` $ sed -i "s/| CLONE_THREAD/| CLONE_THREAD | CLONE_SYSVSEM/g" src/runtime/os_linux.c # 如果使用 go 1.4.3 编译 go 1.4.3 可能会报告如下三个错误,如果使用 go 1.3.3 编译 go 1.4.3不会出现错误 #--- FAIL: TestParseInLocation (0.02s) # format_test.go:202: ParseInLocation(Feb 01 2013 AST, Baghdad) = 2013-02-01 00:00:00 +0000 AST, want 2013-02-01 00:00:00 +0300 +03 #--- FAIL: TestLoadFixed (0.00s) # time_test.go:929: Now().In(loc).Zone() = "-01", -3600, want "GMT+1", -36 $ rm -rf src/time/format_test.go # time_test.go:929: Now().In(loc).Zone() = "-01", -3600, want "GMT+1", -36 $ rm -rf src/time/time_test.go # file_test.go:121: WriteTo failed: write ip: bad address $ rm -rf src/net/file_test.go $ export GOARCH=arm $ export GOOS=linux $ DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc |
完成之后,拷贝到编译环境中并执行安装
1 2 3 4 5 6 7 8 9 |
$ dpkg -i golang-src_1.4.3-3_armhf.deb $ dpkg -i golang-go_1.4.3-3_armhf.deb $ dpkg -i golang-doc_1.4.3-3_all.deb $ dpkg -i golang-go-linux-arm_1.4.3-3_armhf.deb $ dpkg -i golang_1.4.3-3_all.deb |
我们需要在 golang 1.4.3
环境中继续编译,可以在 golang 1.3.3
中运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$ cd ~/wdmc-build/64k-wheezy $ sudo chroot build $ mount -t proc none /proc $ mount -t devtmpfs none /dev $ mount -t devpts none /dev/pts $ export DEBIAN_FRONTEND=noninteractive $ export DEBCONF_NONINTERACTIVE_SEEN=true $ export LC_ALL=C $ export LANGUAGE=C $ export LANG=C $ export DEB_CFLAGS_APPEND='-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE' $ export DEB_BUILD_OPTIONS=nocheck $ cd root $ git clone https://github.com/git-lfs/git-lfs.git # 或者本站下载一份拷贝 wget https://www.mobibrw.com/wp-content/uploads/2019/11/git-lfs.zip $ git checkout v1.2.1 $ DEB_BUILD_OPTIONS="nocheck" dpkg-buildpackage -d -b -uc |
可以本站下载:
golang_1.3.3-1deb8u2.dsc
golang_1.3.3-1+deb8u2.debian.tar.xz
golang_1.3.3.orig.tar.gz
修改完BUG
之后编译好的 golang_1.3.3-1.deb(4KB分页)/golang_1.4.3-3.deb(4KB分页)用于编译环境使用,不能在WD MyCloud
上使用。
参考链接
- ARM chroot issues: fatal error: rt_sigaction failure
- Side by Side Diff: src/pkg/runtime/os_linux.c
- [release-branch.go1.5] runtime: ignore rt_sigaction error if it is fo…
- runtime: qemu-arm fails to emulate go user programs #13024
- failed to create new OS thread (have 2 already; errno=22) #22
- runtime: cannot run cross compiled ARM binary on QEMU #20763
- golang binaries fail to start under linux-user
- 软件包:golang-go(2:1.3.3-1+deb8u2) [security]
- Debian 软件包源码仓库(可在线浏览)
- How can I learn all the options I can pass to DEB_BUILD_OPTIONS?
- time: TestParseInLocation fail #19457