LoginSignup
1
0

rpm/debを簡易的にMakefileで作成する

Last updated at Posted at 2024-03-18

「パッケージングポリシーとか面倒臭いんじゃ社内用にちょっとしたファイルを所定のパスに配置するのに使いたいだけなんじゃ」という人のために。

「hello, world」を出力するhelloプログラムを/usr/local/bin/に配置する簡単な例を作ってみます。

$ uname -srm
Linux 6.5.0-25-generic x86_64
$ lsb_release -sd
Ubuntu 22.04.4 LTS

本文

パッケージング対象

これらをパッケージにしていきます(hello.cは割愛)。
Makefileの$(DESTDIR)変数は以下を参考にしています。

$ tree
.
├── Makefile
└── hello.c
Makefile
BINARY := hello

.PHONY: all install clean rpm

all: $(BINARY)
install: $(BINARY)
        install -d $(DESTDIR)/usr/local/bin/
        install -m 0755 hello $(DESTDIR)/usr/local/bin/hello
clean:
        $(RM) $(BINARY)

この時点ではmakemake installすると/usr/local/bin/にhelloの実行ファイルがインストールされるだけです。

$ make
cc     hello.c   -o hello
$ sudo make install
install -d /usr/local/bin/
install -m 0755 hello /usr/local/bin/hello
$ hello
hello, world

rpmターゲット

Ubuntuでrpmを作成するにはrpmパッケージが必要なのでまずはインストールします。

$ sudo apt update && sudo apt install rpm

rpmを作成出来る様に変更を加えます。

.
├── Makefile
├── hello.c
└── hello.spec
Makefile
BINARY := hello

.PHONY: all install clean rpm

all: $(BINARY)
install: $(BINARY)
        install -d $(DESTDIR)/usr/local/bin/
        install -m 0755 hello $(DESTDIR)/usr/local/bin/hello
clean:
        $(RM) $(BINARY)

rpm: $(BINARY)
        make install DESTDIR=${PWD}/root
        rpmbuild --bb --buildroot ${PWD}/root \
                --define "%_topdir ${PWD}" \
                --define "%_builddir ${PWD}" \
                --define "%_buildrootdir ${PWD}/root" \
                --define "%_rpmdir ${PWD}/rpm" \
                --define "%_srcrpmdir ${PWD}/rpm" \
                hello.spec
        rm -rf root

hello.spec
Summary: hello world program
Name: hello
Version: 1.0
Release: 0
License: MIT
Packager: liqsuq <liqsuq@example.com>

%description
hello world program

%files
/usr/local/bin/hello

specファイルの各項目については以下を参照してください。

rpmではデフォルトでは~/rpmbuild/内にいくつかのディレクトリが作成されそこでビルドされるのですが、今回の様にMakefileでソースツリー内で作業するのには向いていません。なので内部変数をいじり、ソースツリー内に作業を行う様にしています。

またポイントとして、rpmターゲット内でinstallターゲットを呼び、ソースツリー内のrootディレクトリにインストールを行いこのディレクトリを元にrpm作成を行っています。rpmビルドではspecファイルにbuildセクションがあり、それを使うことも出来るのですが後述のdebターゲットと処理を共通化するために敢えてこうしています。

この状態でmake rpmを行うと計算機のアーキテクチャに合わせたrpmファイルが作成されます。

$ make rpm
:
$ tree
.
├── Makefile
├── hello
├── hello.c
├── hello.spec
└── rpm
    └── x86_64
        └── hello-1.0-0.x86_64.rpm

specファイルにBuildArch: noarchを追加すると〜.noarch.rpmと付くアーキテクチャに依存しないパッケージが作成されます。シェルスクリプトや設定ファイル等に便利でしょう。

debターゲット

debを作成出来る様に変更を加えます。

以下のtree出力中のdebはディレクトリです。dpkg-debの引数解釈の都合、ディレクトリが無いとパッケージファイル名と認識されてしますので予め作成しておきます。

$ tree
.
├── DEBIAN
│   └── control
├── Makefile
├── deb
├── hello.c
└── hello.spec
Makefile
BINARY := hello

.PHONY: all install clean rpm deb

all: $(BINARY)
install: $(BINARY)
        install -d $(DESTDIR)/usr/local/bin/
        install -m 0755 hello $(DESTDIR)/usr/local/bin/hello
clean:
        $(RM) $(BINARY)

rpm: $(BINARY)
        make install DESTDIR=${PWD}/root
        rpmbuild --bb --buildroot ${PWD}/root \
                --define "%_topdir ${PWD}" \
                --define "%_builddir ${PWD}" \
                --define "%_buildrootdir ${PWD}/root" \
                --define "%_rpmdir ${PWD}/rpm" \
                --define "%_srcrpmdir ${PWD}/rpm" \
                hello.spec
        rm -rf root

deb: $(BINARY)
        make install DESTDIR=${PWD}/root
        cp -r DEBIAN root/
        fakeroot dpkg-deb --build root deb
        rm -rf root
DEBIAN/control
Package: hello
Maintainer: liqsuq <liqsuq@example.com>
Architecture: amd64
Version: 1.0-0
Description: hello world program

こちらではrootディレクトリにインストールした後にDEBIANディレクトリをコピーしてdebの作成を行っています。DEBIANディレクトリをコピーする理由や各項目の説明は以下を参照してください。

この状態でmake debを行うとDEBIAN/controlのArchtecture:に対応するdebファイルが作成されます。

$ make deb
:
$ tree
.
├── DEBIAN
│   └── control
├── Makefile
├── deb
│   └── hello_1.0-0_amd64.deb
├── hello
├── hello.c
└── hello.spec

debではDEBIAN/controlにArchtecture: allと記述するとアーキテクチャに依存しないパッケージが作成されます。

ソースツリー

最終的なソースツリー及びMakefileは以下の様になります。

$ tree
.
├── DEBIAN
│   └── control
├── Makefile
├── deb
├── hello.c
└── hello.spec
Makefile
BINARY := hello

.PHONY: all install clean rpm deb

all: $(BINARY)
install: $(BINARY)
        install -d $(DESTDIR)/usr/local/bin/
        install -m 0755 hello $(DESTDIR)/usr/local/bin/hello
clean:
        $(RM) $(BINARY)

rpm: $(BINARY)
        make install DESTDIR=${PWD}/root
        rpmbuild --bb --buildroot ${PWD}/root \
                --define "%_topdir ${PWD}" \
                --define "%_builddir ${PWD}" \
                --define "%_buildrootdir ${PWD}/root" \
                --define "%_rpmdir ${PWD}/rpm" \
                --define "%_srcrpmdir ${PWD}/rpm" \
                hello.spec
        rm -rf root
        
deb: $(BINARY)
        make install DESTDIR=${PWD}/root
        cp -r DEBIAN root/
        fakeroot dpkg-deb --build root deb
        rm -rf root

結び

後は必要に応じて依存関係やプリ/ポストスクリプトを記述してみてください。

debでアーキテクチャを決め打ちせずビルド中に自動判定するとかソースパッケージを作りたいとかがしたい場合には各パッケージングガイドを読んでみてください。自分は諦めました。特にdeb。

// ビルド中にDebianポリシーに違反していないか等のチェックが走るため軽率に使えない

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0