freebsdでバイナリパッケージを作成しようとしています。私が見つけたすべてのガイドは、デフォルトでポートを使用してインストールされたソフトウェアからバイナリパッケージをビルドすると言います。ポートをインストールせずにこれを行う方法を探しています。
可能ですか?
私のコードはgolanにあります。したがって、ソースコードにはGoコードと設定ファイルでコンパイルされたバイナリが含まれています。
答え1
Packageformatのドキュメントはここにあります。 https://wiki.freebsd.org/pkgng#Package_format
パッケージを作成するためにソフトウェアをインストールする必要はありません。ポートのパッケージング中に一時ディレクトリにインストールされ、パッケージ化されます。
答え2
パッケージ形式のドキュメント(pkgngがpkgになったため)が今あります。https://github.com/freebsd/pkg#pkgfmt。
ファイルは.pkg
デフォルトでtarアーカイブであり、オプションでいくつかの標準ツールの1つといくつかの追加の制約を使用して圧縮されます。
まず、アーカイブの最初のファイルはメタデータです。 2つのファイルが指定され、名前+MANIFEST
は+COMPACT_MANIFEST
パスもなく先行もありません/
。以下はインストールするファイルで、各ファイルにはフルターゲットパス(で始まる/
)があります。
メタデータ
+MANIFEST
仕様によると、YAMLとJSONが多少混在したUCL形式のファイルです。純粋なJSONが機能します(パッケージのインストールに使用される場合pkg add blah.pkg
)。これは、FreeBSDリポジトリでパッケージをチェックするときに見つかりました。
マニフェスト値は、で説明されているように、makefile変数に大きく対応します。https://docs.freebsd.org/en/books/porters-handbook。具体的には:
name
パッケージに選択した名前です。
version
これはバージョンであり、指定された2つのバージョンのうちどのバージョンが最新であるかを判断するためのいくつかの規則に従います。
origin
リポジトリ内のパッケージの物理的な場所がフォーマットの場合とcategory/name
値name
は同じですname
。追加カテゴリはで指定できますcategories
。
comment
パッケージの 1 行の説明です。
arch
同様の形をとりますfreebsd:13:x86:64
。freebsd:*
特定のアーキテクチャおよび/またはオペレーティングシステムのバージョンに依存しないパッケージ(たとえば、私のためにインストールされている)のワイルドカード値。
www
は、maintainer
それぞれプロジェクトのウェブサイトのURLと管理者のメールアドレスです。
prefix
一般的にそうです。ただし、パッケージがおよび/usr/local
にインストールされていてもインストールには影響しないようです。/opt
/etc
licenselogic
:single
ライセンスが1つしかない場合、or
複数のライセンスから選択できる場合です。
licenses
などのハンドルで参照されるライセンスのリストですGPLv3+
。詳しくはポーターマニュアルをご覧ください。GPLv2
BSD
flatsize
インストールされているすべてのファイルのフルサイズのようです。私が確認したパッケージの値がわずかに異なるため、100%確信できませんが、この仮定を使用して作成したパッケージはうまくインストールされましたpkg add
。
users
、groups
パッケージがインストールされたときに作成されたユーザーとグループであるようです(これを試していないため、これらのエントリが実際にそこに記載されているユーザーとグループの作成をトリガーしているかどうかはわかりません)。
options
: わかりません。私のパッケージが正しくインストールされました。いいえ。
desc
パッケージのより長い(1行以上)説明。
categories
このパッケージがリストする必要がある他のカテゴリのリストです。ここでカテゴリがorigin
繰り返されるようです。
deps
依存関係は、このパッケージが機能するために必要な他のパッケージです。通常、次の形式を取ります。
name: {origin: category/name, version: 1.2.3}
(最小バージョンが必要)または単に- `name:{source:category/name} (すべてのバージョンに対応)
directories
パッケージによって生成されたディレクトリのようです。アイテム形式は/usr/local/share/foo-1.0: y
;この値が何であるかよくわかりません。削除するときにディレクトリを削除しますか?ただし、このエントリがない場合、パッケージは正常にインストールされます(必要に応じてディレクトリが作成されます)。
files
:ファイルとそのSHA256チェックサム。アーカイブのファイルにここにエントリがない場合はどうなるかわかりません。まったくインストールされていませんか、それともインストールされましたが、SHA256確認なしでインストールされましたか?
scripts
インストールまたはアンインストールの前、途中、および後に実行されるスクリプトです。
+COMPACT_MANIFEST
一部の値を省略してください+MANIFEST
。前者はリポジトリのパッケージをリストするために使用され、後者は実際のインストールを実行するために使用されます。+MANIFEST
パッケージをインストールせずに使用するだけで+COMPACT_MANIFEST
動作するようですが、パッケージを公式リポジトリに入れようとすると副作用が発生する可能性があります。
パッケージを構築する
私は単純なシェルスクリプトだけでFreeBSDにインストールできるパッケージをまとめました。これは良い副作用があります。 BSDをビルドする必要もありません。これは、ネイティブコードがない場合に便利です。
最も簡単な方法は、YAMLでスケルトンマニフェストを構築し、すべてを動的に作成してJSONに変換することですfiles
。flatsize
シェルスクリプトの例:
FLATSIZE=0
create_files_entry() {
# TODO if the file is a link, just insert '-'
sha256sum $1 | sed -E 's,([a-fA-F0-9]*) *(.*), \2: \1,' | sed $2
}
add_file() {
[ -d $1 ] && return
create_files_entry $1 $2 >> $(dirname $0)/cache/files.yaml
tar -Pr -f $(dirname $0)/cache/data.tar --transform=$2 $1
case `uname` in
Linux)
FLATSIZE=$(( FLATSIZE + $(stat -c %s $1) ))
;;
FreeBSD)
FLATSIZE=$(( FLATSIZE + $(stat -f %d $1) ))
;;
*)
echo "ERROR: unsupported build platform: `uname`"
exit 1
;;
esac
}
echo "files:" > cache/files.yaml
# the second parameter is a transformation to change the file path
add_file path/to/file 's,\./path/to/,/usr/local/foo/,'
# add more files in this manner as needed
echo "flatsize: $FLATSIZE" >> files.yaml
cat $manifest.yaml $cache/files.yaml | python3 -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read())))' > cache/+MANIFEST
# create new archive with +MANIFEST (without leading /)
tar -c -f cache/full.tar --transform='s,\./cache/,,' cache/+MANIFEST
tar -A cache/data.tar -f cache/full.tar
# compress and move to destination
xz cache/full.tar
mv cache/full.tar.xz out/$PKGNAME-$PKGVER.pkg
インストールする
生成されたpkgファイルは、次のコマンドを使用してインストールできるようになりました。
pkg add /path/to/foo-1.2.3.pkg