Autotoolsに入門した

はじめに

Autotoolsで作られたリポジトリを見る機会があったので、理解のために自分で簡単なサンプルを作成して実行してみる。

(ところどころ説明を省いている箇所があるのでいずれ補足するかもしれない)

Autotools

Autotools (またはGNU build systemとも言う) とはautoconf、automake、libtool(もしくは他の関連ツール)の総称である。主にCやC++の開発者がUNIX系システム向けにソフトウェア(ソースコード)を配布するために使われる。OSごとにディレクトリ構成やビルドツールの違いがあるが、Autotoolsを使うことでソフトウェアの利用者は./configure && make && make installという共通のコマンドでビルド、インストールできる。

事前準備

以下のインストール

  • autoconf
  • automake
  • m4

Hello World!

AutotoolsでC言語で作られたプログラムのビルドと実行までをやる。

$ ls
main.c

main.cの中身は以下。

#include <stdio.h>

int main(int argc, char *argv[]) {
  printf("Hello World!\n");
  return 0;
}

autoconf

まずconfigureスクリプトを作成する。このスクリプトをソフトウェア利用者が実行することで、それぞれの環境に合わせたビルドやインストールのための設定がされる。

以下のコマンドを実行する。

$ autoscan
$ ls
autoscan.log
configure.scan
main.c
$ mv configure.scan configure.ac

autoscanによりconfigure.scanが作られる。autoscanconfigureスクリプトの入力として必要なconfigure.acを自動で作成するために実行する。

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

AC_PREREQ([2.71])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

FULL-PACKAGE-NAMEなどは自分の名前にする。configure.acm4というマクロプロセッサーで処理され、Bourne Shellスクリプトに変換される。例えばAC_CONFIG_SRCDIRは指定したファイルの存在を確認するマクロである。ではconfigure.acからconfigureを生成してみる。

$ autoconf
$ ls
autom4te.cache
autoscan.log
configure
configure.ac
main.c
$ ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether gcc accepts -g... yes
checking for gcc option to enable C11 features... none needed
configure: creating ./config.status
config.status: error: cannot find input file: `config.h.in'

config.h.inがないと怒られる。AC_CONFIG_HEADERSはconfigureスクリプト実行時にconfig.h.inという入力ファイルを読み込んでconfig.hを生成するマクロである。この入力ファイルが存在しないためにconfigure実行時にエラーが出る。これを生成するコマンドがautoheaderである。

$ autoheader
$ ls
autom4te.cache
autoscan.log
config.h.in
config.log
config.status
configure
configure.ac
main.c
$ cat config.h.in
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

再びautoconf && ./configureを実行すると成功する。

automake

Makefile.inを作成するautomakeを実行する。まずAutomakeが使うマクロをconfigure.acに記述する。

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

AC_PREREQ([2.71])
AC_INIT([sample], [0.01], [sample@example.com])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
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])
AC_OUTPUT

次にconfigure.acを読み込んでAutomakeが提供するマクロをインストールするaclocalを実行する。

$ aclocal
$ ls
aclocal.m4
autom4te.cache
config.h.in
config.log
configure
configure.ac
main.c

automakeの入力ファイルであるMakefile.amを作成する。

$ cat Makefile.am
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = helloworld
helloworld_SOURCES = main.c
$ automake --add-missing

ビルドと実行

$ mkdir ~/temp
$ ./configure --prefix ~/temp && make && make install
$ ~/temp/bin/helloworld
Hello World!

以上。

おわりに

MacOSで実行していたので、Dockerでubuntu上でビルド&実行しようとしたが、いくつかのシンボリックリンクを事前に置き換える必要があり面倒になって辞めた。

その他

バックアップを生成しない

autoconfを実行するとconfigure~というバックアップを生成するのを防ぐためにはSIMPLE_BACKUP_SUFFIXを空にして実行するといいよう。

$ SIMPLE_BACKUP_SUFFIX="" autoconf

関連ツール

Autotoolsはクロスコンパイルやパッケージ管理やビルドのためのツールではないが ソフトウェアのビルドを扱う点で関連ツールを挙げる。

  • Red Hat Package Manager
  • Debian Package
  • Homebrew
  • Ports
  • CMake
  • Bazel
  • Nix
  • AppImage
  • Flatpak
  • Snaps
  • Scrachbox