1. GNU Autotools 소개
SW 를 개발하는데 있어 Source 를 편집하여 결과적으로 Executable Binary를 만들어야 하는데
작은 프로젝트의 경우 단순히 gcc 명령어를 통해 진행할 수 있지만 프로젝트가 커지다 보면 복잡도가 증가하여
사람 손으로 일일히 진행하기 어려워 진다.
이를 위해서 Build System 들이 생겨나게 되었고 그 중 하나인 GNU Autotools를 소개하고자 한다.
GNU Autotools 와 CMake가 가장 유명하다.
2. Autotools 구성
[Autotools 진행도]
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. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp mv -f .deps/main.Tpo .deps/main.Po g++ -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 |