1、現(xiàn)象
在go中需要對(duì)外發(fā)布包給用戶(hù)使用,但是由于不能提供開(kāi)源包,所以采用二進(jìn)制包形式(由于某些原因只能采用這中方式)。按照之前go打包的方式首先采用
go build -tags "${BUILD_TAGS}" -i -o $pkgDirectory/$frameworkDir.a
方式打包二進(jìn)制包生成.a 文件;
接著使用腳本生成發(fā)布的go文件
文件格式如下
//go:binary-only-package
package mypack.a
//聲明
func a(){
.....
}
在我們之前的項(xiàng)目中這種方式時(shí)好使的,因?yàn)槲覀冎笆褂玫臅r(shí)go 1.8;但是現(xiàn)在這種方式使用時(shí)會(huì)出現(xiàn)如下的錯(cuò)誤
cannot find package encoding/json (using -importcfg)
cannot find package XXXXXXXXX (using -importcfg)
/usr/local/go/pkg/tool/linux_amd64/link: cannot open file : open : no such file or directory
這個(gè)時(shí)候我們使用
go build -x
查看編譯詳細(xì)過(guò)程,我們能看到打印如下:
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile skillexec=/root/.cache/go-build/5c/5cb87f7186cce13a26403f25b0b58be401996de3b7a30fd5cec976aeb63aa4d5-d
packagefile syscall=/usr/local/go/pkg/linux_arm64/syscall.a
packagefile runtime=/usr/local/go/pkg/linux_arm64/runtime.a
packagefile errors=/usr/local/go/pkg/linux_arm64/errors.a
.........
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=wXO8Fkarg-ul4F28mNmn/O6_brzWOYjAuNbD_PT4v/qxVrSxbhe8F50Mnc5h4p/wXO8Fkarg-ul4F28mNmn -extld=/usr/gcc-aarch64/bin/aarch64-linux-gnu-gcc /root/.cache/go-build/5c/5cb87f7186cce13a26403f25b0b58be401996de3b7a30fd5cec976aeb63aa4d5-d
# skillexec
cannot find package encoding/json (using -importcfg)
cannot find package XXXXXXXXX (using -importcfg)
/usr/local/go/pkg/tool/linux_amd64/link: cannot open file : open : no such file or directory
到這里,我們能夠很明顯的看到后面報(bào)錯(cuò)未找到的包其實(shí)沒(méi)有被go寫(xiě)進(jìn)importcfg.link這個(gè)文件;這一點(diǎn)很關(guān)鍵,在看看自己包引用的關(guān)系,你會(huì)發(fā)現(xiàn)寫(xiě)進(jìn)了importcfg.link的包實(shí)際上只有你在源代碼中使用了的,而.a包中使用的是沒(méi)有被解析出來(lái)的。但是這些包都在pkg文件中。
2、解決辦法
其實(shí)要解決這個(gè)問(wèn)題,就是在go文件中寫(xiě)入包含的包就可以了。所以咱們需要在發(fā)布二進(jìn)制包的時(shí)候?qū)懭脒@個(gè)包引用。
也就是發(fā)布文件中文件格式如下
//go:binary-only-package
package mypack.a
import (
"encoding/json"
"XXXXXXXXX"
)
//聲明
func a(){
}
3、總結(jié)
使用二進(jìn)制包時(shí),我們需要在發(fā)布go文件中加上包依賴(lài)也寫(xiě)進(jìn)該文件中。
//go:binary-only-package
package mypack.a
import (
"encoding/json"
"XXXXXXXXX"
)
再提一句,其實(shí)發(fā)布的go文件中只有上面這段是有用的。
而下面這段代碼是假的,相當(dāng)于頭文件中的聲明。而且不會(huì)被編譯進(jìn)去。
//聲明
func a(){
}
注:第一次寫(xiě),有問(wèn)題請(qǐng)指正。