コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2015年12月26日 >>> 2015年12月13日
link もっと後

2015年12月26日

GNU autotools入門 その1

その1その2

ソースコードのビルドシステムは多々あって決定打はない(個人的にはそう思う)のですが、比較的メジャーと言って良いのがGNU autotoolsです。ビルドする際にconfigureしてmakeするヤツは、大抵autotoolsが絡んでいます。

そんなGNU autotoolsを成すツール群の一つにautoconf/automakeと言うツールがあります。こいつらは簡単に言えばMakefileを作るツールです。

autoconf, automakeとMakefileの関係
configure.ac --(autoconf)--> configure

Makefile.am --(automake)--> Makefile.in --(configure)--> Makefile

最終的に生成されるのはMakefileなのに、なぜ直接書かず遠回りをするかというと、どんな環境でもそれなりに動くMakefileを直接書くのは、実は結構大変だからです。

例えば、依存関係にあるライブラリの有無をチェックしつつ、クロスコンパイルで動的ライブラリを生成するようなMakefileをパッと書けますか?私には無理そうですし、仮に書けたとしても、Makefileを作るのは手段であって目的ではないので、あまり時間を使いたくありません。

ビルドでお決まりの手順はツールで自動生成して楽して作りたい、これがGNU autotoolsや他のビルドツールを使う目的です。

automakeの非互換性

こんな便利なautomakeですが、たまに仕様が変わって、以前の書き方だと怒られることがあります。

楽するためにツールを使っていたのに、ツールの仕様変更に対応するため時間を使うのは本末転倒な感じもしますが、それでもMakefileを直接書くより断然楽でしょうね。

昔のバージョンであるautomake-1.9ではこういう書き方が出来たのですが、

automakeでSOURCESにサブディレクトリを指定

COMMON_DIR = ./common

common_SOURCES = $(COMMON_DIR)/utils.c

これがautomake-1.14だと、

サブディレクトリを指定したときのautomakeのwarning
test/Makefile.am:19: warning: source file '$(COMMON_DIR)/utils.c' is in a subdirectory,
test/Makefile.am:19: but option 'subdir-objects' is disabled
automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the 'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding output
automake: object file(s) will be placed in the top-level directory.  However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout your
automake: project, to avoid future incompatibilities.

こんな風に長々と説教されます。警告の通りsubdir-objectsを有効にすると、今度は $(COMMON_DIR) という名前のディレクトリが作られ、common/utils.cは無いと言われ、コンパイルエラーになります。

なんじゃそりゃ。

解決方法

この警告を解決する方法は、サブディレクトリにもMakefile.amを置くこと、のようです。

今までのMakefile.am
$ tree
.
|-- Makefile.am
|-- configure.ac
`-- test
    |-- Makefile.am
    |-- common
    |   `-- utils.c
    `-- test.c

----
configure.ac
----
AC_PREREQ(2.61)
AC_INIT([automake_test], [0.1])
AC_ARG_PROGRAM()
AC_CONFIG_SRCDIR([test/test.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_AUX_DIR([conf])
AM_INIT_AUTOMAKE([foreign])
LT_INIT()

AC_CONFIG_FILES([Makefile
	test/Makefile])

AC_OUTPUT()

----
Makefile.am
----
SUBDIRS = test

----
test/Makefile.am
----
testdir = $(libdir)
test_LTLIBRARIES = libtest.la

libtest_la_SOURCES = test.c \
	common/utils.c

このようなプロジェクトがあったとします。このプロジェクトはautomakeに、下記のように怒られます。

automake-1.14に怒られるの図
$ autoreconf --force
test/Makefile.am:5: warning: source file 'common/utils.c' is in a subdirectory,
test/Makefile.am:5: but option 'subdir-objects' is disabled
automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the 'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding output
automake: object file(s) will be placed in the top-level directory.  However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout your
automake: project, to avoid future incompatibilities.
autoreconf2.50: automake failed with exit status: 1

以下のように各ディレクトリにMakefile.amを作ってあげれば、警告は出なくなります。

これからのMakefile.am
.
|-- Makefile.am
|-- configure.ac★変更★
`-- test
    |-- Makefile.am★変更★
    |-- common
    |   |-- Makefile.am★追加★
    |   `-- utils.c
    `-- test.c

----
configure.ac
----
AC_PREREQ(2.61)
AC_INIT([automake_test], [0.1])
AC_ARG_PROGRAM()
AC_CONFIG_SRCDIR([test/test.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_AUX_DIR([conf])
AM_INIT_AUTOMAKE([foreign])
LT_INIT()

AC_CONFIG_FILES([Makefile
	test/Makefile test/common/Makefile])
                      ^^^^^^^^^^^^^^^^^^^^ 追加

AC_OUTPUT()


----
test/Makefile.am
----
SUBDIRS = common

test_newdir = $(libdir)
test_new_LTLIBRARIES = libtest_new.la

libtest_new_la_SOURCES = test.c

libtest_new_la_LIBADD = common/libcommon.la


----
test/common/Makefile.am
----
noinst_LTLIBRARIES = libcommon.la

libcommon_la_SOURCES = utils.c

最初は面倒くさいですが、やってみるとtestとtest/commonが分離されて見通しが良くなります。

利点と欠点

従来の方法(親ディレクトリにMakefile.amを置く方法)と、新しい方法(各ディレクトリにMakefile.amを置く方法)の利点と欠点を考えてみます。

利点は、再利用性が高くなることです。

先の例で出てきたcommonディレクトリが「何らかの便利な機能を提供しているパッケージ」だとして、他のプロジェクトにcommonのコードを流用する場合を考えてみましょう。

従来のtest/Makefile.amに全て書く方法だと、commonディレクトリのソースコードは使いまわせますが、ビルド設定であるMakefile.amが親ディレクトリのtest側にあって、単純に使いまわせません。なぜならtest/Makefile.amではtestのビルド設定とcommonのビルド設定が混ざって書かれているため、commonのビルド設定だけを抽出するのが難しいためです。

これが新しいtest/Makefile.amとtest/common/Makefile.amに分ける方法だと、文字通りcommonディレクトリをコピーするだけでMakefile.amつまりビルドの設定も使いまわすことができます。

欠点は面倒くさいことです。

無意味にディレクトリを分割したがる輩には、ディレクトリごとにMakefile.amを作らなければならない面倒くささが、ある意味の抑止力になるので、欠点だとも言い切れませんが、やはり面倒くさいものは面倒くさいです…。

ちなみに従来の方法で書くと警告が出ますが、今のところ使えない訳でもない(※)ので、ちょっと試してみるだけとか、一時的なツールに使うだけであれば、従来の方法を選べば良いと思います。

(※)今は警告だけですが、そのうち廃止されるかもしれません。

編集者:すずき(2018/05/20 03:59)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年12月20日

C++ の変数初期化

会社で大幅にソフトを置き換えるチャンスがあったので、思い切ってCからC++11(gcc-4.6で使える範囲だけ)に切り替えました。

まだまだ使いこなせてませんがC++98より見やすいです。それでもC++ は魔界だなーと思うこともありますけど…。

Effective Modern C++ にも出てますが、C++11で導入されたuniform initialization(波括弧 { a, b, c, } での初期化)は、丸括弧や等号を置き換えることができます。大抵の場合は、ですが。

コンテナ系などstd::initializer_listを引数に取れる場合は、丸括弧と置き換えると動きが変わってしまいます。

std::initializer_listを引数に取るコンストラクタがある例

int i1(5);
-> 5
int i2{5};
-> 5

std::vector<int> b1(5);
-> size:5: 0, 0, 0, 0, 0,
std::vector<int> b2{5};
-> size:1: 5,

丸括弧は丸括弧で、引数が0個になるといきなり関数宣言扱いされる、クラスメンバ変数に使えないなど、一貫性がなくて使いづらいのです。

関数宣言扱いされる例

std::vector<int> a1();
-> a1 type is std::vector<int, std::allocator<int> > ()
std::vector<int> a2{};
-> size:0:

結局、コンストラクタがstd::initializer_listを取れるかどうかを意識して、丸括弧と波括弧を使い分ける必要がありまして、だいぶ難しいですね…。

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2015/12/23 23:26)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年12月13日

高槻ドライブ

車を放置しすぎてバッテリーが上がり、今まで自宅に3回ほどJAFを呼んでいます。4回だったかもしれないが…。

あまりにも車が可哀想なので、1か月に1度はドライブに行くことにしました。今回は高槻市の北側を体験するコースです。

  • 枚方亀岡線(府道6号線)を北へ
  • The山道(府道733号線)を西へ
  • 茨木亀岡線(府道46号線)を南へ

距離は30km程度、約1時間ほどです。ここまで書いておいてなんですが、あまりオススメしません。

46号線から一瞬だけ見える高槻市、茨木市の夜景は綺麗ですが、他は森ばかりで何も見えません。733号線は対向可能なのに車1台分しか幅がなく、横は崖で、二度と行きたくない道です。

もっとマシな道はねーのかよ?と思うのですが、高槻市は道路状況があまり良くないのです。

北は山道、南は淀川で通れず、東西は大阪〜京都を移動する車で渋滞だらけです。

その点言うと、つくば市は、土地が平らで、道が綺麗で、空いてて、広くて、とても良かったんですがねえ…。

編集者:すずき(2015/12/18 01:58)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2015年12月26日 >>> 2015年12月13日
link もっと後

管理用メニュー

link 記事を新規作成

<2015>
<<<12>>>
--12345
6789101112
13141516171819
20212223242526
2728293031--

最近のコメント5件

  • link 24年4月22日
    hdkさん (04/24 08:36)
    「うちのHHFZ4310は15年突破しまし...」
  • link 24年4月22日
    すずきさん (04/24 00:37)
    「ちゃんと数えてないですけど蛍光管が10年...」
  • link 24年4月22日
    hdkさん (04/23 20:52)
    「おお... うちのHHFZ4310より後...」
  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」

最近の記事20件

  • link 24年4月25日
    すずき (04/29 10:08)
    「[AVIFの変換] AVIFが読めないアプリケーションがたまにあるので、AVIF(AV1 Image File Format)...」
  • link 24年2月7日
    すずき (04/24 02:52)
    「[複数の音声ファイルのラウドネスを統一したい] PCやデジタル音楽プレーヤーで音楽を聞いていると、曲によって音量の大小が激しく...」
  • link 24年4月22日
    すずき (04/23 20:13)
    「[仕事部屋の照明が壊れた] いきなり仕事部屋のシーリングライトが消えました。蛍光管の寿命にしては去年(2022年10月19日の...」
  • link 24年4月17日
    すずき (04/18 22:44)
    「[VSCodeとMarkdownとPlantUMLのローカルサーバー] 目次: LinuxVSCodeのPlantUML Ex...」
  • link 23年4月10日
    すずき (04/18 22:30)
    「[Linux - まとめリンク] 目次: Linuxカーネル、ドライバ関連。Linuxのstruct pageって何?Linu...」
  • link 20年2月22日
    すずき (04/17 02:22)
    「[Zephyr - まとめリンク] 目次: Zephyr導入、ブート周りHello! Zephyr OS!!Hello! Ze...」
  • link 24年4月16日
    すずき (04/17 02:05)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その2 - インストール時のバイナリ書き換え] 目次: Zep...」
  • link 24年4月15日
    すずき (04/17 01:47)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その1 - 移動させると動かなくなる] 目次: ZephyrZ...」
  • link 24年4月11日
    すずき (04/17 00:37)
    「[VScodeとAsciiDocとKrokiローカルサーバー] 目次: LinuxAsciiDoc ExtensionはAsc...」
  • link 24年4月12日
    すずき (04/16 00:12)
    「[台湾東部沖地震に寄付] ささやかではありますが台湾東部沖地震に寄付しました。日本の赤十字社→台湾の赤十字(正式名称...」
  • link 22年9月3日
    すずき (04/16 00:08)
    「[MarkDownのその向こう] 目次: Linux簡単なドキュメントやメモはMarkDownで書くことが多いですが、気合を入...」
  • link 22年9月4日
    すずき (04/16 00:08)
    「[Asciidocをさらに活用] 目次: Linux前回(2022年9月3日の日記参照)、Asciidocのプレビュー環境の設...」
  • link 24年3月19日
    すずき (04/16 00:07)
    「[モジュラージャックの規格] 目次: Arduino古くは電話線で、今だとEthernetで良く見かけるモジュラージャックとい...」
  • link 23年6月2日
    すずき (04/16 00:07)
    「[Arduino - まとめリンク] 目次: Arduino一覧が欲しくなったので作りました。 M5Stackとesp32とA...」
  • link 24年4月9日
    すずき (04/12 12:44)
    「[初めて作ったボード動作せず(手で直した)] 目次: Arduino以前(2024年3月24日の日記参照)発注して、全く動ない...」
  • link 24年4月2日
    すずき (04/12 11:00)
    「[KiCadが動かなくなったのでビルド] 目次: ArduinoDebian Testingなマシンをapt-get upgr...」
  • link 24年4月3日
    すずき (04/12 11:00)
    「[初めて作ったボード動作せず(燃えた)] 目次: Arduino以前(2024年3月24日の日記参照)発注したPCBが届いたの...」
  • link 24年3月24日
    すずき (04/12 11:00)
    「[PCBを設計して注文] 目次: Arduinoシューティングの練習でいつもお世話になっているTARGET-1秋葉原店に、6つ...」
  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/29 10:08