반응형

$ ./autogen.sh 

./autogen.sh: 13: ./autogen.sh: autoreconf: not found


- install automake

$ sudo apt install automake

The following additional packages will be installed:

  autoconf autotools-dev libsigsegv2 m4

제안하는 패키지:

  autoconf-archive gnu-standards autoconf-doc libtool gettext m4-doc

다음 새 패키지를 설치할 것입니다:

  autoconf automake autotools-dev libsigsegv2 m4



출처 : GCC 완전정복 (에이콘. Kurt Wall, William von Hagen 지음. 김경현 옮김. 3만원 짜리책)

root@realg-desktop:~/test_CODE/C/struct_point# l
합계 24
drwxr-xr-x 2 realg realg 4096 2009-04-21 19:24 .
drwxr-xr-x 9 realg realg 4096 2009-04-08 16:40 ..
-rwxr-xr-x 1 realg realg 9146 2009-03-30 19:35 a.out
-rw-r--r-- 1 realg realg  373 2009-03-30 19:35 struct_point.c

autoscan 을 실행한다.

root@realg-desktop:~/test_CODE/C/struct_point# autoscan
root@realg-desktop:~/test_CODE/C/struct_point# l
합계 16
drwxr-xr-x 2 realg realg 4096 2009-04-21 19:24 .
drwxr-xr-x 9 realg realg 4096 2009-04-08 16:40 ..
-rw-r--r-- 1 root  root     0 2009-04-21 19:24 autoscan.log
-rw-r--r-- 1 root  root   534 2009-04-21 19:24 configure.scan
-rw-r--r-- 1 realg realg  373 2009-03-30 19:35 struct_point.c

configure.scan 과 autoscan.log 파일이 생겼다.

root@realg-desktop:~/test_CODE/C/struct_point# cat configure.scan
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([struct_point.c])
AC_CONFIG_HEADER([config.h]) 삭제

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([string.h])
AC_CONFIG_FILES([Makefile]) 추가

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CHECK_FUNCS([memset])

AC_OUTPUT
root@realg-desktop:~/test_CODE/C/struct_point#

configure.scan 의 내용이다.

AC_PREREQ : autoconf 버전 2.61패키지를 이용해서 이 autoconf 파일을 만들었다.
AC_INIT : 기본 autoconf 초기화 매크로 이다. autoconf를 이용해서 설정한 응용프로그램 패키지에 대해 사용자가 정의한 이름, 현재 설정된 패키지의 버전, 프로그램의 버그를 보고할 e-mail주소, 이렇게 세개의 인자가 필요하다.
AC_CONFIG_SRCDIR : 설정과 컴파일을 하기 위해서 소스 디렉토리에 있어야 하는 소스 파일의 이름을 인자로 하는 매크로이다. 원래 이 매크로는 autoconf가 제대로 동작하는가를 확인하기 위한 목적이다. 일반적으로 이 값은 설정하는 프로그램의 main루틴을 가지고 있는 파일의 이름이다.
AC_CONFIG_HEADER : 크로스 플랫폼이나 여러 플랫폼에 대한 설정 정보를 담고 있는 헤더 파일을 사용하고자 할 때 그것을 지정해주는 매크로이다. 이 설정 헤더 파일의 기본 이름은 config.h이다. 응용프로그램이 플랫폼의 특정 기능에 의존적이지 않다면, 이 항목을 지워도 된다. 이 기능을 사용하고자 할 때 지나치지 않게 하기 위해서 autoscan 스크립트가 이 값을 기본적으로 넣는다.
AC_PROG_CC : C컴파일러가 있는지 확인하는 매크로이다.
AC_HEADER_STDC : stdlib.h, stdarg.h string.h, float.h 헤더파일을 확인해서 ANSI C 헤더 파일이 있는지 확인하는 매크로이다.
AC_CHECK_HEADERS : stdio.h를 제외한 C 언어의 특정 헤더 파일이 있는지 확인하는 매크로이다.
AC_CONFIG_FILES autoconf가 템플릿 파일을 이용해서 지정된 파일을 만들도록 하는 매크로이다. autoconf 설정 파일에 있는 다른 매크로 구문에 기반해서 최대한 변수 치환을 수행한다. 기본적으로 템플릿 파일은 지정된 파일과 같은 이름(확장다는 .in이다.)을 갖는다. 생성할 파일의 이름을 콜론으로 구분해서 다른 템플릿 파일을 지정할 수 있다. 예를 들어 Makefile:foo.in은 foo.in템플릿 파일을 이용해서 Makefile파일을 생성하라는 것을 지정한다.
AC_OUTPUT : autoconf 프로그램이 config.status 셸 스크립트를 만들어서 그것을 실행하도록 하는 매크로이다. 보통 autoconf 설정 파일의 맨 마지막 매크로이다.


autoscan을 이용하여 템플릿 파일을 만들었다면, 이 파일을 autoconf의 기본 설정 파일인 configure.ac로 복사하거나 이름을 변경해야 한다.

root@realg-desktop:~/test_CODE/C/struct_point# l
합계 16
drwxr-xr-x 2 realg realg 4096 2009-04-21 19:24 .
drwxr-xr-x 9 realg realg 4096 2009-04-08 16:40 ..
-rw-r--r-- 1 root  root     0 2009-04-21 19:24 autoscan.log
-rw-r--r-- 1 root  root   534 2009-04-21 19:24 configure.scan
-rw-r--r-- 1 realg realg  373 2009-03-30 19:35 struct_point.c


root@realg-desktop:~/test_CODE/C/struct_point# mv configure.scan configure.ac
root@realg-desktop:~/test_CODE/C/struct_point# ls
autoscan.log  configure.ac  struct_point.c


root@realg-desktop:~/test_CODE/C/struct_point# autoconf
root@realg-desktop:~/test_CODE/C/struct_point# ls
autom4te.cache  autoscan.log  configure  configure.ac  struct_point.c

이렇게 하면 configure 스크립트와 autom4te.cache 라는 이름의 디렉토리가 만들어진다. 이 디렉토리에는 프로그램에 대한 캐시된 정보가 들어 있는데, autoconf 패키지에 있는 autom4te 프로그램(m4의 고 수준 레이어를 제공한다.)에서 이 정보를 사용한다.

이제 configure를 실행해보자

root@realg-desktop:~/test_CODE/C/struct_point# ./configure
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for string.h... (cached) yes
checking for memset... yes
configure: creating ./config.status
config.status: error: cannot find input file: Makefile.in


root@realg-desktop:~/test_CODE/C/struct_point# ls
autom4te.cache  autoscan.log  config.log  config.status  configure  configure.ac  struct_point.c

Makefile이 만들어지지 않았다.
왜냐? 에러났으니까.!
스크립트 파일인 Makefile.am 을 일단 만들고 그다음에 automake 프로그램이 Makefile.am을 좀더 강력하고 복잡한 Makefile.in으로 확장시킨다.


automake 사용 과정

1. 응용프로그램에 대한 Makefile.am 파일을 만든다.
2. 현재는 없지만 automake 프로그램을 설치할 때 함께 설치된 템플릿을 복사하기 위해 --addmissing command-line 옵션을 사용해서 automake 프로그램을 실행시킨다. 또한 이 과정은 직접 만들어야 하는 파일이 올바른지 확인한다.
3. 전 단계에서 확인한 파일들을 만든다.
4. 응용프로그램의 configure.ac파일에 AM_INIT_AUTOMAKE(program, version) 매크로를 응용프로그램에 맞게 수정해서 추가한다. 이 매크로는 configure.ac. 파일에서 AC_INIT 매크로 다음에 위치해야 한다.
5. AM_INIT_AUTOMAKE 매크로는 표준 autoconf 매크로가 아니라 automake 매크로이기 때문에 , autoconf에서 사용할 m4 매크로의 정의(AM_INIT_AUTOMAKE 매크로 정의 등을 가리킨다.)를 가진 지역 파일을 만들기 위해서 aclocal 스크립트를 실행시켜야 한다.
6. autoconf 프로그램을 다시 실행 시킨다.
7. automake 프로그램을 다시 실행시켜서 Makefile.am에서 완전한 Makefile.in 파일을 만든다.


configure.ac. 파일을 다음과 같이
AM_INIT_AUTOMAKE 라는 부분을 삽입하고 저장한다. 이것음 automake 에서 사용하는 매크로에 대한 초기화 구문이다.

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

AC_PREREQ(2.61)
AC_INIT(Testprogram, 1.0, hyb------@gmail.com)
AM_INIT_AUTOMAKE(Testprogram, 1.0)
AC_CONFIG_SRCDIR([struct_point.c])


# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([string.h])
AC_CONFIG_FILES([Makefile])
# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CHECK_FUNCS([memset])

AC_OUTPUT

automake.am 파일을 생성하고
기본적인 내용인 다음 두줄을 넣는다. (접두어는 Makefile을 만들때 사용된다.)

bin_PROGRAMS = Testprogram
Testprogram_SOURCES = struct_point.c

이렇게 하면

root@realg-desktop:~/test_CODE/C/struct_point# ls
autom4te.cache  automake.am  autoscan.log  config.log  config.status  configure  configure.ac  struct_point.c

위와 같은 파일이 남게 된다.

여기서 aclocal 명령어를 실행한다.

root@realg-desktop:~/test_CODE/C/struct_point# aclocal
root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      automake.am   config.log     configure     struct_point.c
autom4te.cache  autoscan.log  config.status  configure.ac


aclocal 명령을 실행하면 autoconf 매크로의 위치와 정의에 대한 정보를 모아서 aclocal.m4파일에 저장하게 된다.
(aclocal 스크립트는 configure.ac 파일에 AM_INIT_AUTOMAKE 매크로가 있을때에는 aclocal.m4 파일만을 생성한다. 그러나 AM_INIT_AUTOMAKE가 없으면 아무런 동작도 안하거나 실패한다. aclocal.m4가 생성되지 않는다면 configure.ac 에서 AM_INIT_AUTOMAKE 매크로를 선언했는지 확인해보기 바란다.)

드디어 다음으로 automake 프로그램을 실행한다.
automake --add-missing

root@realg-desktop:~/test_CODE/C/struct_point# automake --add-missing
configure.ac:6: installing `./install-sh'
configure.ac:6: installing `./missing'
automake: no `Makefile.am' found for any configure output
root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      automake.am   config.log     configure     install-sh  struct_point.c
autom4te.cache  autoscan.log  config.status  configure.ac  missing
root@realg-desktop:~/test_CODE/C/struct_point#

뭔가 잘못되었다. -_-;;;;;;;;

위에서 automake.ac 이 아니라 Makefile.ac 으로 만들었어야 했다.!!! ㅠ.ㅠ

파일명을 바꾸고 다시 도전해본다.

root@realg-desktop:~/test_CODE/C/struct_point# rm aclocal.m4 install-sh missing
root@realg-desktop:~/test_CODE/C/struct_point# mv automake.am Makefile.am
root@realg-desktop:~/test_CODE/C/struct_point# ls
autom4te.cache  autoscan.log  config.log  config.status  configure  configure.ac  Makefile.am  struct_point.c

root@realg-desktop:~/test_CODE/C/struct_point# aclocal
root@realg-desktop:~/test_CODE/C/struct_point# automake --add-missing
configure.ac:6: installing `./install-sh'
configure.ac:6: installing `./missing'
Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING'
Makefile.am: installing `./depcomp'
root@realg-desktop:~/test_CODE/C/struct_point# l
합계 220
drwxr-xr-x 3 realg realg   4096 2009-04-21 21:01 .
drwxr-xr-x 9 realg realg   4096 2009-04-08 16:40 ..
-rw-r--r-- 1 root  root   32230 2009-04-21 21:01 aclocal.m4
drwxr-xr-x 2 root  root    4096 2009-04-21 21:01 autom4te.cache
-rw-r--r-- 1 root  root       0 2009-04-21 20:01 autoscan.log
-rw-r--r-- 1 root  root   10225 2009-04-21 20:12 config.log
-rwxr-xr-x 1 root  root   20814 2009-04-21 20:12 config.status
-rwxr-xr-x 1 root  root  125035 2009-04-21 20:12 configure
-rwxr--r-- 1 root  root     559 2009-04-21 21:00 configure.ac
lrwxrwxrwx 1 root  root      32 2009-04-21 21:01 COPYING -> /usr/share/automake-1.10/COPYING
lrwxrwxrwx 1 root  root      32 2009-04-21 21:01 depcomp -> /usr/share/automake-1.10/depcomp
lrwxrwxrwx 1 root  root      32 2009-04-21 21:01 INSTALL -> /usr/share/automake-1.10/INSTALL
lrwxrwxrwx 1 root  root      35 2009-04-21 21:01 install-sh -> /usr/share/automake-1.10/install-sh
-rwxr--r-- 1 root  root      64 2009-04-21 21:00 Makefile.am
lrwxrwxrwx 1 root  root      32 2009-04-21 21:01 missing -> /usr/share/automake-1.10/missing
-rw-r--r-- 1 realg realg    373 2009-03-30 19:35 struct_point.c
root@realg-desktop:~/test_CODE/C/struct_point#

root@realg-desktop:~/test_CODE/C/struct_point# touch NEWS README AUTHORS ChangeLog
root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      autoscan.log  config.status  COPYING  install-sh   NEWS
AUTHORS         ChangeLog     configure      depcomp  Makefile.am  README
autom4te.cache  config.log    configure.ac   INSTALL  missing      struct_point.c
root@realg-desktop:~/test_CODE/C/struct_point# automake --add-missing
root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      autoscan.log  config.status  COPYING  install-sh   missing  struct_point.c
AUTHORS         ChangeLog     configure      depcomp  Makefile.am  NEWS
autom4te.cache  config.log    configure.ac   INSTALL  Makefile.in  README

Makefile.in 이 생겼다.

root@realg-desktop:~/test_CODE/C/struct_point# autoconf

root@realg-desktop:~/test_CODE/C/struct_point# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for string.h... (cached) yes
checking for memset... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
root@realg-desktop:~/test_CODE/C/struct_point#

root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      autoscan.log  config.status  COPYING  install-sh   Makefile.in  README
AUTHORS         ChangeLog     configure      depcomp  Makefile     missing      struct_point.c
autom4te.cache  config.log    configure.ac   INSTALL  Makefile.am  NEWS

Makefile 생겼다.


root@realg-desktop:~/test_CODE/C/struct_point# make
gcc -DPACKAGE_NAME=\"Testprogram\" -DPACKAGE_TARNAME=\"testprogram\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Testprogram\ 1.0\" -DPACKAGE_BUGREPORT=\"hyb------@gmail.com\" -DPACKAGE=\"Testprogram\" -DVERSION=\"1.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMSET=1 -I.     -g -O2 -MT struct_point.o -MD -MP -MF .deps/struct_point.Tpo -c -o struct_point.o struct_point.c
struct_point.c: In function ‘test’:
struct_point.c:12: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
struct_point.c: In function ‘main’:
struct_point.c:22: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
mv -f .deps/struct_point.Tpo .deps/struct_point.Po
gcc  -g -O2   -o Testprogram struct_point.o 
root@realg-desktop:~/test_CODE/C/struct_point# ls
aclocal.m4      autoscan.log  config.status  COPYING  install-sh   Makefile.in  README          Testprogram
AUTHORS         ChangeLog     configure      depcomp  Makefile     missing      struct_point.c
autom4te.cache  config.log    configure.ac   INSTALL  Makefile.am  NEWS         struct_point.o
root@realg-desktop:~/test_CODE/C/struct_point# ./Testprogram
adf


=0


== 0


==!! 0
root@realg-desktop:~/test_CODE/C/struct_point#


오~~~~~ 굿잡~!!!

ㅋㅋㅋ 잘된다.




다음 트리는 실제 autotools를 이용해서 작업하기 위해 사전에 입력해 둔 파일들 입니다. 즉 hello프로젝트에 필요한 파일들 입니다.

tifler@blackbox-home:~/Work/autotools-template$ tree
.
|-- Makefile.am
|-- autogen.sh
`-- src
    |-- Makefile.am
    `-- hello.c

1 directory, 4 files


Makefile.am
automake의 입력으로 들어 갑니다.

SUBDIRS=@DIRS@


autogen.sh
autotools를 편하게 쓰고자 만든 스크립트 입니다. 수동 입력하셔도 무방합니다.

#!/bin/sh
aclocal
autoheader
autoconf
automake --add-missing --copy


src/Makefile.am

bin_PROGRAMS = hello
linux_SOURCES = hello.c


src/hello.c

#include <stdio.h>

int main(int argc, char **argv)
{
        return printf("hello autotools\n");
}



필요한 모든 파일을 입력하셨으면, Autotools를 이용해서 프로젝트를 만들어 봅시다.

Step 1)
 autoscan을 이용해서 configure.scan을 만듭니다.

tifler@blackbox-home:~/Work/autotools-template$ ls
Makefile.am  autogen.sh  src
tifler@blackbox-home:~/Work/autotools-template$ autoscan 
tifler@blackbox-home:~/Work/autotools-template$ ls
Makefile.am  autogen.sh  autoscan.log  configure.scan  src
tifler@blackbox-home:~/Work/autotools-template$ 


빨간색으로 표시된 두개의 파일이 생성됩니다.
configure.scan

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

AC_PREREQ(2.61)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([src/hello.c])
AC_CONFIG_HEADER([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
                 src/Makefile])
AC_OUTPUT

autoscan.log 는 무시합니다.

Step 2) configure.scan을 이용하여 configure.ac를 만듭니다.

tifler@blackbox-home:~/Work/autotools-template$ cp configure.scan configure.ac
tifler@blackbox-home:~/Work/autotools-template$ vi configure.ac


다음과 같이 편집합니다.
configure.ac

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

AC_PREREQ(2.61)
AC_INIT(hello, 1.0, nungdo@gmail.com)
AM_INIT_AUTOMAKE(hello, 1.0)
AC_CONFIG_SRCDIR([src/hello.c])
AM_CONFIG_HEADER([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
                 src/Makefile])
AC_OUTPUT


Step 3) autogen.sh 수행에 앞서 몇개의 빈(empty) 파일을 만듭니다.

tifler@blackbox-home:~/Work/autotools-template$ touch NEWS
tifler@blackbox-home:~/Work/autotools-template$ touch README
tifler@blackbox-home:~/Work/autotools-template$ touch AUTHORS
tifler@blackbox-home:~/Work/autotools-template$ touch COPYING
tifler@blackbox-home:~/Work/autotools-template$ touch ChangeLog


Step 4) autogen.sh을 수행합니다.

tifler@blackbox-home:~/Work/autotools-template$ ./autogen.sh
configure.ac:6: installing `./install-sh'
configure.ac:6: installing `./missing'
src/Makefile.am: installing `./depcomp'
Makefile.am: installing `./INSTALL'
tifler@blackbox-home:~/Work/autotools-template$ ls
AUTHORS    Makefile.am  aclocal.m4      config.h.in     depcomp
COPYING    Makefile.in  autogen.sh      configure       install-sh
ChangeLog  NEWS         autom4te.cache  configure.ac    missing
INSTALL    README       autoscan.log    configure.scan  src


Step 5) configure를 실행합니다.

tifler@blackbox-home:~/Work/autotools-template$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands


Step 6-1) make를 수행합니다.

tifler@blackbox-home:~/Work/autotools-template$ make
make  all-recursive
make[1]: Entering directory `/home/tifler/Work/autotools-template'
Making all in src
make[2]: Entering directory `/home/tifler/Work/autotools-template/src'
gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.c
mv -f .deps/hello.Tpo .deps/hello.Po
gcc  -g -O2   -o hello hello.o  
make[2]: Leaving directory `/home/tifler/Work/autotools-template/src'
make[2]: Entering directory `/home/tifler/Work/autotools-template'
make[2]: `all-am'를 위해 할 일이 없습니다
make[2]: Leaving directory `/home/tifler/Work/autotools-template'
make[1]: Leaving directory `/home/tifler/Work/autotools-template'
tifler@blackbox-home:~/Work/autotools-template$ ls src
Makefile  Makefile.am  Makefile.in  hello  hello.c  hello.o


Step 6-2) make dist통해 배포본을 만듭니다.

tifler@blackbox-home:~/Work/autotools-template$ make dist
{ test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }
test -d hello-1.0 || mkdir hello-1.0
list='src'; for subdir in $list; do \
      if test "$subdir" = .; then :; else \
        test -d "hello-1.0/$subdir" \
        || /bin/mkdir -p "hello-1.0/$subdir" \
        || exit 1; \
        distdir=`CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0 && pwd`; \
        top_distdir=`CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0 && pwd`; \
        (cd $subdir && \
          make  \
            top_distdir="$top_distdir" \
            distdir="$distdir/$subdir" \
        am__remove_distdir=: \
        am__skip_length_check=: \
            distdir) \
          || exit 1; \
      fi; \
    done
make[1]: Entering directory `/home/tifler/Work/autotools-template/src'
make[1]: Leaving directory `/home/tifler/Work/autotools-template/src'
find hello-1.0 -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
      ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
      ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
      ! -type d ! -perm -444 -exec /bin/bash /home/tifler/Work/autotools-template/install-sh -c -m a+r {} {} \; \
    || chmod -R a+r hello-1.0
tardir=hello-1.0 && /bin/bash /home/tifler/Work/autotools-template/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
{ test ! -d hello-1.0 || { find hello-1.0 -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr hello-1.0; }; }
tifler@blackbox-home:~/Work/autotools-template$ ls

AUTHORS      Makefile.in     autoscan.log   configure.ac      src
COPYING      NEWS            config.h       configure.scan    stamp-h1
ChangeLog    README          config.h.in    depcomp
INSTALL      aclocal.m4      config.log     hello-1.0.tar.gz
Makefile     autogen.sh      config.status  install-sh
Makefile.am  autom4te.cache  configure      missing


이제 모든 작업이 끝났습니다.
자세한 사항은 autotools 문서를 참고하시기 바랍니다.






GNU Automake

버전 1.4, 31 May 1999

David MacKenzie and Tom Tromey
류창우 역



This document was generated on 13 July 2001 using texi2html 1.56k.



AUTOTOOLS 사용하기 (실행파일 만들기)

Makefile.am을 만든다

필요 내용들

다음 Makefile이 어디 있는지 알려준다. 즉 src/Makefile include/Makefile 을 부르는 역할을 한다.

SUBDIRS= src include

Include에 사용할 directory 명 나열

INCLUDES = -I$(srcdir)/include

bin_PROGRAMS라고 한 뒤에 프로그램명을 나열 하면 compile하면서 실행파일들을 만들어낸다.

bin_PROGRAMS = <프로그램명>
<프로그램명>_SOURCES= \
MAIN.cpp
<프로그램명>_LDADD= $(top_srcdir)/depend/lib/libgame.a -lpthread
<프로그램명>_LDFLAGS= -L$(top_srcdir)/depend/lib/

autoscan

  1. autoscan을 실행해서 configure.scan 를 만들고 이를 configure.ac로 rename 한다.
  2. AM_INIT_AUTOMAKE(<프로그램명>, 버젼) 을 AC_INIT 다음에 넣는다.

aclocal/autoheader

  1. aclocal 실행
  2. autohreader 실행

automake

  1. NEWS, ChangeLog?, README, AUTHORS 만든다.
    touch NEWS ChangeLog README AUTHORS
  2. automake -c -a 실행한다.

autoconf

  1. autoconf 실행

변경 사항 반영

  1. autoreconf 실행

AUTOTOOLS 사용하기 (라이브러리 만들기)

Makefile.am을 만든다

필요 내용들

다음 Makefile이 어디 있는지 알려준다. 즉 src/Makefile include/Makefile 을 부르는 역할을 한다.

SUBDIRS= src include

Include에 사용할 directory 명 나열

INCLUDES = -I$(srcdir)/include \
-I$(top_srcdir)/../core/depend/include/apr

lib_LIBRARIES라고 한 뒤에 프로그램명을 나열 하면 compile하면서 라이브러리를 만들어낸다.

lib_LIBRARIES = <라이브러리명>.a
<라이브러리명>_a_SOURCES= \
iglooTime.cpp
<라이브러리명>_a_LIBADD= $(top_srcdir)/../core/depend/lib/apr/libapr-1.a

autoscan

  1. autoscan을 실행해서 configure.scan 를 만들고 이를 configure.ac로 rename 한다.
  2. AM_INIT_AUTOMAKE(<프로그램명>, 버젼) 을 AC_INIT 다음에 넣는다.
  3. AM_PROG_LIBTOOL 을 그 다음에 넣는다.

libtoolize

  1. libtoolize --force 실행 (이미 파일이 있는 경우 에러를 내므로 덮어쓰기로 한다.)

aclocal/autoheader

  1. aclocal 실행
  2. autohreader 실행

automake

  1. NEWS, ChangeLog?, README, AUTHORS 만든다.
    touch NEWS ChangeLog README AUTHORS
  2. automake -c -a 실행한다.

autoconf

  1. autoconf 실행

변경 사항 반영

  1. autoreconf 실행

configure 실행

  • configure 실행 시 다음과 같은 에러가 나면, 해당 라인에 있는 '.'을 제거하고 저장하여 다시 실행한다.
     ../configure: line 19683: .: filename argument required

별도의 디렉토리에서 make 하기

  • 소스가 있는 디렉토리가 아닌 다른 디렉토리에 output(*.o, *.a, ...)을 내고자 할때
  1. 컴파일 하고자 하는 디렉토리를 만든다.
  2. 그 디렉토리로 이동한다.
  3. configure를 실행한다.
  4. make도 그 디렉토리에서 실행한다.
     예)
    * gamemanager/src 의 구조가 있으며, gamemanager/debug 내에 output 파일들을 넣고자 한다.
    * Makefile.am 은 src와 gamemanager에 있다.
    * 현재 있는 디렉토리가 gamemanager 라 하면,
    1. mkdir debug
    2. cd debug
    3. ../configure
    4. make

AUTOTOOLS Howto

autotools requirement

현재 contents 버젼

autoconf 2.53

automake 1.6

예젼 autoconf 에서는 입력값으로 configure.in 을 사용하였으나 .in 은 configure 의 입력값으로 사용되고 있기때문에 오해를 피하기 위해 현재는 configure.ac를 사용하게 되었다.

주로 *.in 파일들은 configure의 입력값으로 취급되고 있으며, 이 파일들이 configure 과정을 거쳐서 실제 원하는 파일이 된다. 예를 들어 script.in 이라는 파일은 configre 를 거쳐서 script 라는 파일이 될수있다.

따라서 이들과 configure.in 을 구분하기 위해 현재는 configure.ac 라고 부르게 되었다.

개요

1. configure.ac 에 Makefile 이 필요로 하는 사항들을 기록한다.

2. Makefile.am 에 이들 가변수를 사용하여 Makefile 의 초안을 작성한다.

3. configure 실행시에 configure.ac 에 지정한 항목들이 check 되면서 Makefile.am 에서 필요한 정보들이 유효한 값들로 치환된다.

4. Makefile.am 이 유효한 값들을 가지면서 Makefile 이 된다.

configure.ac

autoconf, automake 의 입력값

autoconf 는 이를 받아서 configure 파일을 만든다.

automake 는 이를 makefile.am 과 함께 받아 makefile.in 을 만든다.

보통 이미 지정된 macro 를 사용하여 원하는 정보를 얻거나 설정할수있다.

AC_CANONICAL_SYSTEM : 현재 시스템에 대한 정보를 가져온다. 

AC_PROG_CC : cc 가 사용가능한지를 check

AC_CHECK_HEADERS : 지정하는 header file 들이 시스템에 있는지 검사한다. HAVE_NAME_H 를 만들어준다.

AC_TYPE_ : 지정한 type definition 을 확인한다.

AC_SUBST : configure.ac 에서 사용한 변수들이 configure 시 *.in 파일에 지정한 변수를 찾아 유효값을 넣어준다.

AC_CONFIG_FILES : 생성될 파일들을 지정한다. 흔히 Makefile.

Makefile.am

automake 의 입력값

기본적인 Makefile 의 틀을 지니고 있지만, configure 에 따라 결정되는 변수들을 사용하고 있다.

Makefile.am 은 해당 소스를 컴파일 하고자 하는 위치면 어디든 놓이게 된다.

가장 상위 directory 의 Makefile.am 에는 컴파일할 하위 directory 를 정하게 된다.

configrure.ac 에서 정의되고 configure 를 통해 유효값들을 가지게 되는 변수를 가져오기 위해 @variable@ 을 사용한다. _PROGRAMS, _SCRIPTS, _SOURCES 등 지정된 primary 들이 있고 앞에 인스톨될 위치나 프로그램명, 프로그램의 소스등을 지정하게 되어있다.

   hello.c 의 Makefile.am

PFLAG = @PFLAG@ : configure 를 통해 알아낸 값 가져옴

bin_PROGRAMS = world : 컴파일후의 프로그래명 지정
world_SOURCES = hello.c : 해당 프로그램의 소스지정

AM_CFLAGS = $(PFLAG) : 컴파일시의 flag 지정 macro

how it works

아래 순서로 진행된다.

aclocal : configure.ac --> aclocal.m4

autoheader : configure.ac + aclocal.m4 --> config.h.in

autoconf : configure.ac + aclocal.m4 --> configure

automake : configure.ac + aclocal.m4 + Makefile.am --> Makefile.in

configure : Makefile.in --> Makefile

참고

autoconf,automake 를 실행하기 전에 이들을 보조하는 역할을 수행할 수 있는 것으로 aclocal, autoheader, autoscan이 있다.

aclocal

configure.ac 에서 지정하는 macro 에 대한 보조역할을 한다. 기본적으로 사용할 수 있는 macro 에 대한 정보를 제공한다.

autoheader

config.h.in 을 만들고 이는 후에 config.h 가 된다.

configure.ac 에서 지정된 확인 사항들에 대한 정보를 config.h 에 남기게 된다.예를 들어 dirent.h 라는 header file 이 있는지 없는지를 AC_CHECK_HEADERS 를 검사했다면 이는 config.h 에 #difine HAVE_DIRENT_H 1 로 정의된다.

config.h 는 configure 정보에 의존하는 함수나 header, 변수를 쓰는 곳에는 는 include 되어야 한다. 이를 통해 HAVE_NAME macro 를 써서 상황에 맞는 coding 을 해둠으로써 portable 한 code 를 만들수있게된다.

autoscan

configure.ac 의 초안이라 할수있는 configur.scan 을 만들어 준다. configure.ac 가 configure 를 만들어서 필요한 정보를 check 한다고 할때 모든 사항을 거의다 check 해주는 configure.scan 은 우효할수있으나 실제로는 필요한 기능만을 가지는 configure.ac 를 직접작성하는 것이 좋다고 생각된다. configure.scan 은 너무 복잡하다.더군다나 100% 신뢰 가능하다고 생각되지 않고있다.

간단한 예제 - minimal project

작은 예제를 통해서 autotool 을 사용하는 방법을 보이겠습니다.

흔히 가장 작은 예로 hello.c 를 autotool 을 이용하여 컴파일하고 install 하는 예를 많이 들어보이고 있는데 여기서는 이보다 조금 더 autoconf automake 의 능력을 발휘할 수 있는 예를 들어 보이겠습니다.

흔히 open source project 를 할때 현재 install 하고자 하는 machine 에 상관없이 configure, make, make install 을 통해서 간단하게 프로그램을 install 할수 있었는데 여기서는 이를 간단히 구현해보고자 합니다.더군다나 project 진행상 가장 기본적으로 필요한 기능입니다.

간단히 하기 위해 solaris 와 linux 에 대해서만 보이겠습니다.solaris 에서 실행될 파일과 linux 에서 실행될 파일이 필요합니다. 물론 같은 기능을 하는 파일로 같은 이름을 사용하여도 상관없습니다.

이들이 놓이게 될 장소와 이들을 가지고 원하는 작업을 수행하게 될 autotools 관련 파일들이 놓이게 될 위치를 아래에서 보이도록 하겠습니다.

소스의 위치

소 스들(solaris 에서 실행될 파일은 solaris.c 라 하고 linux 에서 실행될 파일을 linux.c 라고 하자.) 을 배치 할때는 운영체제 별로 directory 를 만들어서 관리하는 것이 좋다.(현재 가장 중요한 구분요소는 운영체제별로 build 가 이루어지게 하는 것이기 때문이기도 하다.) solaris.c 는 solaris directory 에 linux.c 는 linux directory 에 보관한다.

. project directory
./solaris/solaris.c
./linux/linux.c

project directory 에서 각각의 program source 들이 위치할수 있는곳은 바로 하나 아래의 dirctory 까지 이다. 즉 depth 1 의 directory 만 허용되며 그 이상의 깊이를 가지는 directory 안에 있는 소스에 대해서는 configure 로 Makefile 을 만들수 없어 실제로는 autoconf, automake 를 이용하기 위해서는 각 소스들은 depth 1 의 directory 에만 위치해야 한다. 이 문제는 automake 1.4 를 사용할 경우 고려되어야 하며 1.5 이후의 버젼에서는 이 문제가 해결되었다. 1.5 이상의 automake 를 사용하고 있다면 subdirectory 에 위치한 소스에 대해서도 makefile을 만들수 있고 subdirectory 의 파일을 상위 directory 에서 불러와 사용 할 수 있게 되었다.

autotools 입력 화일들의 위치

autoconf 의 입력화일인 configure.ac 는 project directory 에 위치하도록 한다. 즉 가장 상위 directry 에 위치하도록 하고 automake 의 입력파일이면서 configure 의 입력값이 될 Makefile.am 은 각각의 소스가 위치한 곳에 놓도록 한다. 이 Makefile.am 들이 각 소스에 대한 Makefile 이 된다고 생각할때 이 위치에 대한 이견은 없을것이다.

. project directory
./configure.ac
./Makefile.am

./solaris/solaris.c
./solaris/Makefile.am

./linux/linux.c
./linux/Makefile.am

이제 각 directory 에 위치한 configure.ac, Makefile.am 이 어떻게 작동하는 지 살펴보자.

최상위 directory 의 Makefile.am 의 역할

최상위 directory의 Makefile.am 은 configure 시 build 할 directory 를 판단한다. SUBDIRS 라는 변수를 가지고 있으며 여기에 지정된 directory 에 대해 Makefile.am 을 가지고 Makefile 을 만들게 된다. 우리는 configure 결과에 따라 시스템이 solaris 인지 linux 인지를 판단하여, solaris directory 를 build 할 것인 지 linux directory 를 build 할 것인지를 정해야 한다.즉 이 SUBDIRS 는 configure 시에야 알 수 있는 값이므로 일단 적당한 변수로 두고 configure 시 유효한 값으로 치환되도록 해야한다.

configure 시 build directory 를 결정하도록 하며 이 directory 의 값을 DIRS 라는 변수에 저장하도록 하고, 최상의 Makefile.am 에서는 이 값을 가져다 쓰기 위해 다음과 같이 쓰면 된다.

SUBDIRS=@DIRS@ 

이제 configure 에서 이 DIRS 값을 어떻게 결정하고 Makefile.am 에 넘겨주는지 보도록 한다.

configure.ac 의 역할

configure시에 많은 정보를 얻어야 하며 이를 바탕으로 Makefile이 만들어 진다고 할때 configure 시에 check 해야 할것들을 미리 정해주는 configure.ac 의 역할이 autotools 사용의 효용성을 결정한다고 할수도 있다. 각각의 check 사항들은 macro 로 정의되어 있으며 그에 대해서는 필요할경우마다 하나씩 찾아가면서 공부할수있다. 즉 하나의 macro 를 알고 모르는것이 그렇게 중요하지는 않으며 원하는 check 사항이 생길때마다 macro 를 조사하는 것으로도 가능하다.

이 번 예에서는 각 platform 별로 build 하기를 원하기 때문에 configure 시 현재의 platform 을 알아야 하고 이를 바탕으로 build 할 subdirectory, 즉 최상위 Makefile.am 에서 SUBDIRS 에 들어가게될 DIRS 의 값을 결정해 주어야 한다. 기본적인 여러 macro 들이 있겠지만 일단 이과정이 어떻게 처리되는지를 보자.

AC_CANONICAL_SYSTEM

case "$target" in
i?86-*-linux*)
DIRS="linux" ;
AC_SUBST(DIRS)
;;
*solaris*)
DIRS="solaris" ;
AC_SUBST(DIRS)
;;
*)
echo unsupported system : $target
;;
esac

AC_CANONICAL_SYSTEM 이라는 macro 를 통해서 target 이라는 shell 변수에 현재 system 의 정보를 기록하게 된다. 이 정보는 configuration name 형식으로 cpu-manufacturer-operation_system 으로 구성되며, 위의 case 문은 이를 바탕으로 쓰여졌다. 즉 AC_CANONICAL_SYSTEM 이라는 macro 의 실행결과 생긴 target 변수의 내용을 바탕으로 target 에 따른 행동을 할 수 있게 된다.

이 제 case 문 안으로 들어가면 DIRS 라는 변수에 linux 또는 solaris 를 assign 하고 이를 AC_SUBST() macro 를 통해 대치시키고 있다. 이 macro 는 parameter 로받은 변수에 대해 Makefile.am 이나 *.in 에서 이 변수명을 쓰는 값들을 현재 assign 한 값으로 대치시켜 준다. 이번 예제의 경우는 최상위 directory의 Makefile.am 에서 SUBDIRS=@DIRS@ 의 DIRS 의 값을 바꾸게 된다.

따라서 configure 를 거치게 되면 최상위 Makefile.am 의 SUBDIRS 에는 해당 머신에따라 linux 혹은 solaris 가 들어가게 된다. 편의상 현재 configure 가 일어나고 있는 머신을 linux 라고 할때 SUBDIRS=linux 가 되어서 make 를 하게 될 경우 이 Makefile (최상위 directory 의 Makefile.am 에서 만들어지는 Makefile) 에 의해 linux directory 만 빌드가 이루어 지게 된다. solaris directory 에 대한 빌드는 이루어지지 않으며 따라서 platform 을 따져서 원하는 source 를 빌드할수 있게 된다.

하부 directory 의 Makefile.am 의 역할

기본적인 사용을 위해서는 다음 두줄로도 춤분합니다.

./linux/Makefile.am

bin_PROGRAMS = linux
linux_SOURCES = linux.c

기본적으로 Makefile.am 에도 쓸수 있는 값들이 정해져 있다. _PROGRAMS, _SCRIPTS, _DATA, _SOURCES primry 들을 쓸 수 있는데 undersquare 앞에 특정 directory 를 정해 주어야 하는데 이 directory 가 해당 프로그램이나 파일들이 install 될 위치를 가르킨다. 위의 Makefile.am 에서는 linux.c 파일을 compile 해서 linux 라는 이름의 프로그램으로 만든후 이를 bin directory 에 install 하게 된다.

여기서 bin directory는 위의 configure.ac 에서 정의된 default prefix 아래의 bin directory 를 가르키게 된다. 즉, configure.ac 에서

AC_PREFIX_DEFAULT(/usr/eostk) 

라고 정의하였다면, 이 bin 은 /usr/eosrk/bin 이 되고 linux 프로그램은 그 아래에 install 된다.

_SCRIPTS 는 script 를 install 하기 위해 쓰이고 _DATA 는 그냥 파일들을 install 하게 될 경우에 쓰인다. 둘다 _SOURCES 를 필요로 하지 않기 때문에 비슷하나 _SCRIPTS 는 실행 가능하고 _DATA 는 실행불가능하기때문에 따로 쓰고 있다.

이 렇게 쓰여진 Makefile.am 은 configure 시 최상위 Makefile.am 에서 지정하는 SUBDIRS 에 포함될 경우만 build 가 이루어지는데 최상위 Makefile.am 처럼 지정된 변수가 있고 이를 configure.ac 에서 치환해 준다면 해당 유효값이 들어가서 Makefile 이 만들어 지게 된다.(실제로는 Makefile.am 은 automake 를 통해 Makefile.in 로 만들어지고 configure 시 이를 입력값으로 취해서 Makefile 이 만들어 진다.)

실행순서

위의 과정을 실행시키는 방법은 아래와 같다.

 aclocal
autoheader
autoconf
automake --add-missing -copy
./configure
make
make check
make install

흔 히 configure 전까지의 과정을 묶어서 bootstrap 또는 autogen.sh 라는 script 로 만들어서 한꺼번에 실행시킨다. end user 는 단지 ./configre, make, make install 만을 하면 특정 소스를 build 할 수 있는데 autogen.sh 를 end user 가 할수있어야 한다 없어야 한다는데에는 여러 의견이 있다.

요약과 전체 흐름 정리

지금까지 예제를 보면 최상위 Makefile.am 에 configure 시에 build 될 subdirectory 를 정하도록 하였으며 이 값을 알아내기 위해 configure.ac 에서 현 시스템을 검사하고 이 값을 넘겨주도록 되어있다. 즉 configure 실행후 make 를 하게 되면 최상위 Makefile 에 의해서 지정된 directory 만 build 가 이루어져 platform 에 따라 알맞는 소스가 build 되고 install 될 수 있다.

지금은 directory 단위로 특정 directory 를 build 할지 안할지를 결정하였지만 autotools 을 좀더 미시적은 범위에서 이용한다면 하나의 코드에 대해서도 define 문을 이용해서 선별적으로 코드가 build 되게 할 수 있다.

기본 template - configure.ac, Makefile.am

configure.ac, Makefile.am 을 작성할때 기본적으로 적어야하는 macro 등을 설명하겠다. 위의 전체 흐름을 이해했으면 지금부터의 사항들은 한번 읽고 지나쳐도 된다. 그러나 기본인 만큼 이대로 쓰지 않을경우 전혀 작동하지 않는다. --;

configure.ac

configure.ac 에서는 check 사항들을 test 하는 일반적인 순서가 정해져있다. 이 순서를 따르면서 필요한 사항들만 검사하면 된다. 대략적인 순서는

Boilerplate : 기본적인 macro. AC_INIT 이 있는데 이는 꼭 맨 앞에 쓰여져 있어야 한다. AM_INIT_AUTOMAKE, AC_CONFIG_HEADER, AC_REVISION 이 이에 속한다. 흔히 AC_INIT 과 AM_INIT_AUTOMAKE, AM_CONFIG_HEADER 는 꼭 들어간다.

Options

Programs : configure 과정이나 build 과정상에 필요한 프로그램들을 check 한다. AC_CHECK_PROG, AC_PATH_TOOL 이 있다.

Libraries

Headers : 필요한 header file 들이 존재하는지를 검사한다.

Typedefs and structures

Functions

Output

위의 항목들은 autoscan 을 통해서 configure.scan 이라는 파일을 생성하게 되면 그대로 나오게 된다. 이 autoscan 은 configure.ac 파일의 작성을 쉽게 해주고자 하는 도구이다. 허나 아주 자세한 것까지 출력을 해주고 필요없는 것들이 많기때문에 configure.ac 는 직접 작성하는것이 좋다고 생각된다. 간단히 예를 들어보면

# Process this file with autoconf to produce a configure script.
AC_INIT(eostk, 1.0, sylee@inzen.com)
AM_INIT_AUTOMAKE(eostk, 1.0)
AM_CONFIG_HEADER(config.h:config.h.in)

# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL

# Checks for libraries.
AC_CHECK_LIB(socket, connect)

# Checks for header files.
AC_HEADER_DIRENT

# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_TYPE_PID_T

# Checks for library functions.
AC_HEADER_STDC
AC_CHECK_FUNCS(strcpy bcopy)

# Finally, make output files
AC_CONFIG_FILES(
Makefile
solaris/Makefile
linux/Makefile
)
AC_OUTPUT

순이 될수있다. 이 순서대로 필요한 check 사항을 추가시킬수도 있고 필요없는것은 제외시킬수도 있다.configure 시에 모든 필요한 정보들이 수집된다고 할때 이의 초안이 되는 configure.ac 파일이 가장 중요하다고 할수있다.

Makefile.am

Makefile.am 의 기초는 위에서 설명한 것으로 충분하다고 생각한다. 추가적으로 알고있으면 좋은 사항들을 적어보면 check_ prefix 와 TESTS primary, install-exec-hook 이 있다.

check_ prefix, TESTS primary : 이들은 make check 으로 실행이 되는 파일들을 지정할수있다. 흔히 testsuit 이 이에 해당하는데 여기에 지정된 프로그램들은 실제로는 install 되지 않고 build time 에만 실행이 가능하다. 즉 make check 을 하면 TESTS 에 정의된 프로그램들을 찾아서 build 시켜서 실행시키게 된다. 이때 install 은 일어나지 않는다.

install-exec-hook target : make install 을 하면 흔히 지정된 동작이 일어나게 된다. build 가 끝난후 이를 지정한 directory 에 복사하거나 하는데 이를 마친후 추가적인 작업을 하고자 할 경우 install-exec-hook 에 그 행동을 지정해 주면 된다. 이를 install hook 이라고 한다.

check_PROGRAMS = test1
test1_SOURCES = test1.c

check_SCRIPTS = test2

TESTS = test1 \
test2


install-exec-hook :
chmod +x INSTALL.solaris
./INSTALL.solaris

이 렇게 하면 test1 이라는 c 프로그램과 test2 라는 script 가 make check 시 실행될 TESTS 파일로 지정이 되고 make check 이 불려지기 전까지는 build 되지 않는다. make check 이 불러지면 test1 이 빌드되고 test1 test2 순으로 실행된다. 그러나 install 은 되지 않는다.

install-exec-hook 이라는 target 은 make install 을 정상적으로 실행한후 실행된다. 현재 directory 가 solaris 라고 할때 solaris 의 make install 과정을 마친후에 실행이 된다. 이 후에 solaris2 라는 directory 를 빌드하게 되어있다 하더라도 이 과정은 해당 directory 의 install 을 마친후에 일어난다. 즉 solaris 의 make install 을 마친후에 이 과정이 실행된다. 그 후에 solaris2 를 build 하게 된다.

미시적 autotools 의 이용

이 문서는 multi platform 에서 해당 platform 에 맞는 build 를 하기 위한 howto 만을 제공하고 있다. 하지만 앞에서 잠깐 이야기했듯이 autotools 을 미시적인 범위까지 사용하면서, config.h 를 효과적으로 사용한다면 하나의 code 를 얼마든지 다르게 build 할 수 있다.

예를 들어 앞장의 configure.ac 를 볼때,

AC_CHECK_FUNCS(strcpy bcopy) 

라는 부분이 있다. 이 macro 를 실행하고 나면 config.h 에 현재 configure 가 일어난 system에 strcpy, bcopy 라는 함수가 있는지 없는지에 대한 기록이 남게 된다.따라서 개발자가 미리 혹시나 strcpy 나 bcopy 를 가지고 있지 않는 system에 대한 처리를 해줄수가 있다.

config.h 의 내용

#define HAVE_BCOPY 1 

strcpy 를 사용하는 code 시작 부분 혹은 그 code 가 include 하는 header file

#if !HAVE_STRCPY
# if HAVE_BCOPY
# define strcpy(dest,src) bcopy(src, dest, 1+strlen(src))
# else
error no strcpy or bcopy
# endif
#endif

위 처럼 하면 strcpy 를 가지고 있지 않은 machine 에 대해 이를 bcopy 를 이용해 구현할 수 있게 해줄 수 있다. 즉 작은 범위에까지 잘 이용한다면 완벽히 system independent 한 code 를 만들 수 있게된다.

참고자료

GNU AUTOCONF, AUTOMAKE, and LIBTOOL(-Gary V.Vaughan, Ben Elliston, Tom Tromey, and Ian Lance Taylor- New Riders) 이라는 책을 참고하였다. 이와 함께 http://www.gnu.org/manual 에 있는 autoconf, automake 를 간략히 보았다.

전체적으로 돌아가는 개념을 익히기 위해서는 위의 책이 좋고 기타 자세한 option 이나 macro 에 대해서는 gnu manual 을 찾아보면서 작업하는게 좋다고 생각 된다.. <--- 개인적인 생각입니다.


Libtool

개요

Libtool은 이미 컴파일이 완료된 함수의 모음이나 클래스와 메소드의 모음의 제작및 유지보수를 간단하게 해주는 오프소스 응용프로그램

현대 컴퓨터 시스템에서는 크게 세종류의 라이브러리를 사용.

  • 정적라이브러리(static library)
  • 공유라이브러리(shared library)
  • 동적적재라이브러리(dynamically loaded library)

정적라이브러리(static library)

  • 가장 오래되고 가장 간단한 형태의 코드 라이브러리
  • 링크되는 응용프로그램의 경우 마지막 실행 파일안에 라이브러리의 복사본이 포함
  • 확장자는 .a(archive) 또는 .sa(static archive)

장점

  • 항수 호출의 참조가 컴파일 과정에서 결정될수 있기때문에 사용하기 쉽다.
  • 라이브러리 안에 있는 함수의 주소는 하나로 정해져서 실행파일에서 그 주소를 사용할수 있다.
  • 응용프로그램 자체만으로 동작할수 있는 완전한 프로그램이 된다.
    • 의존성이 없다. 다른 컴퓨터에 옮겨도 정상 수행된다.
  • 수행 시간이 짧아진다.
    • shared/dynamically loaded library와는 달리 수행시간에 함수 또는 클래스의 참조를 결정하는 시간이 포함되지 않는다.
  • 실행시에 적은 양의 메모리를 요구한다.
    • 함수참조를 찾고 호출하는 실행환경 자체의 부하가 없다.

단점

  • 응용 프로그램 크기의 증가
    • 사용하는 함수만 추출해서 포함시킬수 없기때문에 전부 포함시켜야만 한다.
  • 라이브러리 수정시 응용 프로그램을 다시 컴파일 해야한다.
    • 컴파일 시간은 오래 걸린다.

공유라이브러리(shared library)

  • 1990년대 초에 썬 마이크로시스템즈 사에 의해 처음 소개
  • 중앙집중화된 코드 라이브러리
  • 응용 프로그램은 컴파일될 때가 아니라 프로그램이 실행될때 라이브러리를 로드하고 링크한다.
  • 공유 라이브러리를 사용하는 프로그램은 라이브러리 루틴에 대한 참조만 갖는다.
  • 확장자는 .so(shared object), Mac OS X시스템은 .dylib(dynamic shared library)
  • 명명규칙 (naming rule)
    • lib 라이브러리 이름 .so .공유 라이브러리의 버젼 번호 .배포버전 --- libc.so.2.9, libxmms.so.1.2.1
  • soname
    • lib 라이브러리 이름 .so 버젼 주번호 --- libc.so.2.9 -> libc.so.2, libxmms.so.1.2.1 -> libxmms.so.1
  • linker name
    • 버젼 번호를 제거한 soname --- libc.so.2.9 -> libc.so , libxmms.so.1.2.1 -> libxmms.so
  • 명명 규칙에 의해서 한 시스템에서 여러 버젼의 라이브러리를 설치할수 있게 해준다.
    • 이전 버젼의 결함 수정을 위해 배포 했다면 -- 배포버젼 증가.
    • 새로운 함수가 추가 되었지만 이전 버젼의 함수들은 동일한 인터페이스로 제공된다면 --- 소버젼 증가. 배포버젼은 처음부터
    • 함수의 인터페이스가 변하여 사용할수 없다면 - 주번호 갱신, 소번호, 배포버젼 처음부터

장점

  • 응용 프로그램의 유지 보수가 쉬움
    • 공유 라이브러리는 언제든지 수정이 가능하며, 버젼 정보를 사용함으로써 응용 프로그램이 "옮은" 버젼의 공유 라이브러리를 로드할수 있게 한다.
    • 버젼 정보로 인하여 응용 프로그램은 충돌 없이 라이브러리를 계속 사용할수 있다.
  • 시스템 디스크 공간 요구량 감소
    • 정적 라이브러리 이용 프로그램 보다 크기가 감소한다.
    • X windows System(GNOME, KDE, X 윈도우 매니져)의 예
  • 시스템 메모리 요구량 감소
    • 메모리에 한번 로드된 라이브러리는 그것을 참조하는 어떠한 응용프로그램에서도 사용이 가능하다.
    • 여러 프로그램들이 하나의 집중화된 공유 라이브러리에 동시에 접근할 수 있기때문에 하나 이상의 프로그램이 공유 라이브러리 사용시에 전체 메모리 사용량은 줄어든다.

단점

  • 응용 프로그램의 외부 환경 의존도가 높아진다.(의존도 있는 라이브러리를 알아내서 전부 설치해줘야한다.)
    • 다른 컴퓨터 시스템으로 옮기는 작업이 어려워진다.
    • ldd( list dynamic dependencies)
  • 약간의 성능 저하
    • 실행시에 해당 라이브러리 루틴을 라이브러리에서 찾는 시간 필요.
    • 라이브러리 로더
      • 공유 라이브러리의 참조를 결정.
      • 수행시간을 최소화 하기 위해서 공유 라이브러리의 위치 정보를 저장하는 캐시 유지 -- /lib/ld.so, /etc/ld.so.cache, ldconfig, /etc/ld.so.conf

동적적재라이브러리(dynamically loaded library)

  • 프로그램 실행시간에 모든 라이브러리를 무조건 로드하지 않고 언제라도 로드/참조 할수 있는 코드 라이브러리
  • 정적 라이브러리/공유 라이브러리 모두 동적 적재 라이브러리로 사용될수 있따.
  • <dlfcn.h> -> dlopen() -- DL 라이브러리를 열고 내용을 확인하고 오류를 처리하는 작업

장점

  • 함수의 로드에 의한 부하를 실제로 그 함수가 필요할때까지 뒤로 미룰수 있다.
  • 독립적으로 개발/유지/배포하기 쉽다.
  • 실행시간 전에는 어떤 라이브러리를 포함시켜야할지 알수 없는 경우에도 유용
  • 라이브러리 이름, 위치만 있으면 로드할수 있다. -- shared library와는 달리 찾는 시간이 없다.

Libtool


1. GNU Autotools 소개


SW 를 개발하는데 있어 Source 를 편집하여 결과적으로 Executable Binary를 만들어야 하는데

작은 프로젝트의 경우 단순히 gcc 명령어를 통해 진행할 수 있지만 프로젝트가 커지다 보면 복잡도가 증가하여

사람 손으로 일일히 진행하기 어려워 진다.

이를 위해서 Build System 들이 생겨나게 되었고 그 중 하나인 GNU Autotools를 소개하고자 한다.


GNU Autotools 와 CMake가 가장 유명하다.




2. Autotools 구성





[Autotools 진행도]

출처 : Wiki-GNU_Build_System






3. Autotools 사용법


3-1. 프로젝트 생성 및 Makefile.am 생성


Project Folder 생성과 hello.cpp Makefile.am을 생성한다.


1
2
3
4
dev@dev:~/work$ tree ./helloworld/
./helloworld/
├── main.cpp
└── Makefile.am
cs


각 파일의 내용은 아래와 같다.


main.cpp

1
2
3
4
5
6
7
#include <iostream>
 
int main()
{
    std::cout << "Hello World!" << std::endl;
    return 0;
}
cs


Makefile.am

1
2
3
bin_PROGRAMS = hello
 
hello_SOURCES = main.cpp
cs





3-2. autoscan


hello.cpp와 Makefile.am 이 있는 동일 Path 내에서 autoscan을 실행한다.

그러면 autoscan.log와 configure.scan 이라는 파일이 자동으로 생성된다.


1
2
3
4
5
6
7
8
9
dev@dev:~/work/helloworld$ autoscan
dev@dev:~/work/helloworld$ tree
.
├── autoscan.log
├── configure.scan
├── main.cpp
└── Makefile.am
 
0 directories, 4 files
cs


autoscan에 의해서 configure.scan 파일이 나왔으며 이를 configure.ac 로 rename 한다.





3-3. configure.ac 수정


configure.ac 를 열면 아래와 같이 나온다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
 
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADERS([config.h])
 
# Checks for programs.
AC_PROG_CXX
 
# Checks for libraries.
 
# Checks for header files.
 
# Checks for typedefs, structures, and compiler characteristics.
 
# Checks for library functions.
 
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
cs


AC_INIT의 1번째 인자는 프로젝트 이름, 1번째는 버전 정보를 채워 넣는다. (3번째는 Bug Report를 받을 E-Mail 주소)


추가로 아래와 같이 AM_INIT_AUTOMAKE, AC_PROG_CC 를 추가해 준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
 
AC_PREREQ([2.69])
AC_INIT([hello], [1.0], [foo@foo.com])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADERS([config.h])
 
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
 
# Checks for libraries.
 
# Checks for header files.
 
# Checks for typedefs, structures, and compiler characteristics.
 
# Checks for library functions.
 
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
cs





3-4. aclocal, autoheader, autoconf 실행


aclocal, autoheader, autoconf 커맨드를 실행하면 아래와 같이 프로젝트 내 파일이 늘어난다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
dev@dev:~/work/helloworld$ aclocal
dev@dev:~/work/helloworld$ autoheader
dev@dev:~/work/helloworld$ autoconf
dev@dev:~/work/helloworld$ tree
.
├── aclocal.m4
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── config.h.in
├── configure
├── configure.ac
├── main.cpp
└── Makefile.am
 
1 directory, 12 files
 
cs






3-5. automake 실행


아래와 같이 automake를 실행하여 Makefile.in 파일이 생성된다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
dev@dev:~/work/helloworld$ tree
.
├── aclocal.m4
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── compile
├── config.h.in
├── configure
├── configure.ac
├── depcomp
├── main.cpp
├── install-sh
├── Makefile.am
├── Makefile.in
└── missing
 
1 directory, 17 files
cs





3-6. configure and make


Build 하기 위한 사전작업은 전부 진행되었으며

이제 마지막으로 본격적인 Build를 위한 작업을 하면 된다.

configure 및 make를 하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
dev@dev:~/work/helloworld$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
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 we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
dev@dev:~/work/helloworld$ make
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash /home/dev/work/helloworld/missing autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-am
make[1]: Entering directory '/home/dev/work/helloworld'
g++ -DHAVE_CONFIG_H -I.     --O2 -MT main.o -MD -MP -MF .deps/main.Tpo --o main.o main.cpp
mv -f .deps/main.Tpo .deps/main.Po
g++  --O2   -o hello main.o  
make[1]: Leaving directory '/home/dev/work/helloworld'
 
cs





3-7. 결과


Output으로 나온 hello 라는 Executable Binary를 실행하면 아래와 같이 나온다.


1
2
dev@dev:~/work/helloworld$ ./hello 
Hello World!
cs



출처: https://wjs890204.tistory.com/1151 [J 창고]



출처 : http://egloos.zum.com/studyfoss/v/5343014

autoconf: 2.65
automake: 1.11.1
libtool: 2.2.6b
OS: ubuntu 10.04



autotools는 GNU 시스템에서 사용하는 빌드 도구로
기존의 make를 이용하기 위한 Makefile을 쉽고 이식성있게 작성하기 위한 기법이다.
하지만 그 사용법이 약간 복잡한 면이 있어서 익숙해지기가 쉽지 않은 면이 있다.
여기서는 C 언어로 작성된 작은 프로젝트에 autotools를 도입하여 사용하는 예제를 보이도록 한다.
(보다 복잡한 프로젝트에서 사용하기 위해서는 autotools의 설명서를 직접 참고하기 바란다.)

주의: 필자도 아직 autotools에 익숙하지 않기 때문에 의도하지 않게 잘못 설명된 부분이 있을 수 있다.
만약 그런 부분을 발견했다면 즉시 알려주시면 감사하겠다.

먼저 전체적인 진행 과정을 요약할 겸 나중에 찾아보기 편하도록 사용한 명령들 만을 적어보면 다음과 같다.
프로젝트의 소스 파일들은 모두 작성되어 있다고 가정한다.

Makefile.am 작성
$ autoscan
$ mv configure.scan configure.ac
configure.ac 수정
$ autoreconf -i
$ ./configure
$ make


실제로 필요한 작업은 Makefile.am 및 configure.ac 파일을 만든 후에 autoreconf를 수행하는 일이다.
(물론 이 파일들을 작성하는 것이 가장 힘든 일이다..;;)
지금부터 하나씩 천천히 살펴보도록 하자.

예제로 사용할 프로젝트는 "JUnit Test Inflected" 문서에서 사용한 예제와 비슷한 작업을 하는
money라는 이름의 프로젝트로 다음과 같은 인터페이스를 제공하는 라이브러리(libmoney)와
이를 이용하는 실행 파일로 구성되어 있다고 가정한다.

money.h:

#ifndef MONEY_H__
#define MONEY_H__

struct money {
  int amount;
  char *currency;
};

struct money * create_money(int, char *);
void destroy_money(struct money *);

int money_amount(struct money *);
char * money_currency(struct money *);

#endif /* MONEY_H__ */


소스 디렉터리의 구조는 다음과 같을 것이다.

$ tree
.
|-- lib
|   |-- money.c
|   `-- money.h
`-- src
    `-- main.c

2 directories, 3 files


이제 Makefile.am 파일을 만들어야 한다.
이 파일은 automake를 통해서 결국 (make가 이용하는) Makefile로 변경될 것이다.
최상위 디렉터리에서는 특별한 작업을 수행하지 않을 것이므로
이를 하위 디렉터리로 넘기기 위해 최상위 디렉터리의 Makefile.am에는 다음과 같은 내용 만을 포함한다.

Makefile.am:

SUBDIRS = lib src


이제 lib 디렉터리에도 Makefile.am 파일을 다음과 같이 만든다.

lib/Makefile.am:

lib_LTLIBRARIES = libmoney.la
libmoney_la_SOURCES = money.c


설명하기에 앞서 src 디렉터리의 Makefile.am 파일도 다음과 같이 만들어 준다.

src/Makefile.am:

bin_PROGRAMS = money
money_SOURCES = main.c
money_CPPFLAGS = -I$(top_srcdir)/lib
money_LDADD = $(builddir)/../lib/libmoney.la


Makefile.am 파일은 독특한 방식의 이름(uniform naming scheme)을 사용하는데
이는 각 파일들이 빌드되고 설치되는 방식을 포함하는 것이다.
첫 줄에 대문자로 표시된 (LT)LIBRARIES, PROGRAMS와 같은 이름을 primary라고 하며
그 앞에 붙은 bin_, lib_과 같은 prefix는 해당 파일이 설치될 디렉터리를 지정하며
뒤에 나오는 이름은 해당 파일의 실제 이름이다.

즉, libmoney.la는 ${prefix}/lib 디렉터리에 설치되는 라이브러리이며
money는 ${prefix}/bin 디렉터리에 설치되는 실행 프로그램이다.

먼저 lib 디렉터리에 있는 파일을 살펴보자.
위에서 설명했듯이 첫 번째 줄의 primary는 여기서 라이브러리를 빌드할 것임을 알려준다.
단, 우리는 libtool을 사용하여 라이브러리를 빌드할 것이므로 (따라서 확장자도 'la'이다)
일반적인 라이브러리를 나타내는 LIBRARIES라는 primary 대신
(앞에 libtool을 의미하는 'LT'가 붙은) LTLIBRARIES라는 primary를 이용하였다.
두 번째 줄은 libmoney.la 라이브러리를 구성하는 소스 파일이 어떤 것이 있는지 알려준다.
이것만으로 automake는 충분히 복잡한 Makefile을 만들어 줄 것이다.. ^^;

이제 src 디렉터리를 살펴보자.
첫 두 줄의 내용은 실행 파일임을 나타내는 PROGRAMS primary가 사용된 것 이외에는 별다른 차이가 없다.
그 아래의 내용은 컴파일 (정확히는 전처리) 시에 전달되는 플래그를 설정하는 것과
링크 시에 함께 링크할 파일(라이브러리)를 지정하는 부분이다.
여기서는 libmoney 라이브러리가 별도의 디렉터리(lib)에 빌드되어 있으므로
이런 복잡한(?) 부분이 필요하며 만일 모두 같은 디렉터리에 존재한다면 이 과정은 불필요하다.

여기서 주의할 부분은 lib 디렉터리의 경로를 지정하는 부분인데
기본적으로 프로그램을 빌드할 때 소스가 존재하는 위치와 빌드를 수행하는 위치가 다를 수 있다는 것을
염두에 두어야 한다. 이는 각각 $(srcdir) 및 $(builddir) 변수를 이용하여 지정할 수 있다.
이 변수들은 하위 디렉터리에서 사용하는 경우 자동으로 해당 디렉터리 위치를 추적하고 있기 때문에
src/Makefile.am에서는 'src'로, lib/Makefile.am에서는 'lib'으로 치환될 것이다.
이를 피하기 위해서 $(top_srcdir)와 $(top_builddir) 변수를 이용할 수 있으며
이는 항상 소스 및 빌드 디렉터리의 최상위 디렉터리의 이름으로 치환된다.

여기서 헤더 파일인 money.h는 항상 소스 디렉터리에 존재하므로 $(srcdir) 변수를 이용하였고
라이브러리 파일은 빌드 시에 동적으로 생성되기 때문에 $(builddir) 변수를 이용하였다.
또한 Makefile 자체도 빌드 시에 동적으로 생성되므로 $(builddir)은 '.'과 같으므로
위의 예제에서 다음과 같은 표현들은 결국 모두 같은 결과를 보여줄 것이다.

money_LDADD = $(top_builddir)/lib/libmoney.la
money_LDADD = $(builddir)/../lib/libmoney.la
money_LDADD = ../lib/libmoney.la


여기까지 Makefile.am 파일을 모두 작성하였다.
실질적으로 지금까지의 과정이 가장 복잡한 것이었으므로 희망을 가지고(?) 다음으로 넘어가자.
이제 필요한 것은 configure.ac 파일이다.
이 파일은 autoconf를 이용하여 configure 스크립트를 생성하는 것으로
사실 상 가장 복잡한 설정이 필요한 파일이지만 Makefile.am 파일처럼 처음부터 직접 다 작성하지 않고
autoscan을 이용하여 뼈대를 구성한 뒤 필요한 부분 만 추가/수정하면 된다.

최상위 디렉터리에서 autoscan 명령을 수행하면 configure.scan 파일이 생성된다.
이를 configure.ac로 복사하고 다음과 같이 수정하도록 하자.

$ diff -u configure.{scan,ac}
--- configure.scan    2010-06-22 22:15:35.981876209 +0900
+++ configure.ac      2010-06-22 22:16:45.320625690 +0900
@@ -2,12 +2,15 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.65])
-AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
+AC_INIT([money], [0.1], [namhyung@gmail.com])
 AC_CONFIG_SRCDIR([lib/money.h])
 AC_CONFIG_HEADERS([config.h])
 
+AM_INIT_AUTOMAKE([foreign])
+
 # Checks for programs.
 AC_PROG_CC
+AC_PROG_LIBTOOL
 
 # Checks for libraries.
 


이제 필요한 모든 준비가 끝났으므로 필요한 파일들을 생성하기 위해 autoreconf를 실행할 수 있다.
지금까지의 과정을 잘 따라왔다면 현재 디렉터리에는 다음과 같은 파일들이 존재할 것이다.

$ tree
.
|-- Makefile.am
|-- autoscan.log
|-- configure.ac
|-- configure.scan
|-- lib
|   |-- Makefile.am
|   |-- money.c
|   `-- money.h
`-- src
    |-- Makefile.am
    `-- main.c

2 directories, 9 files


여기서 autoscan.log와 configure.scan 파일은 더 이상 필요하지 않으므로 삭제해도 문제없다.
이제 autoreconf -i 명령을 수행하면 필요한 파일들을 모두 생성한다.
autoreconf는 이를 위해 필요한 aclocal, libtoolize, automake, autoconf 등의 명령을
자동으로 실행해 주기 때문에 예전과 같이 autogen.sh 혹은 bootstrap 스크립트를 작성할 필요가 없다.
-i (--install) 옵션은 여기서 필요한 부수적인 파일들을 설치하도록 해 준다.
우리는 configure.ac 파일에서 automake를 초기화할 때 strictness 옵션을 foreign으로 설정했기 때문에
README, INSTALL, COPYING, ChangeLog 등의 파일을 강제로 만들지 않는다.
그래도 많은 수의 파일들이 추가되었으며, 특히 Makefile.am에 대응하는 Makefile.in 파일이 생성되었다.

$ autoreconf -i
$ ls -F
Makefile.am  autom4te.cache/  config.h.in  configure.ac    install-sh*  missing*
Makefile.in  autoscan.log     config.sub*  configure.scan  lib/         src/
aclocal.m4   config.guess*    configure*   depcomp*        ltmain.sh*
$
$ find . -name Makefile.\*
./Makefile.in
./Makefile.am
./lib/Makefile.in
./lib/Makefile.am
./src/Makefile.in
./src/Makefile.am


참고로 configure.ac 파일 혹은 Makefile.am 파일이 변경된 후에는 다시 autoreconf를 호출해야 하며
autoreconf는 변경 사항에 맞추어 필요한 파일들을 새로 생성해 준다.
이 때는 새로 추가할 파일이 없으므로 -i 옵션은 제거할 수 있다.

이제 프로그램을 빌드하기 위한 모든 준비가 끝이 났다.
이렇게 준비된 소스는 일반적인 빌드 과정인 ./configure && make 명령을 수행할 수 있다.
이를 확인하기 위해 별도의 디렉터리를 만들어 빌드를 수행해 보도록 하자.
(원래의 디렉터리 이름은 source라고 가정하자.)

$ mkdir ../build
$ cd ../build
$ ../source/configure --prefix=${HOME}/tmp
$ make
$ make install
$ tree ~/tmp
/home/namhyung/tmp
|-- bin
|   `-- money
`-- lib
    |-- libmoney.a
    |-- libmoney.la
    |-- libmoney.so -> libmoney.so.0.0.0
    |-- libmoney.so.0 -> libmoney.so.0.0.0
    `-- libmoney.so.0.0.0

2 directories, 6 files


./configure && make && make install 명령까지 수행한 후 설치된 디렉터리를 확인해 보면
Makefile.am에 지정한 대로 bin 디렉터리에 money 프로그램이 설치되었고
lib 디렉터리에는 libmoney 라이브러리가 설치되었다.
libtool은 la 파일은 물론 static & shared library도 모두 빌드하므로 이들도 함께 설치되었음을 볼 수 있다.

이 외에도 clean, tags, dist, uninstall 등의 make target도 기본 제공되므로 유용하게 사용할 수 있다.

반응형

'Linux > Linux 일반' 카테고리의 다른 글

Libtool 사용하기  (0) 2009.04.21
ubuntu edgy server locale 변경  (0) 2009.04.21
myCortex-LM308의 makefile 분석  (0) 2009.03.12
Posted by Real_G