Autotoolsを使ってプロジェクトのMakefileを生成する


# はじめに
**Autotools**を用いた **Makefile**生成の流れを勉強したので，メモがてらまとめました．

**Autotools**はLinuxなら各々のパーケージ管理ツールからインストールできます．MacOSでも **Homebrew**経由で簡単に入れられます．

```Homebrewでの導入方法
$ brew install automake
$ brew install autoconf
```

今回の例として，ディレクトリ構造は次のようなものを想定しています．

* project
    * src
        * book.h
        * book.cpp
        * main.cpp

# 1. Makefileの生成
## 1.1 Makefile.amの作成
プロジェクトルートおよびソースが入っている全てのサブディレクトリ内に **Makefile.am**を作成します．以下は一例です．

```Makefile.am
# ソースファイルの入っているサブディレクトリの指定
SUBDIRS = src
```

```src/Makefile.am
# 作成する実行可能ファイルの名前
bin_PROGRAMS = test

# Cコンパイラへ渡すオプション(ここではコメントアウトしています)
# test_CFLAGS = -g

# C++コンパイラへ渡すオプション
test_CXXFLAGS = -g

# 使用しているライブラリ(ここではコメントアウトしています)
# test_LDADD = -lm

# test生成に必要なソースコード
test_SOURCES = main.cpp book.h book.cpp


### 以下はライブラリを作成する際の設定(オプション)

# インストールするヘッダファイル
include_HEADERS = book.h

# インストールする際のライブラリ名
lib_LIBRARIES = libbook.a

# Cコンパイラへ渡すオプション(ここではコメントアウトしています)
# libbook_a_CFLAGS = -g

# C++コンパイラへ渡すオプション
libbook_a_CXXFLAGS = -g

# ライブラリ生成に必要なソースコード
libbook_a_SOURCES = book.h book.cpp
```

`test`という実行可能ファイルに関するオプション・依存ファイル等を設定する際は，接頭辞として **'test_'**を付与しています．(`test`という名前以外の実行可能ファイルを作成する際はこれらの接頭辞も変えて下さい)

ライブラリ名についても同様です．こちらは拡張子の前の **'.'**もアンダーバーに変えてください．


## 1.2 configure.acの作成
プロジェクトルートで`autoscan`を実行します．

```
$ autoscan
```

そうすると， **project**直下に **configure.scan**というファイルが作られます．このファイル名を次のように変更します．

```
$ mv configure.scan configure.ac
```

その後， **configure.ac**を次のように変更します.

```configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([test], [1.0], [your@address.com])    # プロジェクトに合わせてこの行を変更
AM_INIT_AUTOMAKE                              # この行を新規追加
AC_PROG_RANLIB                                # ライブラリを作成するならこの行を新規追加
AC_CONFIG_SRCDIR([src/book.cpp])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_CONFIG_FILES([Makefile
                 src/Makefile])
AC_OUTPUT
```

## 1.3 Makefile.inの生成
初めに， **NEWS**， **README**， **AUTHORS**， **ChangeLog**というファイルを(空で構いませんので)作成します．

```
$ touch NEWS README AUTHORS ChangeLog
```

この手順は **configure.ac**の **AM_INIT_AUTOMAKE**の行を次のように変更することで省略することができます．

```configure.ac
AM_INIT_AUTOMAKE([foreign])
```

既存のファイル，例えば **README.md**等を使用したい場合はこのオプションを設定すると良いです．(GNUの標準に従っていないことになりますが)
 
次に，下記のコマンドを実行していき， **Makefile.in**を生成します．

```
$ autoheader
$ aclocal
$ automake -a -c
```


## 1.4 configureスクリプトの生成
次のコマンドで`configure`スクリプトを生成します．

```
$ autoconf
```

これでプロジェクトの`configure`スクリプトを作成することができました．


## 1.5 Makefileの生成

```
$./configure
```
を実行することで **Makefile**が生成されます．後は，`make`を実行することで実行可能ファイルを生成，`make install`を実行することでライブラリをインストールすることができます．やったぜ🎉🎉🎉


# 2. バージョン管理
説明した手順を実行していくと多数の中間ファイルが生成されますが，結局次のファイルのみをバージョン管理の対象とすればよさそうです．
* 各々の **Makefile.am**
* **configure.ac**
* (作成していれば) **NEWS** **README** **AUTHORS** **ChangeLog**


# 3. プロジェクトの公開
GitHub上でプロジェクトを公開する際は，次のようなスクリプトも追加しておくとユーザはより簡単に **Makefile**を作成できるようになります．

```bootstrap.sh
#!/bin/sh
autoreconf --install --force || exit 1
echo "Please run ./configure, make and make install."
```

`autoreconf`というのは，`autoheader` `aclocal` `automake` `autoconf`等をまとめてやってくれるコマンドです．


# 4. 最後に
これでもうゴリゴリ **Makefile**を書かなくて済む…
**Autotools**に関してはまだまだ全くの初心者ですので，不適切な表現をしている箇所がありましたらコメントにて指摘して頂けると幸いです．


# 参考
* [configureファイルの書き方 - ごろねこ日記](http://d.hatena.ne.jp/hiroe_orz17/20131006/1381040379)
* [configureの作り方 〜まだMakefileを書いていませんか?〜 - @IT](http://el.jibun.atmarkit.co.jp/itsenshi/2012/08/configure-makef-1328.html)
* [libraryの作成 - hippos-lab::net](http://homepage2.nifty.com/hippos/autoconf/library.html)
* [Autotools (automake, autoconf, libtool) 使い方まとめ - たまにゃんのメモ帳](http://tamaobject.hatenablog.com/entry/2013/08/01/165119)
* [Use autotools with README.md - stackoverflow](http://stackoverflow.com/questions/15013672/use-autotools-with-readme-md)
* [Which files generated by Autotools should I keep in version control repository? - staskoverflow](http://stackoverflow.com/questions/3290908/which-files-generated-by-autotools-should-i-keep-in-version-control-repository)