ククログ

株式会社クリアコード > ククログ > 共有ライブラリーをDebianパッケージ化する方法を紹介

共有ライブラリーをDebianパッケージ化する方法を紹介

こんにちは。 OpenArmの開発に少しずつ参加している福田です。

最近、OpenArm CAN LibraryのDebianパッケージを作成しました。

本記事では、現時点の最新のdebian/のお作法をまとめました。

概要

今回例にするのはOpenArm CAN Libraryで、CMakeでビルドするC++による共有ライブラリーがメインです。

本記事では、パッケージをビルドするのに必要な最低限のファイルを用意して、手動でビルドできるようにするところまでを紹介します。

debian/ ディレクトリーの作成

Debianパッケージの作成には、debian/ディレクトリーを作り、その配下に必要なファイルを作成する必要があります。

$ mkdir debian

このdebian/配下に、次のファイルを作成していきます。

  • debian/control
  • debian/rules
  • debian/copyright
  • debian/changelog
  • debian/source/format
  • debian/upstream/metadata
  • debian/install

今回は、これらのファイルを手動で作る形を想定して説明しますが、dh_makeを使ってテンプレートを生成する方法もあります。 それについては後述する「補足: dh_makeを使ってテンプレートを生成する例」をご覧ください。

debian/control

パッケージ全体の情報と、個々のパッケージの情報を書きます。 以前のククログでも説明しているので、そちらも参照ください。

今回は次のようになりました。

主なポイントを紹介します。

パッケージ全体の情報

Source: openarm-can
Section: libs
Priority: optional
Maintainer: "Enactic, Inc." <openarm@enactic.ai>
Rules-Requires-Root: no
Build-Depends:
 cmake,
 debhelper-compat (= 13),
 ninja-build,
Standards-Version: 4.6.0
Homepage: https://docs.openarm.dev/
Vcs-Browser: https://github.com/enactic/openarm_can
Vcs-Git: https://github.com/enactic/openarm_can.git
  • Section
  • Maintainer
    • 名前に,が含まれている場合は、ダブルクオーテーション"で囲う必要があります
  • Build-Depends
    • パッケージを生成するときに利用するパッケージを書きます
    • debhelper-compatは必須です
      • パッケージのビルドに使われるdebhelperCOMPATIBILITY LEVELSを指定しています
      • 昔はdebian/compatで指定していましたが、今はここでdebhelper-compat (= 13)のように指定します
      • 現時点ではレベル13が推奨です
    • ビルドにCMakeとNinjaを利用するので、cmakeninja-buildを足しています
    • 最後の項目の末尾に,を付けてもエラーになりません
  • Standards-Version

各パッケージの情報

配布したい共有ライブラリーをパッケージしたlibopenarm-can1と、その開発用パッケージであるlibopenarm-can-devの2つを定義しています。

ライブラリーのパッケージの場合、パッケージ名の末尾にアプリケーションバイナリインターフェース(ABI)1のバージョンを付与します。 セマンティックバージョニングを使っているなど、同一メジャーバージョン内でABIが壊れない場合はメジャーバージョンをそのまま使って良いです(今回のケース)。 一方で、マイナーバージョンアップでも互換性が壊れるならば、メジャーバージョン+マイナーバージョンなどにします。

Package: libopenarm-can1
Architecture: any
Multi-Arch: same
Depends:
 ${misc:Depends},
 ${shlibs:Depends},
Description: CAN communication library for OpenArm robotic hardware
 OpenArm CAN Library is a communication bridge between high-level
 OpenArm control applications and low-level motor protocols.
 It abstracts CAN bus communication via SocketCAN interface.
Package: libopenarm-can-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends:
 ${misc:Depends},
 libopenarm-can1 (= ${binary:Version}),
Description: Development files to use OpenArm CAN as a library
 OpenArm CAN Library is a communication bridge between high-level
 OpenArm control applications and low-level motor protocols.
 It abstracts CAN bus communication via SocketCAN interface.
 .
 This package provides header files to use OpenArm CAN as a library.
  • Section
    • Sourceと同じ場合(libsの場合)は省略可能です
    • ライブラリーの開発用パッケージはlibdevelにします
  • Architecture
    • 今回は、各アーキテクチャ毎にビルドする、かつ特定のアーキテクチャに限定する必要はない、のでanyにしています
    • もし、各アーキテクチャ毎にビルドする、かつアーキテクチャを限定したい場合は、そのアーキテクチャを指定します2
    • もし、各アーキテクチャ毎にビルドしなくてよい場合は、allにします
  • Multi-Arch
    • Architectureanyの場合は基本的にsameで良いです
  • Depends
    • 必要な依存を記載します
    • ${misc:Depends}${shlibs:Depends}は、ビルド結果から依存を自動的に検出してくれる便利な指定です
    • ${misc:Depends}は、基本的に入れておきます
    • ${shlibs:Depends}は、開発用パッケージの方には入れなくてよいです3
    • 開発用パッケージ側libopenarm-can-devは、本体のlibopenarm-can1を依存に指定します
      • この際、依存バージョンを(= ${binary:Version})と指定することで、確実に同じバージョンに依存させるようにしています
  • Description
    • 次の形式で書きます
      Description: <insert up to 60 chars description>
       <insert long description, indented with spaces>
      
    • 空行は.だけの行として表します

debian/rules

パッケージの作り方を書きます。 昔はCDBS4を使う方法などがあったようですが、最近は基本的にdhコマンドだけで簡単に記述できます。

ミニマムなrulesは次のとおりです。

#!/usr/bin/make -f

%:
	dh $@

必要に応じて定義を追加します5。 今回は次のようになりました。

#!/usr/bin/make -f

export DEB_BUILD_MAINT_OPTIONS = hardening=+all

%:
	dh $@ --buildsystem=cmake+ninja

override_dh_auto_configure:
	dh_auto_configure \
		-- \
		-DBUILD_SHARED_LIBS=ON \
		-DCMAKE_BUILD_TYPE=RelWithDebInfo

dh

  • --buildsystem=cmake+ninja
    • ビルドシステムをNinjaをバックエンドにしたCMakeに設定します
    • Ninjaをバックエンドにするとビルドが速くなります

DEB_BUILD_MAINT_OPTIONS

DEB_BUILD_MAINT_OPTIONSは、ビルド時のフラグなど(features)を管理する環境変数です6

特に理由がなければhardening=+allを指定して、セキュリティーに配慮する工夫を全部入れてビルドするようにします7

override_dh_auto_configure

CMakeのオプションを指定したいので、override_dh_auto_configureを定義します。

  • --
    • 以降をdh_auto_configureコマンド自体のオプションではなく、引数として(CMakeに渡したいオプションとして)記載するために必要です
  • -DBUILD_SHARED_LIBS=ON
    • 今回は共有ライブラリーを配布したいので、共有ライブラリーをビルドするようにします
  • -DCMAKE_BUILD_TYPE=RelWithDebInfo
    • デバッグ情報付きのリリースビルドを実行するようにします

debian/copyright

ソースに関する著作権やライセンスなどの情報を記載します。 書き方は次の公式ドキュメントを参考にしてください。

今回は次のようになりました。

Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/enactic/openarm_can/releases
Upstream-Name: OpenArm CAN
Upstream-Contact: "Enactic, Inc." <openarm@enactic.ai>

Files:
 *
Copyright:
 2025 Enactic, Inc. <openarm@enactic.ai>
License: Apache-2.0
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at
 .
      http://www.apache.org/licenses/LICENSE-2.0
 .
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 .
 On Debian systems, the full text of the Apache Software License version 2 can
 be found in the file `/usr/share/common-licenses/Apache-2.0'.
  • すべてのファイルに対して同じライセンスを適用しています
  • 空行は.だけの行として表します

debian/changelog

変更履歴を書きます。

正式にビルドするときに作成し直しますが、いったん次のコマンドで表示される内容そのままに作成しておきます。

$ dch --create -v 1.0.0-1 --package openarm-can

以前のククログでも説明しているので、そちらも参照ください。

debian/source/format

パッケージのフォーマットを指定します。 大抵は8次のようにquiltを指定します。

3.0 (quilt)

debian/upstream/metadata

ソース側のメタデータを書きます。

Bug-Database: https://github.com/enactic/openarm_can/issues
Bug-Submit: https://github.com/enactic/openarm_can/issues/new
Changelog: https://github.com/enactic/openarm_can/blob/main/packages/debian/changelog
Documentation: https://docs.openarm.dev/software/can/
Repository-Browse: https://github.com/enactic/openarm_can
Repository: https://github.com/enactic/openarm_can.git

debian/install

どのファイルをどこにインストールするかを書きます。 debian/controlでパッケージを複数定義している場合には、{パッケージ名}.installファイル名でパッケージ毎に定義します。

基本的には次の書式になります。

{from} {to}

fromはプロジェクトルートからの相対パスになります。 toはインストールディレクトリーからの相対パスになります。

例えば、次のようにsetup/configure_socketcan.shのスクリプトをusr/libexec/openarm-can配下へインストールしています。

https://github.com/enactic/openarm_can/blob/f5794597afb6acc96db7bb019224963221753351/packages/debian/openarm-can-utils.install

setup/configure_socketcan.sh usr/libexec/openarm-can

また、今回は共有ライブラリーなどをインストールする必要があります。

後述の「パッケージのビルド」の方法で、まずは一度パッケージのビルドを試してみます。 すると、インストールの指定が必要なファイルについて警告が出るので、それをヒントに設定できます。

dh_missing: warning: usr/include/openarm/can/socket/arm_component.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/can/socket/gripper_component.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/can/socket/openarm.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/canbus/can_device.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/canbus/can_device_collection.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/canbus/can_socket.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/damiao_motor/dm_motor.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/damiao_motor/dm_motor_constants.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/damiao_motor/dm_motor_control.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/damiao_motor/dm_motor_device.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/include/openarm/damiao_motor/dm_motor_device_collection.hpp exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/cmake/OpenArmCAN/OpenArmCANConfig.cmake exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/cmake/OpenArmCAN/OpenArmCANTargets-relwithdebinfo.cmake exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/cmake/OpenArmCAN/OpenArmCANTargets.cmake exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/cmake/OpenArmCAN/OpenArmCANVersion.cmake exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/libopenarm_can.so exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/libopenarm_can.so.1 exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/libopenarm_can.so.1.0.0 exists in debian/tmp but is not installed to anywhere 
dh_missing: warning: usr/lib/x86_64-linux-gnu/pkgconfig/openarm-can.pc exists in debian/tmp but is not installed to anywhere

このようなケースでは、既にインストールしたいパスと同じパス構成になっていることが多く、その場合はtoを省略して次のように書けます。 (プロジェクトルートからの相対パスになっていませんが、ファイルが見つからない場合はdebian/tmp/配下を探してくれるので、このようにシンプルに書けます)。

libopenarm-can1.install

usr/lib/*/lib*.so.*

libopenarm-can-dev.install

usr/include/*
usr/lib/*/lib*.so
usr/lib/*/pkgconfig/*
usr/lib/*/cmake/OpenArmCAN/*

以下補足します。

補足: 共有ライブラリーの配布の仕方について

ビルドされた共有ライブラリーは次のようになっています。

libopenarm_can.so -> libopenarm_can.so.1
libopenarm_can.so.1 -> libopenarm_can.so.1.0.0
libopenarm_can.so.1.0.0

通常パッケージlibopenarm-can1ではusr/lib/*/lib*.so.*を指定し、次の2つを配布しています。

libopenarm_can.so.1 -> libopenarm_can.so.1.0.0
libopenarm_can.so.1.0.0

開発用パッケージlibopenarm-can-devでは、usr/lib/*/lib*.soを指定し、次を配布しています。

libopenarm_can.so -> libopenarm_can.so.1

これは、GNU/Linuxの共有ライブラリーとして一般的な構成です。 詳細は次のククログをご覧ください。

補足: その他のインストール関連機能

debian/install以外にも同様のインストール関連の機能が複数あります。 特に、ドキュメントファイルやsystemd系のファイル、ログローテートファイルなどは専用の機能があり、それらについてはdebian/installではなくてそちらで定義するべきです。

それらの機能については、debhelperdh_installxxxを確認します。

また、勘違いしがちなポイントとして、debian/dirsがあります。 インストール時にディレクトリーを作成するためのものですが、debian/installでインストールするパスなどは自動で作成されるため、それらのためのdebian/dirsの設定は不要です。 意図的に空ディレクトリーを用意しておきたい場合などに使用します。

パッケージのビルド

ソースアーカイブを、1つ上のディレクトリーに作成します。

$ git archive HEAD --prefix openarm-can-1.0.0/ --output ../openarm-can_1.0.0.orig.tar.gz

アーカイブ名には命名規則があり、{パッケージ名}_{バージョン}.orig.tar.gzとなっている必要があります。

また、プロジェクトディレクトリー内に、debian/以外に変更のあるファイルが存在しないことを確かめます。 .gitignoreで管理対象外になっているファイルも含めて、削除してクリーンにします。

以上で、次のコマンドを実行すると、Debianパッケージのビルドが実行されます。

$ debuild -us -uc

-us, -ucオプションは、署名を省略するためのオプションです。 検証目的で作成するので、署名は省略します。

以上で、プロジェクトディレクトリーの1つ上のディレクトリーに、.debファイルが作成されます。

補足: dh_makeを使ってテンプレートを生成する例

debian/ディレクトリーを準備する別の方法として、dh_makeを使ってテンプレートを生成する方法もあります。 多くのファイルが生成されてしまうので、今回は手動で最低限のファイルを作る方法を紹介しましたが、テンプレートの内容も確認してみると面白いです。

$ git archive HEAD --prefix openarm-can-1.0.0/ --output openarm-can-1.0.0.tar.gz
$ dh_make -p openarm-can_1.0.0 -f openarm-can-1.0.0.tar.gz

まとめ

本記事では、OpenArm CAN LibraryでDebianパッケージを作成した事例に即して、現時点の最新のdebian/のお作法をまとめました。

また、今回のDebianパッケージ対応は、クリアコードの提供するサービスであるOSS開発支援サービスの一環で実施したものです。 クリアコードはOSS開発に関する技術的な支援を得意としておりますので、お問い合わせフォームよりお気軽にお問い合わせください。

  1. GNU/Linuxの共有ライブラリーのバージョンとアプリケーションバイナリインターフェース(ABI)

  2. debian/control Architecture

  3. ${shlibs:Depends}は、共有ライブラリー関連依存の自動検出であり、開発用パッケージは共有ライブラリーの実ファイルを通常は含まないからです

  4. CDBS: Debianパッケージの作り方と公開方法: groongaを例にして - debian/rules参照

  5. debian/rules: https://www.debian.org/doc/manuals/maint-guide/dreq.ja.html#rules

  6. features: FEATURE AREAS in dpkg-buildflags(1)

  7. Hardening

  8. https://www.debian.org/doc/manuals/maint-guide/dother.en.html#sourcef