当前位置: 首页 > news >正文

cgo静态编译不能用glibc,用musl

Golang 的一个动态链接依赖问题

upx 是一个压缩二进制的工具,如上图,经过压缩之后,这些 binary 的体积都减少了 46%。

静态链接 CGO 的依赖
如果使用 glibc 的是,是不能静态链接的:

root@f88271a666f9:/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-go@v1.5.2/kafka/librdkafka/librdkafka_glibc_linux.a(rddl.o): in function `rd_dl_open':
(.text+0x1d): 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_ENABLED=0 GOOS=linux GOARCH=amd64 go build
或者加上可选参数

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 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_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS=“-static” go build -a -v
通过CC=x86_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
提示如下:

lizhongsu@lizhongdeMBP ~ % brew install FiloSottile/musl-cross/musl-cross
==> Downloading 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 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!
==> Installing musl-cross from filosottile/musl-cross
==> Downloading 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.3MB
==> `brew 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_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS=“-static” go build -a -v

成功交叉编译完成Go在linux下可运行文件。

相关文章:

cgo静态编译不能用glibc,用musl

Golang 的一个动态链接依赖问题 upx 是一个压缩二进制的工具,如上图,经过压缩之后,这些 binary 的体积都减少了 46%。 静态链接 CGO 的依赖 如果使用 glibc 的是,是不能静态链接的: rootf88271a666f9:/workspace# g…...

​力扣解法汇总1124. 表现良好的最长时间段

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。…...

12- 降维算法 (PCA降维/LDA分类/NMF) (数据处理)

数据降维就是一种对高维度特征数据预处理方法。降维是将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的。PCA算法有两种实现方法: 基于特征值分解协方差矩阵实现PCA算法基于SVD分解协方差矩阵实…...

QT+ OpenGL学习

文章目录QT OpenGLQOpenGLWidget:不需要GLFWQOpenGLFunction_X_X_Core:不需要GLAD你好,三角形顶点输入顶点着色器片段着色器链接着色器本节代码元素缓冲对象EBOQT交互GLSLGLSL支持的类型输入输出Uniform纹理纹理单元纹理环绕纹理过滤多级渐远纹理QT OpenGL 本篇完整…...

C语言(字符串输入)

目录 一.gets和puts组合 二.fgets()和fputs() 三.fgets()函数返回 四.fgets读取满问题 五.修改fgets函数,自动用\0替换\n 一.gets和puts组合 Gets()读取整行输入,知道遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符的…...

背包问题求方案数(AcWing)(JAVA)

有 N件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出 最优选法的方案数。注意答案可能很大,请输出答…...

一篇文章带你读懂HashMap

HashMap是面试中经常问到的一个知识点,也是判断一个候选人基础是否扎实的标准之一。可见HashMap的掌握是多重要。 一、HashMap源码分析 1、构造函数 让我们先从构造函数说起,HashMap有四个构造方法,别慌 1.1 HashMap() // 1.无参构造方法、// 构造一…...

Java如何进行优雅的判空——Optional类的灵活应用

0 引言 在Java Web项目开发中,经常令人头疼的NPE问题(NullPointerException)——空指针,例如我们在调用equal()方法时,就经常会出现NPE问题: String str null; str.equals("fsfs");…...

Fluent Python 笔记 第 12 章 继承的优缺点

重点是说明对 Python 而言尤为重要的两个细节: 子类化内置类型的缺点多重继承和方法解析顺序 12.1 子类化内置类型很麻烦 内置类型(使用 C 语言编写)不会调用用户定义的类覆盖的特殊方法。 不要子类化内置类型,用户自己定义的类应 该继承 collections 模块(http…...

Go语言读取解析yml文件,快速转换yml到go struct

YAML (YAML Aint a Markup Language)是一种标记语言,通常以.yml为后缀的文件,是一种直观的能够被计算机程序识别的数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入…...

第二十六章 java并发常见知识内容(ThreadLocal 详解)

JAVA重要知识点带着疑问看ThreadLocalGC 之后 key 是否为 null?ThreadLocalMap Hash 算法ThreadLocalMap Hash 冲突ThreadLocalMap.set()方法ThreadLocalMap过期 key 的探测式清理流程ThreadLocalMap扩容机制ThreadLocalMap.get()详解ThreadLocalMap过期 key 的启发…...

人类的第一语言是什么

其实机器智能始终存在一个争议 没有人类的肢体和感受器无法理解和感同身受 这不用想是自然,但是可以通过虚拟数据进行模拟,深度学习便是 深度学习是模拟简单输入输出的最好选择,但不是开放性的学习 没有智能交互的智能永远不是智能 就像狼孩一…...

jsp(全部知识点)

👌 棒棒有言:也许我一直照着别人的方向飞,可是这次,我想要用我的方式飞翔一次!人生,既要淡,又要有味。凡事不必太在意,一切随缘,缘深多聚聚,缘浅随它去。凡事…...

测试开发面试基础题

1.对测试开发的理解 测试开发首先离不开测试,而软件测试是指,在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。 而且,现在不仅仅是通过手工测试来发…...

C++——多态|虚函数|重写|虚表

文章目录1. 多态的概念1.1 概念2. 多态的定义及实现2.1多态的构成条件2.2 虚函数2.3虚函数的重写虚函数重写的三个例外:2.4 普通调用和多态调用:2.5 C11 override 和 final2.6 重载、虚函数的覆盖(重写)、隐藏(重定义)的对比3. 抽象类(有关纯虚函数)3.1 …...

IPV4地址详解

文章目录IPV4地址分类编址划分子网无分类编制CIDR路由聚合应用规划(子网划分的细节)定长的子网掩码FLSM变长的子网掩码VLSMIPV4地址 IPV4地址就是给因特网(Internet)上的每一台主机(或路由器)的每一个接口…...

(一)初识Streamlit(附安装)

本入门指南介绍Streamlit的工作原理、如何在您首选的操作系统上安装Streamlit,以及如何创建第一个Streamlit应用程序! 1 安装 1.1 先决条件 Python 3.7 – Python 3.11 **注:我这里使用的是anaconda的虚拟环境,用pycharm编写代…...

【新】华为OD机试 - 斗地主 2(Python)| 刷完获取OD招聘渠道

斗地主 2 题目描述 在斗地主扑克牌游戏中,扑克牌由小到大的顺序为3 4 5 6 7 8 9 10 J Q K A 2 玩家可以出的扑克牌阵型有,单张,对子,顺子,飞机,炸弹等 其中顺子的出牌规则为,由至少 5 张由小到大连续递增的扑克牌组成 且不能包含2 例如:{3,4,5,6,7}、{3,4,5,6,7,8,9,1…...

秒杀项目之消息推送

目录一、创建消费者二、创建订单链路配置2.1 定义RabbitMQ配置类2.2 创建RabbitmqOrderConfig配置类三、如何实现RabbitMQ重复投递机制3.1 开启发送者消息确认模式3.2 消费发送确认3.2.1 创建ConfirmCallBack确认模式3.2.2 创建ReturnCallBack退回模式3.3 创建生产者3.4 创建消…...

【重磅】IEEE33配电网两阶段鲁棒优化调度CCG

目录 1 前言 2基本内容 2.1 配网两阶段鲁棒模型 2.2 求解步骤 3部分程序 4程序结果 5程序链接 1 前言 鲁棒优化是电力系统研究的热点,而两阶段鲁棒和分布鲁棒研究就成为各类期刊(sci/ei/核心)的宠儿,最简单的思路是通过改…...

GPT2代码拆解+生成实例

本文代码来自博客,GPT2模型解析参考 import torch import copy import torch.nn as nn import torch.nn.functional as F from torch.nn.modules import ModuleList from torch.nn.modules.normalization import LayerNorm import numpy as np import os from tqd…...

基于android的即时通讯APP 聊天APP

基于android的即时通讯APP 或者 聊天APP 一 项目概述 该项目是基于Android 的聊天APP系统,该APP包含前台,后台管理系统,前台包含用户通讯录,用户详情,用户聊天服务,用户二维码,发现功能,发现详情 , 个人中心, 个人信…...

【C++】二叉树之力扣经典题目1——详解二叉树的递归遍历,二叉树的层次遍历

如有错误,欢迎指正。 如有不理解的地方,可以私信问我。 文章目录题目1:根据二叉树创建字符串题目实例思路与解析代码实现题目2:二叉树的层序遍历题目思路与解析代码实现题目1:根据二叉树创建字符串 点击进入题目链接—…...

MySQL数据库调优————SQL性能分析

TIPS 本文基于MySQL 8.0 本文探讨如何深入SQL内部,去分析其性能,包括了三种方式: SHOW PROFILEINFORMATION_SCHEMA.PROFILINGPERFORMANCE_SCHEMA SHOW PROFILE SHOW PROFILE是MySQL的一个性能分析命令,可以跟踪SQL各种资源消耗。…...

sql数据库高级编程总结(一)

1、数学函数:操作一个数据,返回一个结果 (1)取上限 ceiling 如果有一个小数就取大于它的一个最小整数 列如9.5 就会取到 10 select code,name,ceiling(price) from car (2)取下限 floor 如果有一个小数就…...

软件工程(5)--喷泉模型

前言 这是基于我所学习的软件工程课程总结的第五篇文章。 迭代是软件开发过程中普遍存在的一种内在属性。经验表明,软件过程各个阶段之间的迭代或一个阶段内各个工作步骤之间的迭代,在面向对象范型中比在结构化范型中更常见。 一般说来,使用…...

SM2数字签名

文章目录6. 签名流程7. 验签流程实现参考资料6. 签名流程 M’ ZA || Msge Hash(M’)&#xff0c;并转为大数&#xff1b;生成随机数k&#xff0c;范围0<k<n&#xff1b;计算kG (x1, y1)r (e x1) mod n, 若r0或(rkn)则重新生成k&#xff1b;s (k-rd) / (1d) mod n&…...

RPA+保险后台部门擦出不一样“火花” | RPA案例

在保险行业中&#xff0c;后台业务线主要是为前台和中台等提供支持&#xff0c;提供公司整体运营服务&#xff0c;包括财务、信息、人力、综合办等。相对于中前台部门&#xff0c;后台部门离核心价值链更远一些&#xff0c;更偏支持部门&#xff0c;其中某些岗位与业务相关度强…...

设备树相关概念的理解

设备树 定义 设备树是描述硬件信息的一种树形结构&#xff0c;设备树文件会在内核启动后被内核解析得到对应设备的具体信息。 树形结构就自然会存在节点&#xff0c;硬件设备信息就存储再设备树中的节点上&#xff0c;即设备节点。而一个设备节点中可以存储硬件的多个不同属性…...

ubuntu20.04下配置深度学习环境GPU

卸载子系统 C:\Users\thzn>wsl --list 适用于 Linux 的 Windows 子系统分发版: docker-desktop (默认) docker-desktop-data Ubuntu-18.04 Ubuntu-22.04 Ubuntu-20.04 C:\Users\thzn>wsl --unregister Ubuntu-18.04 ubuntu 换源 https://www.cnblogs.com/Horizon-asd/p…...

南阳网站建设制作价格/广东省最新疫情

C语言枚举和共用体 文章目录C语言枚举和共用体C enum(枚举)枚举变量的定义将整数转换为枚举C 共用体定义共用体访问共用体成员C enum(枚举) 枚举是 C 语言中的一种基本数据类型&#xff0c;它可以让数据更简洁&#xff0c;更易读。 枚举语法定义格式为&#xff1a; enum 枚…...

网站集约化建设汇报/手机百度搜索

文章目录前言一、大驼峰法&#xff08;帕斯卡命名法&#xff09;二、小驼峰法三、其他前言 驼峰命名法&#xff0c;是指混合使用大小写字母构成变量和函数名字。在Java开发中&#xff0c;建议使用驼峰命名法&#xff0c;增强代码的识别性和可读性。 一、大驼峰法&#xff08;帕…...

太原免费网站建设/seo关键词推广话术

好久没写东西了&#xff0c;去年用了angular2的RC版本和ionic2写了一个项目&#xff0c;因为开发周期和有些版本不稳定&#xff0c;所以一直没有升级&#xff0c;ng2新版本引用Aot打包&#xff0c;听说优化还不错&#xff0c;现在尝试升级ionic2、angular2到最新版本&#xff0…...

中国最大的库存尾货清货平台/seo关键词排名优化品牌

近来公司redmine服务器表现很糟糕&#xff0c;在16核&#xff0c;64GRAM的机器上&#xff0c;压测结果竟然只有每秒5~7个请求&#xff0c;部分页面一个都出不来。 以下是我对Redmine性能优化方案: redmine服务器性能问题排查与优化建议&#xff1a; 以下建议的方案是基于redmi…...

网站做营销推广的公司/西安seo排名收费

PHP 怎么去掉一张图片里的一些颜色&#xff0c;让其变成透明&#xff1f;把一张图片(根据指定的RGB颜色范围)透明化。但是实际处理当中&#xff0c;下面的代码值移除了白色&#xff0c;请教是怎么回事&#xff1f;$o_pic 1.jpg;//要处理的色阶起始值$begin_r 215;$begin_g 2…...

做网站价位/电脑全自动挂机赚钱

几种并发服务器模型的实现&#xff1a;多线程&#xff0c;多进程&#xff0c;select&#xff0c;poll&#xff0c;epoll - rail 时间 2014-07-31 00:18:00 博客园-所有随笔区原文 http://www.cnblogs.com/wj9012/p/3879605.html主题 Socket 多线程 Epoll#include <stdio.h&…...