[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7. 프로그램과 라이브러리 build하기

Automake 기능의 많은 부분은 C 프로그램과 라이브러리를 쉽게 만들 수 있도록 하기 위한 것이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.1 프로그램을 build하기

(라이브러리에 대조되어) 프로그램으로 빌드되는 소스가 들어 있는 디렉토리에서, `PROGRAMS' primary가 사용된다. 프로그램은 `bindir', `sbindir', `libexecdir', `pkglibdir'에 설치되거나, 아예 설치되지 않을 수도 (`noinst') 있다.

예를 들어:

 
bin_PROGRAMS = hello

위의 간단한 경우에서, `Makefile.in'은 결과적으로 hello라는 이름의 프로그램을 만드는 코드를 갖게 될 것이다. hello_SOURCES 변수는 어떤 소스 파일이 실행 파일로 build될 것인지 알리는 데 쓰인다.

 
hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h 

위는 각 `.c' 파일이 대응되는 `.o' 파일로 컴파일되고, 그 다음에 링크되어 `hello'를 만들도록 한다.

`prog_SOURCES'가 필요한데 언급되지 않은 경우, 기본은 한개의 `prog.c' 파일이다. 위의 예에서, hello_SOURCES의 정의는 실제로는 필요없는 것이다.

한개의 디렉토리에서 여러개의 프로그램이 build될 수 있다. 여러개의 프로그램은 한개의 소스 파일을 공유할 수 있다. 그 소스 파일은 각각의 `_SOURCES' 정의에 열거되어야 한다.

`_SOURCES' 정의에 열거된 헤더 파일들은 배포본에 포함될 것이지만, 한편 무시될 것이다. 명백하지 않은 경우, `_SOURCES' 변수에 `configure'에 의해 만들어지는 헤더 파일을 포함해서는 안된다; 이 파일을 배포되는 것이 아니다. Lex(`.l')와 Yacc(`.y') 파일들 또한 열거될 수 있다; Yacc와 Lex 지원를 보라.

모든 상황에서 모든 파일이 빌드(build)되는 것이 아닐지라도, Automake는 프로그램에 들어갈 가능성이 있는 소스 파일으 ㄹ모두 알고 있어야 한다. 조건에 따라 빌드(build)되는 파일은 적절한 `EXTRA_'변수에 열거되야 한다. 예를 들어, `hello-linux.c'가 조건에 따라서 hello에 포함된다면, `Makefile.am'은 다음을 포함해야 한다:

 
EXTRA_hello_SOURCES = hello-linux.c

비슷하게, 때로는 configure시에 무엇이 빌드(build)될지 결정하는 것이 좋다. 예를 들어, GNU cpio는 특정 상황에서만 mtrmt를 빌드(build)한다.

이런 경우, automake는 build될 가능성이 있는 프로그램을 모두 알려줘야 한다. 하지만, 동시에 만들어질 `Makefile.in'configure가 명시하는 프로그램을 사용하도록 해야 한다. 이 일은 옵션으로 build되는 프로그램을 EXTRA_PROGRAMS에 적어주는 한편, 각 `_PROGRAMS' 정의에 configure 치환(substitute) 값을 적어주면 된다.

configure가 직접 찾지 않는 라이브러리와 링크해야 한다면, LDADD를 쓸 수 있다. 이 변수는 링커의 명령행에 어떤 옵션이라도 첨가하고 싶을때 사용할 수 있다.

가끔, 여러개의 프로그램이 한개의 디렉토리에서 build되면서 링크시에 필요한 것이 같지 않을 수 있다. 이 경우, global LDADD를 재정의하기 위해 `prog_LDADD' (PROG`_PROGRAMS' 변수 안에 나타나는 프로그램의 이름이고, 보통 소문자로만 쓰여진다) 변수를 사용한다. (만약 이 변수가 어떤 프로그램에 주어졌다면 그 프로그램은 LDADD를 써서 링크되지 않는다.)

예를 들어, GNU cpio에서, pax, cpio, 그리고 mt`libcpio.a' 라이브러리와 링크된다. 하지만, rmt는 같은 디렉토리에서 build되면서, 링크할때 그런 것이 필요없다. 또 mtrmt는 특정 architecture에서만 build된다. 여기 cpio의 `src/Makefile.am'이 있다 (요약):

 
bin_PROGRAMS = cpio pax @MT@
libexec_PROGRAMS = @RMT@
EXTRA_PROGRAMS = mt rmt

LDADD = ../lib/libcpio.a @INTLLIBS@
rmt_LDADD =

cpio_SOURCES = …
pax_SOURCES = …
mt_SOURCES = …
rmt_SOURCES = …

`prog_LDADD'는 프로그램에 관계된 링커 옵션(`-l'`-L'을 제외하고)을 넘겨주는 데는 부적합하다. 그래서 이런 목적으로는 `prog_LDFLAGS'를 사용한다.

때때로 그 프로그램의 일부가 아닌 어떤 다른 target에 의존하는 프로그램이 유용할 수 있다. 이렇게 하려면 `prog_DEPENDENCIES' 변수를 쓰면 된다. 각 프로그램은 이 변수의 내용에 의존하게 되지만, 그 이상의 해석은 하지 않는다.

`prog_DEPENDENCIES'가 제공되지 않으면, 이것은 Automake에 의해 결정된다. 자동으로 주어지는 값은 `prog_LDADD'의 내용에서 대부분의 configure 치환(substitution), `-l', 그리고 `-L' 옵션을 뺀 것이다. 남아 있게 되는 configure 치환(substitution)은 `@LIBOBJS@'`@ALLOCA@'뿐이다; 이 옵션들은 만들어지게 되는 `prog_DEPENDENCIES'에 잘못된 값이 들어가게 하지 않는다고 알려져 있기 때문에 남아 있는다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.2 라이브러리를 build하기

라이브러리를 build하는 것은 프로그램을 build하는 것과 많이 비슷하다. 이 경우, primary의 이름은 `LIBRARIES'이다. 라이브러리는 libdirpkglibdir에 설치될 수 있다.

`_LIBRARIES' 변수는 build될 라이브러리를 열거한 것이다. 예를 들어 `libcpio.a'라는 이름의 라이브러리를 만들고, 설치하지 않으려면, 다음과 같이 쓴다:

 
noinst_LIBRARIES = libcpio.a

라이브러리로 들어가게 되는 소스는 프로그램에서 하는 것과 마찬가지로 `_SOURCES' 변수를 통해 결정된다. 라이브러리의 이름은 규범화된다는 (see section 파생된 변수의 명명법) 것에 유의하자. 그래서 `liblob.a'에 대한 `_SOURCES' 변수는 `liblob_a_SOURCES'이지 `liblob.a_SOURCES'가 아니다.

`library_LIBADD' 변수를 사용해서 추가적으로 라이브러리에 object를 첨가할 수 있따. 이 변수는 configure에 의해 결정되는 object를 위해 사용된다. 다시 cpio의 경우:

 
libcpio_a_LIBADD = @LIBOBJS@ @ALLOCA@

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3 LIBOBJS and ALLOCA의 특별 처리

Automake는 자동으로 배포판에 (see section 배포판에 들어가는 것들) 소스 파일을 포함하기 위해 @LIBOBJS@@ALLOCA@의 사용을 외포적으로 알아내서, 그 정보와 `configure.in'에서 나온 LIBOBJS 파일의 목록을 활용한다. 이 소스 파일들은 자동으로 의존성 추적 방식에 제어될 것이다. See section 자동 의존성 추적를 보라.

@LIBOBJS@@ALLOCA@`_LDADD'`_LIBADD' 변수에게 특별히 인식될 것이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.4 동적 라이브러리(shared library) 만들기

동적 라이브러리(shared library)를 만드는 것은 비교적 복잡한 일이다. 이런 이유로, GNU Libtool (see (libtool)Top section `The Libtool Manual' in The Libtool Manual)이 플랫폼(platform)에 관계없이 동적 라이브러리(shared library)를 만들기 위해 작성되었다.

Automake는 `LTLIBRARIES' 주요변수를 정의해서 라이브러리를 만드는 데 Libtool을 쓴다. 각 `_LTLIBRARIES' 변수는 만들어야 할 동적 라이브러리(shared library)의 리스트이다. 예를 들어, `libgettext.a'와 이에 상대되는 동적 라이브러리(shared library)를 만들고, `libdir'에 설치하려면, 다음과 같이 쓴다:

 
lib_LTLIBRARIES = libgettext.la

동적 라이브러리(shared library)는 반드시 설치되야 하므로, `noinst_LTLIBRARIES'`check_LTLIBRARIES'변수는 사용할 수 없다.

각 라이브러리에 대해서, `library_LIBADD' 변수는 동적 라이브러리에 추가할 추가적인 libtool 오브젝트(object)의 이름을 담고 있다. `library_LDFLAGS' 변수는 `-version-info'`static'과 같은 그외 추가할 libtool 옵션을 담고 있다.

같은 디렉토리에 설치할 라이브러리에 대해서는, automake는 자동으로 적절한 `-rpath' 옵션을 추가한다. 하지만, configure 시에 결정해야 할 (즉 EXTRA_LTLIBRARIES에 언급되는) 라이브러리에 대해서는, automake는 결과적으로 설치할 디렉토리에 대해서 알지 못한다; 그런 디렉토리에서는 `-rpath' 옵션을 해당되는 `_LDFLAGS' 변수에 직접 추가해야 한다.

자세한 정보는 See Using Automake with Libtool: (libtool)Using Automake section `The Libtool Manual' in The Libtool Manual.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.5 프로그램을 build할때 쓰이는 변수들

때로는 어떤 `Makefile' 변수가 Automake가 컴파일을 위해 사용하는 것인지 아는 것이 유용하다; 예를 들어 어떤 특별한 경우에만 컴파일을 해야 할지도 모른다.

어떤 변수는 Autoconf에서 물려받는 것이다; 그것들은 CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, 그리고 LIBS이다.

Automake가 직접 추가로 정의하는 몇개 변수가 있다.

INCLUDES

`-I' 옵션들의 리스트이다. 이 변수는 특별히 들여다보고 싶은 디렉토리가 있으면 `Makefile.am'에 지정할 수 있다. automake는 이미 자동으로 몇개의 `-I' 옵션을 추가한다. 특히 automake`-I$(srcdir)'`config.h'가 들어 있는 디렉토리를 가리키는 `-I'를 만든다(만약 AC_CONFIG_HEADERAM_CONFIG_HEADER를 사용했다면).

실제로는 INCLUDES`-I' 외에 다른 cpp 옵션을 쓰고 싶을때 쓰인다. 예를 들어, 임의의 `-D' 옵션을 컴파일러에 넘겨주고 싶을 때 쓰인다.

COMPILE

이 변수는 C 소스 파일을 컴파일할때 실제로 사용될 명령이다. 파일이름은 이 완전한 명령행 뒤에 붙여진다.

LINK

이것은 실제 C 프로그램을 링크할때 쓰이는 명령이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6 Yacc와 Lex 지원

Automake는 좀 특이하게 Yacc와 Lex를 지원한다.

Automake는 yacc(또는 lex)에 의해 만들어진 `.c' 파일은 입력파일의 basename을 사용해서 이름지어진다고 가정한다. 즉, yacc 소스 파일 `foo.y'의 경우, automake는 중간 파일은 `foo.c'라는 이름(더 전통적인 이름인 `y.tab.c'가 아니라)으로 만들어 낸다.

yacc 소스 파일의 확장자는 `C' 혹은 `C++' 결과 파일의 확장자를 결정하는 데 ㅆ인다. `.y' 확장자를 가진 파일은 `.c' 파일이 된다; 마찬가지로, `samp.yy'`.cc'가 된다; `.y++'`c++'이 된다; `.yxx'`cxx'. 마찬가지로, lex 소스 파일은 `C' 혹은 `C++' 파일을 만드는 데 쓰인다; `.l', `.ll', `.l++', 그리고 `.lxx' 확장자를 알아본다.

어떤 `SOURCES' 변수에도 중간 파일(`C' 혹은 `C++')을 언급하면 안 된다; 오직 소스 파일만을 열거한다.

yacc(혹은 lex)가 만드는 중간 파일은 배포본을 만들때 포함된다. 그래서, 사용자는 yacc나 lex를 갖고 있을 필요가 없다.

yacc 소스 파일이 있으면, `configure.in'`YACC' 변수를 정의해야 한다. 이 작업은 `AC_PROG_YACC' 매크로를 실행시켜서 쉽게 할 수 있다.

비슷하게 lex 소스 파일이 있으면 `configure.in'`LEX' 변수를 정의해야 한다. 이것을 하기 위해 `AC_PROG_LEX'를 쓸 수 있다. Automake의 lex 지원을 위해서는 `AC_DECL_YYTEXT' 매크로도 사용해야 한다 - automake는 `LEX_OUTPUT_ROOT'의 값을 알 필요가 있다.

lex 소스 파일을 포함하는 어떤 프로그램이든 `@LEXLIB@'와 링크되야 한다. 이 작업은 적당한 `LDADD' 변수에 `@LEXLIB@'를 넣어서 할 수 있다.

Automake는 여러개의 yacc (또는 lex) 소스 파일을 한개의 프로그램에 포함할 수 있게 해 준다. Automake는 여러개의 yacc 실행간의 lock을 관리하기 위해 interlock이라는 작은 프로그램을 사용한다. yacc의 출력 파일이름은 고정되어 있고, 병렬로 make를 실행할 경우 여러 instance의 yacc를 동시에 실행할 수 있기 때문에 이 기능이 필요하다. interlock은 automake와 함께 배포된다. 이 프로그램은 `AC_CONFIG_AUX_DIR'에서 언급된 디렉토리에 있거나, 혹은 이 매크로가 `configure.in'에서 사용되지 않았다면 현재 디렉토리에 있어야 한다.

yacc에서는, 단순한 locking 관리는 충분하지 않다. yacc 출력은 내부적으로 항상 같은 symbol을 사용할 것이고, 두개의 yacc parser를 동일한 실행파일로 링크할 수 없다.

gdb에서 사용하고 있는 방법인 이름을 고치는 해킹(hack)을 추천한다:

 
#define	yymaxdepth c_maxdepth
#define	yyparse	c_parse
#define	yylex	c_lex
#define	yyerror	c_error
#define	yylval	c_lval
#define	yychar	c_char
#define	yydebug	c_debug
#define	yypact	c_pact	
#define	yyr1	c_r1			
#define	yyr2	c_r2			
#define	yydef	c_def		
#define	yychk	c_chk		
#define	yypgo	c_pgo		
#define	yyact	c_act		
#define	yyexca	c_exca
#define yyerrflag c_errflag
#define yynerrs	c_nerrs
#define	yyps	c_ps
#define	yypv	c_pv
#define	yys	c_s
#define	yy_yys	c_yys
#define	yystate	c_state
#define	yytmp	c_tmp
#define	yyv	c_v
#define	yy_yyv	c_yyv
#define	yyval	c_val
#define	yylloc	c_lloc
#define yyreds	c_reds
#define yytoks	c_toks
#define yylhs	c_yylhs
#define yylen	c_yylen
#define yydefred c_yydefred
#define yydgoto	c_yydgoto
#define yysindex c_yysindex
#define yyrindex c_yyrindex
#define yygindex c_yygindex
#define yytable	 c_yytable
#define yycheck	 c_yycheck

각 define에서 `c_' 접두어를 좋은대로 바꾸라. 이 define은 bison, byacc, 그리고 전통적인 yacc 버전에서 동작한다. 만약 여기 언급되지 않은 symbol을 사용하는 parser generator를 찾으면, 새로운 이름을 알려주면 그것은 리스트에 추가될 것이다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.7 C++과 그외 언어들

Automake는 C++에 대해서 완전히 지원하고, 다른 언어들에 대해서 기본적인 지원을 한다. 다른 언어들에 대한 지원은 요구에 따라서 향상될 것이다.

C++ 코드를 포함한 패키지는 `CXX' 변수를 `configure.in'에서 정의해야 한다; 이 작업을 하기 위한 가장 간단한 방법은 AC_PROG_CXX 매크로를 사용하는 것이다.

C++ 소스 파일이 있을때 몇개 변수가 추가로 정의된다.

CXX

C++ 컴파일러의 이름.

CXXFLAGS

C++ 컴파일러에 붙을 flag.

CXXCOMPILE

명령은 실제로 C++ 소스 파일을 컴파일할 때 쓰인다. 완전한 명령 행을 만들기 위해 파일 이름이 뒤에 붙여진다.

CXXLINK

이 명령은 실제로 C++ 프로그램을 링크할 때 쓰인다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.8 자동 ANSI문법 없애기

GNU 표준(GNU standards)는 ANSI C를 사용해도 된다고 하지만, 그렇게 하면, 몇몇 오래된 컴파일러(특히 SunOS)에 대해 호환성이 떨어질 것이다.

Automake에서는 그러한 기계에서 컴파일이 일어나기 전에 소스 파일에서`ANSI 문법 없애기(de-ANSI-fying)'로 이 문제를 해결할 수 있다.

`Makefile.am'의 변수인 AUTOMAKE_OPTIONS (Changing Automake's Behavior) 안에 ansi2knr 옵션이 들어 있다면 ANSI 문법을 없애는 것을 처리하는 코드는 만들어질 `Makefile.in'에 들어갈 것이다.

이 기능은 그 디렉토리에 들어 있는 각 C 소스 파일이 ANSI C로 취급되도록 한다. 만약 ANSI C 컴파일러를 사용할 수 있다면, 그것을 사용한다. 만약 ANSI C 컴파일러가 없다면, ansi2knr 프로그램이 소스 파일을 K&R C로 바꾸는 데 사용되고, 그 다음에 컴파일된다.

ansi2knr 프로그램은 한가지 생각만 한다. 이 프로그램은 소스 파일이 한가지 특정 방법으로 format되어 있을 것이라고 가정한다; 자세한 것은 ansi2knr man page를 보라. ansi2knr을 K&R C 소스에 대하여 실행시키면 컴파일 애러를 낼 것이다.

ANSI 문법을 없애는 지원은 소스 파일 `ansi2knr.c'`ansi2knr.1'이 ANSI C 소스와 같은 패키지에 있어야 한다; 이 파일들은 Automake와 함께 배포된다. 또한 패키지의 `configure.in'AM_C_PROTOTYPES 매크로를 실행해야 한다.

Automake는 현재 패키지 내의 다른 파일에 있는 ansi2knr 지원 파일들을 찾아내는 것도 해 준다. 이 기능은 ansi2knr 옵션에 적당한 디렉토리의 상대 path를 앞에 붙여주면 된다. 예를 들어 패키지의 `src'`lib' 서브디렉토리에 ANSI C 코드가 있다고 가정하자. `ansi2knr.c'`ansi2knr.1' 파일은 `lib'에 있다. 그러면 다음이 `src/Makefile.am'에 들어갈 수 있을 것이다:

 
AUTOMAKE_OPTIONS = ../lib/ansi2knr

어떤 디렉토리 접두어도 주어지지 않는다면, 파일들은 현재 디렉토리에 있다고 가정한다.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.9 자동 의존성 추적

개발자로서 프로젝트에서 include 파일의 의존성이 바뀔 때마다 `Makefile.in'을 계속 수정하는 것은 때론 고통스럽다. automake는 자동으로 의존성(dependency) 변화를 추척하는 방법을 제공하고, 만들어질 `Makefile.in'에 의존성(dependency)을 넣어 배포한다.

현재 이 지원은 GNU makegcc의 사용을 필요로 한다. 충분한 요구가 있다면, 미래에는 의존성을 만드는 또다른 프로그램을 제공할 수 있을지 모른다. 한편, 이 모드는 C 프로그램이나 라이브러리가 하나라도 정의되어 있다면 동작하기 때문에, GNU make가 아닌 경우에는 `Must be a separator' 애러가 날 수도 있다.

배포본을 만들기로 결정했을 때, dist target은 automake`--include-deps'와 다른 옵션들과 함께 다시 실행할 것이다. 이것은 전에 만들어진 의존성(dependency)이 만들어질 `Makefile.in'에 들어가도록 한다. 즉 배포판으로 들어가도록 한다. 이 과정은 배포본을 받는 사람이 GNU make를 사용할 필요가 없고, gcc가 애러를 내지 않도록 하기 위해서, 의존성(dependency)을 만드는 코드를 포함하지 않도록 한다.

`Makefile.in'에 추가되었을 때, 추가된 의존성은 시스템에 따른 의존성은 모두 자동으로 지워진 상태이다. 이 과정은 `OMIT_DEPENDENCIES'에 파일을 열거함으로써 가능하다. 예를 들어 시스템 헤더 파일에 대한 참조는 automake에 의해 지워진다. 때로는 특정 헤더 파일이 지우는 것을 명시하는 것이 유용하다. 예를 들어 `configure.in'`AM_WITH_REGEX'를 사용한다면, `rx.h'`regex.h'에 대한 의존성은 지워질 것이다. 왜냐하면 사용자가 패키지를 configure할 때까지는 맞는지 알 수 없기 때문이다.

사실, automake는 이 특별한 경우에 대해 처리할 수 있을 정도로 영리하다. `AM_GNU_GETTEXT'가 쓰이면 자동으로 `libintl.h'를 빼 주기도 할 것이다.

자동 의존성 추적은 no-dependenciesAUTOMAKE_OPTIONS 변수에 넣어서 없앨 수 있다.

make dist에 의해 만들어진 배포본을 풀고, 의존성 추적 코드를 다시 사용하고 싶다면, 단순히 automake를 다시 실행하면 된다.

실제로 사용되는 의존성 파일은 build 디렉토리 밑에 `.deps'라는 이름의 서브디렉토리 안에 넣어진다. 이 의존성은 machine에 따라 다르다. 그렇게 하고 싶다면, 이 파일들을 지워도 좋다; 이 파일들은 다음 build에서 자동으로 다시 만들어 질 것이다.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Autobuild on March, 29 2007 using texi2html 1.76.