[ < ] | [ > ] | [ << ] | [ 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 October 25, 2015 using texi2html 1.82.