複数の静的ライブラリを結合する方法 (2019年版)

2つの static library, libX.a と libY.a を結合して libAll.a を生成する方法です

この記事は 複数の静的ライブラリ (.a) を結合する方法 - pyopyopyo - Linuxとかプログラミングの覚え書き - の改訂版です

Linux の場合 (方法1)

ar scripts を使います.
ar scripts (GNU Binary Utilities)

具体的にはarコマンドに "-M" オプションを付与して起動します.

$ ar -M

すると標準入力からスクリプトを受け付けるので,libAll.a を生成して libX.a と libY.a を追加するスクリプトを入力します

create libAll.a
addlib libX.a
addlib libY.a
save

これを Makefile で自動実行するには次のようなルールを書きます

libAll.a : libX.a libY.a
        @echo "create $@\n" $(addprefix addlib , $(addsuffix \\n, $^)) "save" | ar -M
動作原理

  • create $@ は create libAll.a に置換されます
  • $^ は "libX.a libY.a" のリストに置換されます
  • $(addsuffix \\n, $^)で "libX.a\n libY.a\n"に置換されます
  • $(addprefix addlib , "libX.a\n libY.a\n") は "addlib libX.a\n addlib libY.a\n"に置換されます

まとめると

echo "create libAll.a \n " "addlib libX.a\n  addlib libY.a\n" "save" 

をまず実行して ar script を stdoutに出力,パイプ経由で ar -M のstdin に渡すことになります


Linux の場合 (方法2)

少し違う Makefile の書き方もあります

libZ.a: libX.a libY.a
        $(RM) $@
	$(AR) cqT $@ $^
	echo "create $@\naddlib $@\nsave\nend" | ar -M
動作原理

仕組みとしては

$ ar cqT libZ.a libX.a libY.a

で,まず一時的なライブラリとして libZ.a を生成します

この libZ.a は thin archive 形式で作成されていて

  • シンボルテーブル
  • 元ファイルのパス名

のみを保持していて,データやコードの実体は含んでいません

次に thin archive 形式のライブラリを ar scriptで変換します.

create libZ.a
addlib libZ.a
save
end

これで新しい libZ.a を作成し,データやコードも含んだ スタティックライブラリを出力します

mac OS の場合

mac OS の場合は /usr/bin/libtool を使うと簡単に結合できます

$ /usr/bin/libtool -o libZ.a   libX.a libY.a

なおこの方法は Linux では使えません.Linux の /usr/bin/libtool は GNU版で,mac OS のそれとは動作が異なるためです.

svnからgitへの移行方法

久しぶりにSubversionリポジトリをgitに移行したので手順をまとめておきます

2020/11/30 追記.加筆したエントリ http://pyopyopyo.hatenablog.com/entry/2020/11/30/154224
を新しく用意しました.

subversion側の状況を確認する

SVNでcheckout済みの作業ディレクトリにて,svn リポジトリのURLやパスを確認します

$ cd SVNの作業
$ svn info
  • URL: svn+ssh:///サーバ名/hogehoge/src/trunk
  • Relative URL: ^/src/trunk

SVNリポジトリは サーバ上の hogehogeディレクトリにあり,
SVNリポジトリの直下には src というディレクトリ,その下に trunkというディレクトリがあることがわかります

src ディレクトリの中身を確認します

$ svn list ^/src/
branches/
tags/
trunk/

trunk, branches, tags というディレクトリがあります.つまりこのリポジトリSVNの標準的な構成になっています.

このような標準的な構成のSVNリポジトリは以下の手順で簡単にgitに移行できます.

また変則的な構成の場合でも,以下の手順を参考に git svnのhelpを読みながらオプションを大量に指定すればgitに移行できます

git側の準備

git のサブコマンド git-svn を使います.インストールされてない環境も多いので,予め確認&追加インストールしておきます.

まず試しに起動してみます.インストール済みならヘルプが表示されます.

未インストールの場合は 以下のようなエラーメッセージが出ます

$ git svn 
git: 'svn' is not a git command. See 'git --help'.

この場合は追加インストールします.debian とか ubuntu なら

$ sudo apt install git-svn

でOK

SVNからgitへの変換

$ git svn clone --stdlayout  --prefix=svn/ [svn-repo] [git-dir]

[svn-repo]は,上記の svn infoで調べたURLです.
上記の例に従えば svn+ssh:///サーバ名/hogehoge/src/ になります

オプションの意味は以下の通りです

  • [svn-repo]は tagsやtrunkがある標準構成になっているので --stdlayout をつける
  • svn由来のブランチで有ることを示すため "--prefix=svn/" をつけます.これで git の remote-tracking ref が refs/remotes/svn/ となります.

[git-dir]は出力先ディレクトリ名です. ここに作業デレクトリが作成されます

確認

ログやブランチの状況を確認します

$ git log
$ git branch -a