XMLCPP 라이브러리를 만들면서 Autoconf에 대해 알게 되었습니다. 원래 Autoconf의 목적은 다양한 Unix-like 시스템에서 source code package가 컴파일될 수 있도록 해주는 shell-script들을 생성해주는 것입니다.
하지만 여러 Unix-like 시스템에서 사용할 계획이 없는 프로그램이라도 이를 사용하면 install/uninstall/dist/check 등의 다양한 장점을 얻을 수 있습니다. 특히 automake, libtool등과 같이 사용하면 Makefile도 간단히 만들 수 있고 .a나 .so등도 쉽게 관리가 가능합니다. 이번 글에서는 간단한 예제를 가지고 autoconf를 사용하는 방법을 소개합니다. 자세한 파일 내용들은 첨부 파일을 참고하세요. ((hello-10tar.gz))
다음과 같이 디렉토리와 파일들을 생성합니다. 생성하는 파일들은 GNU coding standards에서 요구하는 파일들입니다. ((만약 이 파일들이 필요없다면 automake에 --foreign 옵션을 줄 수 있습니다.))
다음과 같이 libtool 관련 파일들을 config 디렉토리에 cp 합니다.
이번 글에서는 간단한 Hello 클래스를 구현합니다. .h 파일은 include, .cpp 파일은 src 디렉토리에 생성합니다.
먼저 configure.ac 파일의 template 생성을 위해 autoscan 을 실행합니다. Autoscan은 하위 디렉토리들을 읽어들여 configure.scan 파일을 생성해 줍니다. 이 파일의 이름을 configure.ac로 mv 한 후 다음과 같이 수정합니다.
먼저 AC_INIT의 인자를 원하는 프로그램 명과 버전으로 변경합니다. 다음으로 AC_CONFIG_AUX_DIR에서 앞에서 생성한 config 디렉토리를 지정합니다. 다음으로 automake와 libtool을 위한 선언을 하고 AC_OUTPUT에 생성하고자 하는 Makefile들의 리스트를 넣습니다.
다음으로 각 디렉토리에 Makefile을 만들기 위한 Makefile.am 파일들을 생성합니다. 이 파일들은 automake에 의해 Makefile로 변환됩니다.
먼저 top 디렉토리에 다음과 같이 Makefile.am을 생성합니다.
top 디렉토리에서는 따로 install하거나 build할 파일이 없으므로 다음 sub-디렉토리들을 나열합니다.
다음으로 src 디렉토리에는 다음과 같이 Makefile.am을 생성합니다.
위와 같이 해주면 libtool이 configure 실행 옵션에 따라 .a와 .so를 생성해줍니다. (--enable-shared, --enable-static) 아무 옵션도 주지 않으면 둘 다 생성됩니다.
include 디렉토리의 Makefile.am은 다음과 같습니다.
마지막으로 tests 디렉토리의 것은 다음과 같습니다.
TESTS에 선언된 프로그램들은 make check시에 수행됩니다.
마지막으로 bootstrap 파일을 다음과 같이 작성합니다. 이 파일은 간단히 매번 타이핑해야 하는 수고를 줄이기 위해 사용합니다.
빌드하는 과정은 다음과 같이 간단합니다.
make check의 결과는 다음과 같이 출력됩니다.
그리고 make install후 /tmp 디렉토리에는 다음과 같은 파일들이 install 됩니다.
물론 make uninstall을 수행하면 install된 파일들이 모두 삭제됩니다.
마지막으로 이를 패키지로 꾸리기 위해 make dist를 사용할 수 있습니다. 패키지에 필요한 파일들을 모두 tar.gz으로 꾸려 줍니다. ((물론 configure.ac를 수정하여 gz2와 같이 다른 포맷으로 패키지를 꾸릴 수 있습니다. 첨부 파일 역시 make dist로 만들어진 패키지입니다.))
하지만 여러 Unix-like 시스템에서 사용할 계획이 없는 프로그램이라도 이를 사용하면 install/uninstall/dist/check 등의 다양한 장점을 얻을 수 있습니다. 특히 automake, libtool등과 같이 사용하면 Makefile도 간단히 만들 수 있고 .a나 .so등도 쉽게 관리가 가능합니다. 이번 글에서는 간단한 예제를 가지고 autoconf를 사용하는 방법을 소개합니다. 자세한 파일 내용들은 첨부 파일을 참고하세요. ((hello-10tar.gz))
Create directories & files
Create basic directories & files
다음과 같이 디렉토리와 파일들을 생성합니다. 생성하는 파일들은 GNU coding standards에서 요구하는 파일들입니다. ((만약 이 파일들이 필요없다면 automake에 --foreign 옵션을 줄 수 있습니다.))
$ mkdir config include src tests
$ touch INSTALL README AUTHORS ChangeLog COPYING NEWS
Copy libtool files
다음과 같이 libtool 관련 파일들을 config 디렉토리에 cp 합니다.
$ cd /usr/share/libtool 혹은 cd /usr/local/share/libtool
$ cp config.* lt* your/path/to/config/
Write source code files
이번 글에서는 간단한 Hello 클래스를 구현합니다. .h 파일은 include, .cpp 파일은 src 디렉토리에 생성합니다.
Create configure.ac file
먼저 configure.ac 파일의 template 생성을 위해 autoscan 을 실행합니다. Autoscan은 하위 디렉토리들을 읽어들여 configure.scan 파일을 생성해 줍니다. 이 파일의 이름을 configure.ac로 mv 한 후 다음과 같이 수정합니다.
5,6c5,7
< AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
< AC_CONFIG_SRCDIR([include/hello.h])
---
> AC_INIT(hello, [1.0], [your@email.com])
> AC_CONFIG_SRCDIR([src/hello.cpp])
> AC_CONFIG_AUX_DIR(config)
8a10,11
> AM_INIT_AUTOMAKE(hello, [1.0])
>
11a15
> AC_PROG_LIBTOOL
21c25
< AC_OUTPUT
---
> AC_OUTPUT(Makefile include/Makefile src/Makefile tests/Makefile)
먼저 AC_INIT의 인자를 원하는 프로그램 명과 버전으로 변경합니다. 다음으로 AC_CONFIG_AUX_DIR에서 앞에서 생성한 config 디렉토리를 지정합니다. 다음으로 automake와 libtool을 위한 선언을 하고 AC_OUTPUT에 생성하고자 하는 Makefile들의 리스트를 넣습니다.
Create Makefile.am files
다음으로 각 디렉토리에 Makefile을 만들기 위한 Makefile.am 파일들을 생성합니다. 이 파일들은 automake에 의해 Makefile로 변환됩니다.
먼저 top 디렉토리에 다음과 같이 Makefile.am을 생성합니다.
SUBDIRS = include src tests
top 디렉토리에서는 따로 install하거나 build할 파일이 없으므로 다음 sub-디렉토리들을 나열합니다.
다음으로 src 디렉토리에는 다음과 같이 Makefile.am을 생성합니다.
INCLUDES = -I$(top_srcdir)/include
lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = hello.cpp
위와 같이 해주면 libtool이 configure 실행 옵션에 따라 .a와 .so를 생성해줍니다. (--enable-shared, --enable-static) 아무 옵션도 주지 않으면 둘 다 생성됩니다.
include 디렉토리의 Makefile.am은 다음과 같습니다.
include_HEADERS = hello.h
마지막으로 tests 디렉토리의 것은 다음과 같습니다.
INCLUDES = -I$(top_srcdir)/include
TESTS = test1 test2
check_PROGRAMS = test1 test2
test1_SOURCES = test1.cpp
test1_LDADD = $(top_srcdir)/src/libhello.la
test2_SOURCES = test2.cpp
test2_LDADD = $(top_srcdir)/src/libhello.la
TESTS에 선언된 프로그램들은 make check시에 수행됩니다.
Create bootstrap file
마지막으로 bootstrap 파일을 다음과 같이 작성합니다. 이 파일은 간단히 매번 타이핑해야 하는 수고를 줄이기 위해 사용합니다.
#! /bin/sh
set -x
aclocal -I config
autoheader
automake --add-missing --copy
autoconf
Build
빌드하는 과정은 다음과 같이 간단합니다.
$ ./bootstrap
$ ./configure --prefix=/tmp
$ make
$ make check
$ make install
make check의 결과는 다음과 같이 출력됩니다.
PASS: test1
PASS: test2
==================
All 2 tests passed
==================
그리고 make install후 /tmp 디렉토리에는 다음과 같은 파일들이 install 됩니다.
$ ls include/ lib/
include/:
hello.h
lib/:
libhello-1.0.so.0 libhello-1.0.so.0.0.0 libhello.a
libhello.la libhello.so
물론 make uninstall을 수행하면 install된 파일들이 모두 삭제됩니다.
Etc
마지막으로 이를 패키지로 꾸리기 위해 make dist를 사용할 수 있습니다. 패키지에 필요한 파일들을 모두 tar.gz으로 꾸려 줍니다. ((물론 configure.ac를 수정하여 gz2와 같이 다른 포맷으로 패키지를 꾸릴 수 있습니다. 첨부 파일 역시 make dist로 만들어진 패키지입니다.))
autoconf, automake 너무 어려워보입니다. 예전부터 시도하다가 몇번을 포기했는지 모르겠어요.
ReplyDelete네. 생각보다 쉽지 않더라고요. 그래도 책을 빌려서 한번 읽고 나니 좀 낫더군요. 책에서 기본적인 내용을 보고, 필요한데 모르는게 있으면 검색하고 해서 간신히 성공했습니다. 제대로 하려면 m4 코딩까지 해서 필요한 check 함수들을 만들어야 하는데 검색해보니 대부분 필요한건 남들이 다 만들어놨더라고요. :-)
ReplyDelete처음엔 좀 어려워도 일단 좀 알고나니 편하긴 합니다. 그냥 makefile로 install, uninstall에 dist까지 만들려고 하면... 게다가 라이브러리 패키지인 경우에는 .a에 .so까지 만들어주니까요. :-)