我正在尝试为名为 igotu2gpx 的软件打包 snap。该软件是 qt4 并使用libmarble
。我查看了 repos(并使用虚拟机尝试了它)-Ubuntu 14.04 是最后一个提供libmarble
qt4 的版本。之后,软件包消失了或被同名的 qt5 版本取代了(!)。
现在,为了构建 snap(适用于 Ubuntu 18.04),我手动下载了所有必要的 .deb 文件并想直接从我的 snap 中引用它们。
我首先在额外部分中使用自定义插件。这有效,但仅适用于构建阶段。在准备阶段,我必须在包含和构建源的部分内直接引用这些 .deb,但为了定义额外的 apt 源,我需要定义一个插件,并且插件空间已被插件占用qmake
。此外,我需要固定或类似的机制,因为在定义时PLUGIN_STAGE_SOURCES
我必须明确引用旧软件包。并且build-packages
/stage-packages
不允许明确定义版本号。
那么,我怎样才能做一些“简单的事情”,比如添加自定义 .deb 文件?
snapcraft.yaml:
name: igotu
base: core18 # the base snap is the execution environment for this snap
version: bzr-227
title: GUI for i-gotU USB GPS travel logger
summary: MobileAction i-gotU USB GPS travel logger
description: |
MobileAction i-gotU USB GPS travel logger
license: unknown
grade: devel
#confinement: strict
confinement: devmode
apps:
igotugui:
command: usr/local/bin/igotugui
plugs:
- hardware-observe
- raw-usb
- x11
environment:
LD_LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/usr/local/lib
igotu2gpx:
command: usr/local/bin/igotu2gpx
plugs:
- hardware-observe
- raw-usb
environment:
LD_LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/usr/local/lib
parts:
app:
source-type: bzr
source: lp:igotu2gpx
# expect to pull a 0.4 version rev. 227
plugin: qmake
qt-version: qt4
build-packages:
- libqtgui4
- pkg-config
- ctags
- gdb
- chrpath
- libboost-all-dev
- libboost-program-options-dev
- libusb-dev
stage-packages:
# to be cleaned up and marble to be added
- libqt4-declarative
- libqt4-opengl
- libqt4-svg
- libqt4-xml
- libqt4-xmlpatterns
- libqtcore4
- libqtdbus4
- libqtgui4
- libqtwebkit4
- libxt6
# [...]
# the following declarations must point to the .deb files
- libastro1=4:4.13.0-0ubuntu1
- libmarblewidget18=4:4.13.0-0ubuntu1
- marble-data=4:4.13.0-0ubuntu1
- marble-plugins=4:4.13.0-0ubuntu1
extradebs:
plugin: extradebs
extra-debs:
- 3rdParty/deb/other/libgps20_3.9-3_amd64.deb
- 3rdParty/deb/other/libqextserialport1_1.2.0~rc1+git7-g3be3fbf-1_amd64.deb
- 3rdParty/deb/other/libqtlocation1_1.2.0-3ubuntu5_amd64.deb
- 3rdParty/deb/other/libquazip0_0.6.2-0ubuntu1_amd64.deb
- 3rdParty/deb/other/libshp1_1.2.10-7_amd64.deb
- 3rdParty/deb/marble/libastro1_4:4.13.0-0ubuntu1_amd64.deb
- 3rdParty/deb/marble/libastro-dev_4:4.13.0-0ubuntu1_amd64.deb
- 3rdParty/deb/marble/libmarble-dev_4:4.13.0-0ubuntu1_amd64.deb
- 3rdParty/deb/marble/libmarblewidget18_4:4.13.0-0ubuntu1_amd64.deb
- 3rdParty/deb/marble/marble-data_4:4.13.0-0ubuntu1_all.deb
- 3rdParty/deb/marble/marble-plugins_4:4.13.0-0ubuntu1_amd64.deb
build-packages:
#- libmarble-dev=4:4.13.0-0ubuntu1 depends on
- libqtcore4
- libqtgui4
- libqt4-dev
#- libmarblewidget18=4:4.13.0-0ubuntu1 depends on
- libphonon4
- libqt4-dbus
- libqt4-declarative
- libqt4-network
- libqt4-script
- libqt4-svg
- libqt4-xml
#- libqtcore4
#- libqtgui4
- libqtwebkit4
- phonon
#- marble-plugins=4:4.13.0-0ubuntu1 depends on
#- libphonon4
#- libqextserialport1
#- libqt4-declarative
#- libqt4-network
#- libqt4-script
- libqt4-sql
#- libqt4-svg
#- libqt4-xml
#- libqtcore4
#- libqtgui4
#- libqtwebkit4
#- phonon
- libwlocate0
#- libgps20 depends on
- libbluetooth3
- libusb-1.0-0
插件/extradebs.py:
import snapcraft
import os
import subprocess
from typing import List
import collections
import logging
from snapcraft.internal import errors
logger = logging.getLogger(__name__)
class ExtraDebs(snapcraft.BasePlugin):
@classmethod
def schema(cls):
schema = super().schema()
# Add a new property called "my-property"
schema['properties']['extra-debs'] = {
"type": "array",
"uniqueItems": True,
"items": {"type": "string"},
}
# The "my-option" property is now required
#schema['required'].append('extra-debs')
return schema
def pull(self):
super().pull()
print ('Start pulling extra debs')
deb_files = ["%s/../../project/snap/%s" % (self.partdir, file) for file in self.options.extra_debs]
self._install_extra_debs(deb_files)
#def build(self):
# super().build()
# print('Look ma, I built!')
@classmethod
def _install_extra_debs(cls, deb_files: List[str]) -> None:
deb_files.sort()
logger.info("Installing extra deb files: %s", " ".join(deb_files))
env = os.environ.copy()
env.update(
{
"DEBIAN_FRONTEND": "noninteractive",
"DEBCONF_NONINTERACTIVE_SEEN": "true",
"DEBIAN_PRIORITY": "critical",
}
)
dpkg_command = [
"sudo",
"--preserve-env",
"dpkg",
"-i",
]
try:
subprocess.check_call(dpkg_command + deb_files, env=env)
except subprocess.CalledProcessError:
raise errors.BuildPackagesNotInstalledError(packages=deb_files)
package_names = [deb.split("/")[-1].split('_')[0] for deb in deb_files]
try:
subprocess.check_call(["sudo", "apt-mark", "auto"] + package_names, env=env)
except subprocess.CalledProcessError as e:
logger.warning(
"Impossible to mark packages as auto-installed: {}".format(e)
)
答案1
一个更简单的方法是使用make
插件并自定义其步骤:
...
parts:
app:
after: [extradebs]
...
...
extradebs:
...
plugin: make
override-pull: |
...
override-stage: |
...
override-build: |
...
override-install: |
...
...
...
...
参考:
答案2
这可以使用转储插件直接。例如
libsqlite:
plugin: dump
source: http://ports.ubuntu.com/pool/main/s/sqlite3/libsqlite3-0_3.31.1-4_amd64.deb
请注意,这当然会对架构进行硬编码。如果您需要进行多架构构建,则可以使用类似以下方法https://forum.snapcraft.io/t/alias-request-for-snap-google-cloud-cli-arm/29718/5
最后,如果你尝试“覆盖”已由另一部分安装的文件,则会收到类似以下错误
Failed to stage: Parts 'x' and 'y' have the following files, but with different contents
您可以通过在其定义中添加以下内容来删除第一部分安装的过时文件:
stage:
- -file/to/remove
- -other/file/to/remove