autotoolsオープンソースのライブラリ構成サンプル

autotoolsオープンソースのライブラリ構成

OSSとして公開されているソースコードをautotoolsプロジェクトに組み込み、ライブラリとして利用できるように設定します。

実行例として、C言語からJSON形式を扱うjson-cを用います。

json-cでライブラリを作成することは当然可能ですが、プラットフォームごとの移植作業が煩わしい場合に、プロジェクトへの組み込みを行うと効率的です。


プロジェクト構成

  • ヘッダーファイルをincludeにまとめ、ライブラリのソースコードをlibにまとめています。
  • ライブラリを利用する実行ファイルの作成はbinに作成します。下記例ではmain.cとなります。
  • COPYING(著作権情報)はlibに格納しています。

$ tree
.
├── Makefile.am
├── am.conf
├── autotools.sh
├── bin
│   ├── Makefile.am
│   └── main.c
├── configure.ac
├── include
│   ├── Makefile.am
│   └── json
│       ├── Makefile.am
│       ├── arraylist.h
│       ├── bits.h
│       ├── debug.h
│       ├── json.h
│       ├── json_object.h
│       ├── json_object_private.h
│       ├── json_tokener.h
│       ├── json_util.h
│       ├── linkhash.h
│       └── printbuf.h
└── lib
    ├── Makefile.am
    └── json
        ├── AUTHORS
        ├── COPYING
        ├── ChangeLog
        ├── Makefile.am
        ├── arraylist.c
        ├── debug.c
        ├── json.pc.in
        ├── json_object.c
        ├── json_tokener.c
        ├── json_util.c
        ├── linkhash.c
        ├── printbuf.c
        ├── test1.c
        ├── test2.c
        └── test3.c

bin/main.c

ライブラリを利用する実行ファイルのソースコードです。


#include <stdio.h>
#include "json.h"

int
main( int argc, char *argv[] )
{
    struct json_object *base = NULL;
    char *cp = NULL;

    base = json_object_new_object();
    json_object_object_add(base, "abc", json_object_new_int(12));
    json_object_object_add(base, "foo", json_object_new_string("bar")); 
    cp = json_object_to_json_string( base );
    fprintf( stdout, "%s\n", cp );

    json_object_put(base);
    return( 0 );
}


autotools構成ファイルの作成

下記ファイルを作成します。


./am.conf

automake用の設定ファイルとして、ヘッダーファイルやライブラリのパス情報を記載しています。


# automake configure

# header file include
INCLUDE_PATH=$(top_srcdir)/include
INCLUDES=-I$(top_srcdir)/include
INCJSON=-I$(INCLUDE_PATH)/json

# library file
LIB_PATH=$(top_srcdir)/lib
LIBJSON=$(LIB_PATH)/json/libjson.la

./Makefile.am

トップディレクトリのMakefile.amとなります。


#  Makefile.am
include $(top_srcdir)/am.conf

ACLOCAL_AMFLAGS = -I m4

SUBDIRS = include lib bin

bin/Makefile.am

main.cからライブラリを利用してsampleという実行ファイルを作成します。


include $(top_srcdir)/am.conf
bin_PROGRAMS = sample

sample_SOURCES = main.c
sample_CPPFLAGS = $(INCLUDES) $(INCJSON)
sample_LDADD    = $(LIBJSON)

include/Makefile.am

サブディレクトリの指定をします。


SUBDIRS = json

include/json/Makefile.am

ヘッダーファイルを記述します。


include $(top_srcdir)/am.conf

noinst_HEADERS = json.h json_tokener.h  printbuf.h \
                 arraylist.h  json_object.h json_util.h \
                 bits.h json_object_private.h  linkhash.h debug.h 

lib/Makefile.am

サブディレクトリの指定をします。


SUBDIRS = json

lib/json/Makefile.am

ライブラリのソースコードを記述します。


include $(top_srcdir)/am.conf
AM_CPPFLAGS = $(INCLUDES) $(INCJSON)

noinst_LTLIBRARIES = libjson.la
libjson_la_SOURCES = arraylist.c debug.c json_object.c json_tokener.c \
                     json_util.c linkhash.c printbuf.c

autotools実行

configure.acの作成

autoscanコマンドでconfigure.acのテンプレートを作成します。


$ autoscan
$ mv configure.scan configure.ac

autoscanコマンドによる自動生成後に、手動で設定しなければいけない作業は以下の通りです。

  • AC_INITにパッケージ名とバージョンと連絡先メールアドレスを記述します。
  • AM_INIT_AUTOMAKEマクロ(内容はパッケージ名とバージョン)を記述します。
  • libtoolを利用するために、「AM_PROG_LIBTOOL」を定義します。
  • libtoolizeコマンドが警告するため、「AC_CONFIG_MACRO_DIR([m4])」を定義します。
  • AM_PROG_CC_C_Oを定義します。
  • ヘッダーファイルが見つからないエラーとなるため「AC_CHECK_HEADERS([stdarg.h])」を定義します。
  • 関数が見つからないエラーとなるため、「AC_CHECK_FUNCS([vsnprintf])」「AC_CHECK_FUNCS([vasprintf])」を追記します。


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

AC_PREREQ([2.68])
AC_INIT([sample], [1.0], [mail@mail])
AM_INIT_AUTOMAKE([sample], [1.0])
AC_CONFIG_SRCDIR([bin/main.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])

# Checks for programs.
AC_PROG_CC
AM_PROG_LIBTOOL
AM_PROG_CC_C_O

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([fcntl.h limits.h stddef.h stdlib.h string.h strings.h sys/param.h syslog.h unistd.h])
AC_CHECK_HEADERS([stdarg.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
AC_CHECK_TYPES([ptrdiff_t])

# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset strchr strdup strerror strncasecmp strndup])
AC_CHECK_FUNCS([vsnprintf])
AC_CHECK_FUNCS([vasprintf])

AC_CONFIG_FILES([Makefile
                 bin/Makefile
                 include/Makefile
                 include/json/Makefile
                 lib/Makefile
                 lib/json/Makefile])
AC_OUTPUT

autotoolsスクリプトを作成します。

autotools関連コマンドをシェルスクリプトとしてまとめて記述します。


$ touch autotools.sh
$ chmod 755 autotools.sh

内容は下記の通りです。libtoolとして「glibtoolize」コマンドを使用しています。


$ cat autotools.sh
#!/bin/sh
touch INSTALL NEWS README COPYING AUTHORS ChangeLog
autoheader
glibtoolize --force
aclocal
automake --add-missing --copy
autoconf

コンパイル実行

ソースコードをコンパイルしてバイナリを作成します。


$ ./autotools.sh
$ ./configure
$ make

以上でライブラリと実行ファイルが生成されます。


$ bin/sample 
{ "abc": 12, "foo": "bar" }


関連ページ