重庆商城网站建设地址,购物网站的商品展示模块,做php网站用mvc多吗,资讯门户网站Golang 的一个动态链接依赖问题
upx 是一个压缩二进制的工具#xff0c;如上图#xff0c;经过压缩之后#xff0c;这些 binary 的体积都减少了 46%。
静态链接 CGO 的依赖 如果使用 glibc 的是#xff0c;是不能静态链接的#xff1a;
rootf88271a666f9:/workspace# g…Golang 的一个动态链接依赖问题
upx 是一个压缩二进制的工具如上图经过压缩之后这些 binary 的体积都减少了 46%。
静态链接 CGO 的依赖 如果使用 glibc 的是是不能静态链接的
rootf88271a666f9:/workspace# go build -ldflags -linkmode external -extldflags -static ./cmd/spex
# git.garena.com/shopee/platform/spex/cmd/spex
/usr/bin/ld: /go/pkg/mod/github.com/confluentinc/confluent-kafka-gov1.5.2/kafka/librdkafka/librdkafka_glibc_linux.a(rddl.o): in function rd_dl_open:
(.text0x1d): warning: Using dlopen in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-883441031/000004.o: in function _cgo_26061493d47f_C2func_getaddrinfo:
/tmp/go-build/cgo-gcc-prolog:58: warning: Using getaddrinfo in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
因为 glibc 依赖了 libnss libnss 支持不同的 provider必须被 dynamic link.所以这里只有使用 musl 替换 glibc 了。librdkafka 和 golang 的封装 confluent-kafka-go 都支持 musl 构建。只要在构建的时候指定 --tags musl 即可。alpine 是基于 musl 的发行版这里直接使用 alpine Linux 进行构建。然后指定使用外部 ld指定 flags 使用 -static编译出来的 binary 就完全是静态链接的了。编译过程如下$ docker run -it -v $(pwd):/workspace -v /Users/xintao.lai/.netrc:/root/.netrc golang:alpine3.14
/go $ cd /workspace/
/workspace $ apk add git alpine-sdk
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/37) Installing fakeroot (1.25.3-r3)
(2/37) Installing openssl (1.1.1l-r0)
(3/37) Installing libattr (2.5.1-r0)
(4/37) Installing attr (2.5.1-r0)
(5/37) Installing libacl (2.2.53-r0)
(6/37) Installing tar (1.34-r0)
(7/37) Installing pkgconf (1.7.4-r0)
...
/workspace $ go build -ldflags -linkmode external -extldflags -static -tags musl ./cmd/spex
/workspace $ ldd spex
/lib/ld-musl-x86_64.so.1: spex: Not a valid dynamic program
$ docker run -it -v $(pwd):/workspace -v /Users/xintao.lai/.netrc:/root/.netrc golang:alpine3.14
/go $ cd /workspace/
/workspace $ apk add git alpine-sdk
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/37) Installing fakeroot (1.25.3-r3)
(2/37) Installing openssl (1.1.1l-r0)
(3/37) Installing libattr (2.5.1-r0)
(4/37) Installing attr (2.5.1-r0)
(5/37) Installing libacl (2.2.53-r0)
(6/37) Installing tar (1.34-r0)
(7/37) Installing pkgconf (1.7.4-r0)
...
/workspace $ go build -ldflags -linkmode external -extldflags -static -tags musl ./cmd/spex
/workspace $ ldd spex
/lib/ld-musl-x86_64.so.1: spex: Not a valid dynamic program静态编译 CGO 的依赖可以参考这篇教程Using CGO bindings under Alpine, CentOS and Ubuntu 和这个例子go-static-linking.
shadowmint/go-static-linking
https://github.com/shadowmint/go-static-linking
Go语言涉及CGO的交叉编译(跨平台编译)解决办法
在实际开发中我们往往要使用交叉编译[1]来实现跨平台部署这两天查阅资料发现之所以TensorFlow跨平台编译失败是因为使用了cgo来调用TensorFlow C。今天我们就来深入了解下怎么处理带CGO的交叉编译。
在没有CGO调用的情况下交叉编译只需带上三个参数便可以实现
CGO_ENABLED0 GOOSlinux GOARCHamd64 go build 或者加上可选参数
CGO_ENABLED0 GOOSlinux GOARCHamd64 go build -ldflags ‘-s -w --extldflags “-static -fpic”’ main.go CGO_ENABLED 这个参数默认为1开启CGO。需要指定为0来关闭因为CGO不支持交叉编译。
GOOS 和 GOARCH 用来指定要构建的平台为Linux
可选参数-ldflags 是编译选项
-s -w 去掉调试信息可以减小构建后文件体积 –extldflags “-static -fpic” 完全静态编译[2]这样编译生成的文件就可以任意放到指定平台下运行而不需要运行环境配置。 显然对于带CGO的交叉编译CGO_ENABLED必须开启。这也就需要辅助编译器来帮我们实现交叉编译了。
如果你是mac平台可以用这个工具 FiloSottile/musl-cross/musl-cross 直接通过brew安装就可以使用
brew install FiloSottile/musl-cross/musl-cross 安装成功后有多种编译器可以帮我们实现交叉编译使用时只需在编译对应参数下指定就可以了。
FiloSottile/musl-cross/musl-cross CGO_ENABLED1 GOOSlinux GOARCHamd64 CCx86_64-linux-musl-gcc CGO_LDFLAGS“-static” go build -a -v 通过CCx86_64-linux-musl-gcc 来指定GCC编译器。而CGO_LDFLAGS-static来指定CGO部分的编译为静态编译。
这样就可以实现带CGO的交叉编译啦。如果你是其他平台也可以通过跨平台编译的工具musl 下载对应平台工具这里有支持多平台实现工具。下载解压将解压好的目录下 bin 文件路径放到PATH环境变量中就可以啦。
brew install FiloSottile/musl-cross/musl-cross 安装过程中出现如下问题 Error: An exception occurred within a child process: NoMethodError: undefined method path’ for nil:NilClass Did you mean? paths 解决方案 使用命令brew update-reset升级Homebrew即可[1]
References [1] https://discourse.brew.sh/t/homebrew-installation-fail/7439
再次安装brew install FiloSottile/musl-cross/musl-cross 提示如下
lizhongsulizhongdeMBP ~ % brew install FiloSottile/musl-cross/musl-crossDownloading https://ghcr.io/v2/homebrew/portable-ruby/portable-ruby/blobs/sha256:b065e5e3783954f3e65d8d3a6377ca51649bfcfa21b356b0dd70490f74c6bd86
##################################################################################################################################################################################################### 100.0%Pouring portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
Error:homebrew-core is a shallow clone.
To brew update, first run:git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
This command may take a few minutes to run due to the large size of the repository.
This restriction has been made on GitHubs request because updating shallow
clones is an extremely expensive operation due to the tree layout and traffic of
Homebrew/homebrew-core and Homebrew/homebrew-cask. We dont do this for you
automatically to avoid repeatedly performing an expensive unshallow operation in
CI systems (which should instead be fixed to not use shallow clones). Sorry for
the inconvenience!Installing musl-cross from filosottile/musl-crossDownloading https://f001.backblazeb2.com/file/filippo-public/musl-cross-0.9.9_1.catalina.bottle.tar.gz
######################################################################## 100.0%Pouring musl-cross-0.9.9_1.catalina.bottle.tar.gz/usr/local/Cellar/musl-cross/0.9.9_1: 1,851 files, 246.3MBbrew cleanup has not been run in 30 days, running now...
Removing: /Users/lizhongsu/Library/Caches/Homebrew/autoconf--2.69.catalina.bottle.4.tar.gz... (871.6KB)
Removing: /Users/lizhongsu/Library/Caches/Homebrew/automake--1.16.2.catalina.bottle.tar.gz... (948.7KB)
Removing: /Users/lizhongsu/Library/Logs/Homebrew/autoconf... (64B)
Removing: /Users/lizhongsu/Library/Logs/Homebrew/automake... (64B)
Removing: /Users/lizhongsu/Library/Logs/Homebrew/telnet... (64B)
Pruned 2 symbolic links from /usr/local有一个错误提示 Error: homebrew-core is a shallow clone. To brew update, first run: git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow This command may take a few minutes to run due to the large size of the repository. This restriction has been made on GitHub’s request because updating shallow clones is an extremely expensive operation due to the tree layout and traffic of Homebrew/homebrew-core and Homebrew/homebrew-cask. We don’t do this for you automatically to avoid repeatedly performing an expensive unshallow operation in CI systems (which should instead be fixed to not use shallow clones). Sorry for the inconvenience!
暂时没有进行根据提示进行处理尝试编译成功 执行命令 CGO_ENABLED1 GOOSlinux GOARCHamd64 CCx86_64-linux-musl-gcc CGO_LDFLAGS“-static” go build -a -v
成功交叉编译完成Go在linux下可运行文件。