[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Automake 기능의 많은 부분은 C 프로그램과 라이브러리를 쉽게 만들 수 있도록 하기 위한 것이다.
7.1 프로그램을 build하기 | ||
7.2 라이브러리를 build하기 | ||
7.3 LIBOBJS and ALLOCA의 특별 처리 | ||
7.4 동적 라이브러리(shared library) 만들기 | ||
7.5 프로그램을 build할때 쓰이는 변수들 | ||
7.6 Yacc와 Lex 지원 | ||
7.7 C++과 그외 언어들 | ||
7.8 자동 ANSI문법 없애기 | ||
7.9 자동 의존성 추적 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(라이브러리에 대조되어) 프로그램으로 빌드되는 소스가 들어 있는 디렉토리에서, `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
는 특정 상황에서만 mt
와
rmt
를 빌드(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되면서, 링크할때 그런 것이 필요없다. 또 mt
와
rmt
는 특정 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] | [ ? ] |
라이브러리를 build하는 것은 프로그램을 build하는 것과 많이 비슷하다. 이
경우, primary의 이름은 `LIBRARIES'이다. 라이브러리는
libdir
나 pkglibdir
에 설치될 수 있다.
각 `_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] | [ ? ] |
Automake는
자동으로 배포판에 (see section 배포판에 들어가는 것들) 소스 파일을 포함하기 위해
@LIBOBJS@
와 @ALLOCA@
의 사용을 외포적으로
알아내서, 그 정보와 `configure.in'에서 나온 LIBOBJS
파일의
목록을 활용한다. 이 소스 파일들은 자동으로 의존성 추적 방식에 제어될
것이다. See section 자동 의존성 추적를 보라.
@LIBOBJS@
와 @ALLOCA@
는 `_LDADD'나 `_LIBADD'
변수에게 특별히 인식될 것이다.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
동적 라이브러리(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] | [ ? ] |
때로는 어떤 `Makefile' 변수가 Automake가 컴파일을 위해 사용하는 것인지 아는 것이 유용하다; 예를 들어 어떤 특별한 경우에만 컴파일을 해야 할지도 모른다.
어떤 변수는 Autoconf에서 물려받는 것이다; 그것들은 CC
,
CFLAGS
, CPPFLAGS
, DEFS
, LDFLAGS
, 그리고
LIBS
이다.
Automake가 직접 추가로 정의하는 몇개 변수가 있다.
INCLUDES
`-I' 옵션들의 리스트이다. 이 변수는 특별히 들여다보고 싶은
디렉토리가 있으면 `Makefile.am'에 지정할 수 있다.
automake
는 이미 자동으로 몇개의 `-I' 옵션을 추가한다. 특히
automake
는 `-I$(srcdir)'와 `config.h'가 들어 있는
디렉토리를 가리키는 `-I'를 만든다(만약 AC_CONFIG_HEADER
나
AM_CONFIG_HEADER
를 사용했다면).
실제로는 INCLUDES
는 `-I' 외에 다른 cpp
옵션을 쓰고
싶을때 쓰인다. 예를 들어, 임의의 `-D' 옵션을 컴파일러에 넘겨주고
싶을 때 쓰인다.
COMPILE
이 변수는 C 소스 파일을 컴파일할때 실제로 사용될 명령이다. 파일이름은 이 완전한 명령행 뒤에 붙여진다.
LINK
이것은 실제 C 프로그램을 링크할때 쓰이는 명령이다.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
Automake는 C++에 대해서 완전히 지원하고, 다른 언어들에 대해서 기본적인 지원을 한다. 다른 언어들에 대한 지원은 요구에 따라서 향상될 것이다.
C++ 코드를 포함한 패키지는 `CXX' 변수를 `configure.in'에서
정의해야 한다; 이 작업을 하기 위한 가장 간단한 방법은 AC_PROG_CXX
매크로를 사용하는 것이다.
C++ 소스 파일이 있을때 몇개 변수가 추가로 정의된다.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
개발자로서 프로젝트에서 include 파일의 의존성이 바뀔 때마다
`Makefile.in'을 계속 수정하는 것은 때론 고통스럽다.
automake
는 자동으로 의존성(dependency) 변화를 추척하는 방법을
제공하고, 만들어질 `Makefile.in'에 의존성(dependency)을 넣어
배포한다.
현재 이 지원은 GNU make
와 gcc
의 사용을 필요로 한다.
충분한 요구가 있다면, 미래에는 의존성을 만드는 또다른 프로그램을
제공할 수 있을지 모른다. 한편, 이 모드는 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-dependencies
를 AUTOMAKE_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.