为Debian打包Go应用程序

huangapple go评论81阅读模式
英文:

Packaging Go application for Debian

问题

我如何将我的Go二进制文件放入Debian软件包中?由于Go是静态链接的,我只有一个可执行文件 - 我不需要很多复杂的项目元数据信息。有没有一种简单的方法来打包可执行文件和资源文件,而不需要经历“debuild”的痛苦?

我已经在各个地方寻找现有的问题;然而,我所有的研究结果都是关于包含golang开发环境的.deb文件(即,如果你执行sudo apt-get install golang-go会得到什么)。

英文:

How can I put my Go binary into a Debian package? Since Go is statically linked, I just have a single executable--I don't need a lot of complicated project metadata information. Is there a simple way to package the executable and resource files without going through the trauma of debuild?

I've looked all over for existing questions; however, all of my research turns up questions/answers about a .deb file containing the golang development environment (i.e., what you would get if you do sudo apt-get install golang-go).

答案1

得分: 26

好的。我认为debuild唯一的“创伤”就是在构建软件包之后运行lintian,而lintian试图发现软件包中的问题。

因此,有两种方法可以解决这个问题:

  • 不使用debuild:这个工具只是调用dpkg-buildpackage,它真正执行必要的构建操作。构建二进制软件包的常规调用是dpkg-buildpackage -us -uc -b。你仍然可以为其他目的调用debuild,比如debuild clean
  • 添加所谓的“lintian覆盖”(lintian override),可以让lintian对你坚称不是问题的选定问题视而不见。

这两种方法都意味着你不要尝试使用打包工具来构建你的应用程序,而是将其视为一个封装的软件包。这将要求你稍微放弃debian/rules正常工作的方式(不要尝试构建任何东西)。

另一个可能的解决方案(而且更符合Debian的方式)是尝试使用gcc-go(加上gold进行链接):因为它是GCC的前端,这个工具会生成一个动态链接的应用程序(链接到libgo或类似的库)。我个人对此还没有经验,只有在你打算尝试将软件包推送到Debian官方时才会考虑使用它。

关于将Go程序打包为Debian的一般问题,你可能会发现以下资源有用:

  • 这个线程是由Go for Debian打包者之一在go-nuts上发起的。
  • 特别是,该线程中的第一篇帖子链接到了这个讨论,该讨论发生在debian-devel上。
  • 这个线程是debian-devel上关于同样问题的第二个线程(它是前一个线程的逻辑延续)。

更新于2015-10-15。

(由于这篇帖子似乎仍然被人们搜索、找到并研究,我决定更新它以更好地反映当前的情况。)

自那时以来,打包Go应用程序和软件包的情况得到了显着改善,现在可以使用“经典”Go(即源自Google的gc套件)而不是gcc-go来构建Debian软件包。
而且还存在一个很好的软件包基础设施。

现在在将Go程序打包为Debian软件包时要使用的关键工具是dh-golang,在这里有描述。

英文:

Well. I think the only "trauma" of debuild is that it runs lintian after building the package, and it's lintian who tries to spot problems with your package.

So there are two ways to combat the situation:

  • Do not use debuild: this tool merely calls dpkg-buildpackage which really does the necessary powerlifting. The usual call to build a binary package is dpkg-buildpackage -us -uc -b. You still might call debuild for other purposes, like debuild clean for instance.
  • Add the so-called "lintian override" which can be used to make lintian turn a blind eye to selected problems with your package which, you insist, are not problems.

Both approaches imply that you do not attempt to build your application by the packaging tools but rather treat it as a blob which is just wrapped to a package. This would require slightly abstraining from the normal way debian/rules work (to not attempt to build anything).

Another solution which might be possible (and is really way more Debian-ish) is to try to use gcc-go (plus gold for linking): since it's a GCC front-end, this tool produces a dynamically-linked application (which links against libgo or something like this). I, personally, have no experience with it yet, and would only consider using it if you intend to try to push your package into the Debian proper.

Regarding the general question of packaging Go programs for Debian, you might find the following resources useful:

  • This thread started on go-nuts by one of Go for Debian packagers.
  • In particular, the first post in that thread links to this discussion on debian-devel.
  • The second thread on debian-devel regarding that same problem (it's a logical continuation of the former thread).

Update on 2015-10-15.

(Since this post appears to still be searched and found and studied by people I've decided to update it to better reflec the current state of affairs.)

Since then the situation with packaging Go apps and packages got improved dramatically, and it's possible to build a Debian package using "classic" Go (the so-called gc suite originating from Google) rather than gcc-go.
And there exist a good infrastructure for packages as well.

The key tool to use when debianizing a Go program now is dh-golang described here.

答案2

得分: 16

我刚刚自己研究了一下,基本上已经弄清楚了。

概要

通过从Canonical现有的Go项目的“package”分支中“借用”,您可以使用dpkg-buildpackage构建您的软件包。

  1. 安装依赖项并从另一个存储库中获取“package”分支。

      # 我认为这个软件包列表足够了。可能还需要dpkg-dev。
      sudo apt-get install bzr debhelper build-essential golang-go
      bzr branch lp:~niemeyer/cobzr/package mypackage-build
      cd mypackage-build
    
  2. 编辑元数据。

  • 编辑debian/control文件(名称,版本,源)。您可能需要将golang-stable依赖项更改为golang-go。
  • debian/control文件是清单。请注意“构建依赖项”(Build-Depends: debhelper (>= 7.0.50~), golang-stable)和3个架构。在使用Ubuntu(没有gophers ppa)时,我必须将golang-stable更改为golang-go。
  • 编辑debian/rules文件(将您的软件包名称放在cobzr的位置)。
  • debian/rules文件基本上是一个“make”文件,它显示了如何构建软件包。在这种情况下,他们在很大程度上依赖于debhelper。在这里,他们设置了GOPATH,并调用“go install”。
    这是神奇的“go install”行:

cd $(GOPATH)/src && find * -name '*.go' -exec dirname {} \; | xargs -n1 go install

  • 还要更新版权文件,自述文件,许可证等。
  1. 将您的源代码放在src文件夹中。例如:

      git clone https://github.com/yourgithubusername/yourpackagename src/github.com/yourgithubusername/yourpackagename
    

或者例如2:

     cp .../yourpackage/ src/
  1. 构建软件包

      # -us -uc跳过软件包签名。
      dpkg-buildpackage -us -uc
    

这应该会生成一个针对您的架构的二进制.deb文件,以及“源deb”(.tgz)和源deb描述文件(.dsc)。

更多细节

所以,我意识到Canonical(Ubuntu的人们)正在使用Go,并为他们的一些Go项目构建.deb软件包。Ubuntu基于Debian,因此在很大程度上,相同的方法应该适用于这两个发行版(依赖项名称可能会稍有不同)。

您将在Ubuntu的Launchpad存储库中找到一些基于Go的软件包。到目前为止,我找到了cobzr(用于bzr的git风格分支)和juju-core(一个从Python移植的devops项目)。

这两个项目都有一个“trunk”和一个“package”分支,您可以在包分支中看到debian/文件夹。这里最重要的两个文件是debian/controldebian/rules - 我已经链接到了“浏览源代码”。

最后

我没有涵盖的一件事是交叉编译您的软件包(到另外两个架构中的一个,386/arm/amd64)。在Go中进行交叉编译并不太复杂(您需要为每个目标平台构建工具链,然后在“go build”期间设置一些环境变量),我自己一直在开发一个交叉编译工具。最终,我希望能够将.deb支持添加到我的工具中,但首先我需要明确这个任务。

祝你好运。如果您取得任何进展,请更新我的答案或添加评论。谢谢

英文:

I've just been looking into this myself, and I'm basically there.

Synopsis

By 'borrowing' from the 'package' branch from one of Canonical's existing Go projects, you can build your package with dpkg-buildpackage.

  1. install dependencies and grab a 'package' branch from another repo.

      # I think this list of packages is enough. May need dpkg-dev aswell.
      sudo apt-get install bzr debhelper build-essential golang-go
      bzr branch lp:~niemeyer/cobzr/package mypackage-build
      cd mypackage-build
    
  2. Edit the metadata.

  • edit debian/control file (name, version, source). You may need to change the golang-stable dependency to golang-go.
  • The debian/control file is the manifest. Note the 'build dependencies' (Build-Depends: debhelper (>= 7.0.50~), golang-stable) and the 3 architectures. Using Ubuntu (without the gophers ppa), I had to change golang-stable to golang-go.
  • edit debian/rules file (put your package name in place of cobzr).
  • The debian/rules file is basically a 'make' file, and it shows how the package is built. In this case they are relying heavily on debhelper. Here they set up GOPATH, and invoke 'go install'.
    Here's the magic 'go install' line:

cd $(GOPATH)/src && find * -name '*.go' -exec dirname {} \; | xargs -n1 go install

  • Also update the copyright file, readme, licence, etc.
  1. Put your source inside the src folder. e.g.

      git clone https://github.com/yourgithubusername/yourpackagename src/github.com/yourgithubusername/yourpackagename
    

or e.g.2

     cp .../yourpackage/ src/
  1. build the package

      # -us -uc skips package signing.
      dpkg-buildpackage -us -uc
    

This should produce a binary .deb file for your architecture, plus the 'source deb' (.tgz) and the source deb description file (.dsc).

More details

So, I realised that Canonical (the Ubuntu people) are using Go, and building .deb packages for some of their Go projects. Ubuntu is based on Debian, so for the most part the same approach should apply to both distributions (dependency names may vary slightly).

You'll find a few Go-based packages in Ubuntu's Launchpad repositories. So far I've found cobzr (git-style branching for bzr) and juju-core (a devops project, being ported from Python).

Both of these projects have both a 'trunk' and a 'package' branch, and you can see the debian/ folder inside the package branch. The 2 most important files here are debian/control and debian/rules - I have linked to 'browse source'.

Finally

Something I haven't covered is cross-compiling your package (to the other 2 architectures of the 3, 386/arm/amd64). Cross-compiling isn't too tricky in go (you need to build the toolchain for each target platform, and then set some ENV vars during 'go build'), and I've been working on a cross-compiler utility myself. Eventually I'll hopefully add .deb support into my utility, but first I need to crystallize this task.

Good luck. If you make any progress then please update my answer or add a comment. Thanks

答案3

得分: 6

使用fpm可以很容易地从Go应用程序构建deb或rpm软件包。

从rubygems获取它:

gem install fpm

构建二进制文件后,例如foobar,可以按如下方式打包:

fpm -s dir -t deb -n foobar -v 0.0.1 foobar=/usr/bin/

fpm支持各种高级打包选项。

英文:

Building deb or rpm packages from Go Applications is also very easy with fpm.

Grab it from rubygems:

gem install fpm

After building you binary, e.g. foobar, you can package it like this:

fpm -s dir -t deb -n foobar -v 0.0.1 foobar=/usr/bin/

fpm supports all sorts of advanced packaging options.

答案4

得分: 5

有一个官方的Debian政策文件描述了Go的打包过程:https://go-team.pages.debian.net/packaging.html

对于:使用dh-make-golang创建一个包的框架。使用从导入路径派生的名称命名您的包,并在末尾加上-dev后缀,例如golang-github-lib-pq-dev。在Depends:行中指定依赖项(这些是用于构建的源依赖项,而不是用于运行的二进制依赖项,因为Go会静态链接所有源代码)。

安装库包将把其源代码安装到/usr/share/golang/src(可能,编译的库可能会放在.../pkg中)。构建依赖于Go包的项目将使用这些系统范围内的位置的构件。

对于可执行文件:使用dh-golang创建包。在Build-Depends:行中指定依赖项(有关打包依赖项的信息,请参见上文)。

英文:

There is an official Debian policy document describing the packaging procedure for Go: https://go-team.pages.debian.net/packaging.html

For libraries: Use dh-make-golang to create a package skeleton. Name your package with a name derived from import path, with a -dev suffix, e.g. golang-github-lib-pq-dev. Specify the dependencies ont Depends: line. (These are source dependencies for building, not binary dependencies for running, since Go statically links all source.)

Installing the library package will install its source code to /usr/share/golang/src (possibly, the compiled libraries could go into .../pkg). Building depending Go packages will use the artifacts from those system-wide locations.

For executables: Use dh-golang to create the package. Specify dependencies in Build-Depends: line (see above regarding packaging the dependencies).

答案5

得分: -4

我最近发现了https://packager.io/ - 我对他们的工作感到非常满意。也许可以打开其中一个软件包,看看他们在做什么?

英文:

I recently discovered https://packager.io/ - I'm quite happy with what they're doing. Maybe open up one of the packages to see what they're doing?

huangapple
  • 本文由 发表于 2013年2月27日 12:13:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/15104089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定