使用Golang创建共享同一库的Debian软件包
使用Golang创建共享同一库的Debian软件包 我正在尝试创建一个包含3个共享相同Go库的可执行文件的Debian包。我的目录包含以下文件:
- rtd_dsp.go 一个在命令行显示流式测量的可执行文件
- rtd_web.go 一个通过Web服务器显示最近一次测量的可执行文件
- rtd_influxdb.go 一个将流式测量存储到数据库的可执行文件
- dmn.go 包含用于多个测量流的监听器的库代码
可以按如下方式轻松创建可执行文件:
- go build rtd_dsp.go dmn.go
- go build rtd_web.go dmn.go
- go build rtd_influxdb.go dmn.go
我找到了用于创建Debian包的debian包 dh-golang,并尝试使其正常工作。然而,这似乎不像宣传的那么简单。在创建了包含所需changelog、control、copyright和rules、source/target文件的debian文件夹,并在Ubuntu 20.04.2(使用golang-1.16)上使用dh-golang 1.48运行 dpkg-buildpackage -us -uc -d 之后,它抱怨了几件事:
- 它找不到外部包,而这些包在 $(GOMODCACHE)=$(HOME)/go/pkg/mod 中是可用的。在我看来,它要么可以自己获取它们,要么重用现有的包。作为实验,我修改了golang.pm,将GOPATH设置为$(GOMODCACHE)。
- 它找不到任何Go文件,而这些文件就在创建的 _build/src/sst-goflow 目录中。
- 我预计会出现一个错误,指出每个可执行的go文件都实现了相同的handleMessage调用(正如简单的
go install所指示的那样),而我却希望它能创建单独的可执行文件。
是否有更简单的方法来创建包含Go可执行文件的Debian包?并且/或者上述问题是否容易解决?
此致, Dennis
更多关于使用Golang创建共享同一库的Debian软件包的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我成功找到了一个更简单的解决方案,使用 debian/install 文件和一个带有构建目标的常规 GNU Makefile 来创建可执行文件。install 文件用于将可执行文件复制到 debian 包中的 usr/bin。所以,除非有人能说服我改变主意,否则我不再使用 dh-golang 了;-)
祝好, Dennis
这可能是因为 Go 源码文件名中的下划线具有特殊含义:下划线后的单词必须是构建标签名称。例如,名为
myfile_windows.go的文件仅在 GOOS=windows 时才会被构建。myfile_linux_386.go仅在 GOOS=linux 且 GOARCH=386 时才会被构建,依此类推。或许可以尝试从 Go 源码文件名中移除下划线,看看行为是否发生变化。
我完全不了解 gh-golang,因此无法对其发表任何评论,但如果常规的 Debian 构建安装包的方式可行,那么我就不会再寻找其他方法了。
Go 二进制文件的静态特性(即没有共享库依赖)使得打包和部署 Go 二进制文件变得特别容易,无需专门的工具。
话虽如此,总有一些便利的选项可用,例如 goreleaser。(特别是配合 NFPM 选项。)
针对你使用dh-golang创建包含多个共享库的可执行文件的Debian包时遇到的问题,以下是具体的解决方案和示例代码:
首先,确保你的项目结构符合Go模块规范。在项目根目录初始化模块:
go mod init github.com/yourname/rtd
创建标准的Debian包结构,debian/control文件示例:
Source: rtd
Section: utils
Priority: optional
Maintainer: Dennis <dennis@example.com>
Build-Depends: debhelper-compat (= 13), dh-golang, golang-1.16
Standards-Version: 4.5.1
Homepage: https://github.com/yourname/rtd
Package: rtd-dsp
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Display streaming measurements
Command-line tool for displaying streaming measurements.
Package: rtd-web
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Web interface for measurements
Web server displaying recent measurements.
Package: rtd-influxdb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Store measurements to InfluxDB
Stores streaming measurements to InfluxDB database.
debian/rules文件配置:
#!/usr/bin/make -f
%:
dh $@ --with=golang
override_dh_auto_build:
# 构建所有可执行文件
GOBIN=$(CURDIR)/debian/rtd-dsp/usr/bin go install ./cmd/rtd_dsp
GOBIN=$(CURDIR)/debian/rtd-web/usr/bin go install ./cmd/rtd_web
GOBIN=$(CURDIR)/debian/rtd-influxdb/usr/bin go install ./cmd/rtd_influxdb
override_dh_auto_install:
# 安装可执行文件到对应包目录
install -d debian/rtd-dsp/usr/bin
install -d debian/rtd-web/usr/bin
install -d debian/rtd-influxdb/usr/bin
install -m 0755 $(CURDIR)/debian/rtd-dsp/usr/bin/rtd_dsp debian/rtd-dsp/usr/bin/
install -m 0755 $(CURDIR)/debian/rtd-web/usr/bin/rtd_web debian/rtd-web/usr/bin/
install -m 0755 $(CURDIR)/debian/rtd-influxdb/usr/bin/rtd_influxdb debian/rtd-influxdb/usr/bin/
调整项目目录结构,将可执行文件移到cmd目录:
project/
├── cmd/
│ ├── rtd_dsp/
│ │ └── main.go
│ ├── rtd_web/
│ │ └── main.go
│ └── rtd_influxdb/
│ └── main.go
├── internal/
│ └── dmn/
│ └── dmn.go
├── go.mod
└── go.sum
每个main.go文件导入共享库:
package main
import (
"github.com/yourname/rtd/internal/dmn"
)
func main() {
dmn.HandleMessage()
}
共享库dmn.go示例:
package dmn
import "fmt"
func HandleMessage() {
fmt.Println("Handling measurement")
}
构建命令:
# 设置Go模块代理
export GOPROXY=https://proxy.golang.org,direct
# 清理并构建
dpkg-buildpackage -us -uc -d -i -I
对于外部依赖问题,在debian/rules中添加:
override_dh_auto_configure:
# 确保使用系统Go模块缓存
export GOMODCACHE=/usr/share/gocode/pkg/mod; \
export GOPROXY=https://proxy.golang.org,direct; \
dh_auto_configure
如果遇到符号冲突,在debian/rules中添加:
override_dh_strip:
# 为每个包单独构建以避免符号冲突
dh_strip --dbg-package=rtd-dsp-dbg
dh_strip --dbg-package=rtd-web-dbg
dh_strip --dbg-package=rtd-influxdb-dbg
使用gbp buildpackage替代dpkg-buildpackage:
gbp buildpackage --git-ignore-new --git-ignore-branch -us -uc
创建debian/source/format文件:
3.0 (quilt)
运行完整构建流程:
# 更新依赖
go mod tidy
go mod vendor
# 构建包
dpkg-buildpackage -rfakeroot -us -uc -d -i -I
这样配置后,dh-golang会正确识别Go模块结构,分别构建三个可执行文件,并打包到对应的Debian包中。共享的dmn库会被自动编译并链接到每个可执行文件中。


