Go to the first, previous, next, last section, table of contents.


관리자의 관점

패키지의 관리자는 많은 책임이 있다. 그 중의 한 가지는 그 패키지가 수많은 플랫폼에서 쉽게 설치될 것인지를 확인하고, 위에서 언급한 (see section 사용자의 관점) 마술들이 설치하는 사람과 최종 사용자들에게 동작하는지를 확인하는 것이다.

물론 GNU gettext를 배포본과 결합하는 방법은 매우 많고, 이 장은 일반적으로 이 경우들을 모두 다루지 않는다. 대신에 GNU 표준, 혹은 그보다 좋은 Gnits 표준을 따르는 많은 공개 소프트웨어에 특히 적합한 한 가지 접근방법에 대해 자세히 설명한다. 왜냐하면 GNU gettext는 전체 GNU 프로젝트와, 가능하다면 그 외의 공개 패키지들의 국제화를 돕는 것이 그 목적이기 때문이다. 그러므로 관리자의 관점에서는 모든 패키지에 `configure.in'이 있고, GNU Autoconf를 사용한다고 가정한다.

그렇지만, GNU gettext는 GNU 표준과 관습을 따르지 않는 공개 패키지들에게도 유용한 것이 사실이다. 하지만, 그러한 패키지들의 관리자들은 gettext가 그 상황에서 제대로 동작하도록 배포판을 어떻게 조직하는 데에 대한 생각하거나 의도할 필요가 없을 지도 모른다. 분명히, 울타리 바깥에도 많은 소프트웨어들이 있다.

gettext의 방법이 안정화되고 있다고 해도, 각각의 gettext 버전 사이에 약간 조정이 필요할 수 있다. 그러므로, 반드시 각 버전이 바뀔 때마다 가능하면 이 장의 내용을 다시 읽어야 하고, 변한 내용에 주의를 기울여야 한다.

플랫, 아니면 논 플랫 디렉토리 구조

몇몇 공개 소프트웨어들은 모든 파일이 한개의 디렉토리에 풀리는 tar 파일로 배포되고, 이러한 패키지를 플랫(flat) 배포판이라고 한다. 그 외의 공개 소프트웨어 패키지들은 한단계의 서브디렉토리구조를 가지고 있다. 예를 들어 Texinfo 안내서는 `doc/'이라는 서브디렉토리에 들어 있고, `lib/'에는 C 라이브러리를 대체하거나 보충하기 위한 함수들을 담고 있고, `src/'에는 그 패키지의 진짜 소스코드를 담고 있다. 이 배포본들을 논플랫(non-flat)이라고 한다.

플랫 배포본에 대해 많은 얘기를 할 수가 없다. 플랫 디렉토리 구조는 새로운 버전의 GNU gettext로 갱신하는 데에 너무 어렵다는 단점이 있다. 또, 만약 PO 파일이 많은 경우, 그 한개의 디렉토리를 어지럽힐 염려가 있다. 또, GNU gettext 배포본의 libintl 소스코드는 C 소스, 셸 스크립트, sed 스크립트와 복잡한 메이크파일 룰들이 들어 있는데, 이는 플랫 구조에서는 맞지 않는 것들이다. 이러한 이유로 논플랫 방식을 사용하기를 권한다.

아마도 GNU gettext 자체가 논플랫 구조라서 때문인지, 우리는 논플랫 구조에 더 많은 경험이 있고, 나머지 장에서 설명될 방법이다. 몇몇 관리자는 이 기회에 패키지 구조를 논플랫구조로 바꿀 지도 모른다.

미리 필요한 작업

GNU gettext를 패키지에 사용하기 위해서 준비해야 할 몇 가지 작업이 있다. 이 작업은 말하자면 이 장의 뒷부분에서 설명할 부분들을 위한 일반적인 작업이므로, 여기에서 설명한다.

PO 파일 제출에 대한 관리자의 이상적인 행동에 대해 몇 가지 첨가하고 싶다. 관리자로서의 역할은 그 제출물이 번역 프로젝트의 적절한 번역팀을 대표하는지 확인하는 것이고 (의심이 가면 그 제출물을 `translation@iro.umontreal.ca'로 보내주기 바란다), PO 파일 형식이 심각하게 위배되지 않았고, 성공적인 설치를 방해하지 않는지 확인하는 것이다. 그리고 나머지 일은 이 PO 파일들을 배포본의 `po/' 디렉토리에 넣는 것뿐이다.

관리자로써, 번역문이 적합하고, 완전한지 체크할 책임은 가질 필요가 없다. 그리고 언어적인 문제에 빠져들지 않도록 해야 한다. 번역 프로젝트의 번역 팀은 그 자체적으로 잘 동작하고 그들의 언어 선택에 있어서 번역팀에 책임이 있다. 번역 팀은 관리자에 의해 동작하는 것이 아니라는 사실을 명심하자. 사용자로부터 언어적인 문제에 대해 적절한 번역 팀으로 잘 알려줌으로써 번역 팀을 도울 수 있다. 또는 사용자에게 어떻게 그 번역팀에 연락하고 참여할 수 있는지 설명해서 번역 팀에 도움을 줄 수 있다. 가장 간단한 방법은 `ABOUT-NLS' 파일을 보내주는 것이다.

관리자는 절대 번역 팀을 무시한채 PO 파일의 버그 보고를 처리해서는 안 된다. 만약 어떤 번역자가 그 번역팀과 의견을 맞추기 어려웠다면, 그 번역자가 관리자와 번역문을 직접 무시했다는 것은 전혀 문제가 되지 않는다. 만약 무슨 문제가 있다면 그 팀이 그들의 문제를 해결해야 한다. 만약 당신이 관리자로서 어떤 번역팀에 문제가 있다고 생각한다고 해도, 절대로 당신이 그 팀의 문제를 해결하려고 하지 말라.

gettextize 프로그램 실행하기

몇 개의 파일은 GNU gettext를 사용해 국제화된 모든 패키지에서 공통적으로 필요하다. 편의를 위해, gettext 프로그램은 모든 파일을 당신의 패키지에 맞게 설치해 준다. 이 프로그램의 사용법은 다음과 같다:

gettextize [ option... ] [ directory ]

그리고 다음과 같은 옵션이 있다:

`-c'
`--copy'
심볼릭 링크를 만드는 대신에 필요한 파일들을 복사한다. 링크를 사용하면 패키지는 언제나 시스템에 설치된 최신의 gettext 코드를 사용할 수 있지만, 이렇게 하면 관리자가 소스에 적용하는 몇 가지 방법들을 방해할 수도 있다. gettextize를 실행하는 것은 쉬운 일이기 때문에 복사를 하는 데 문제가 발생하지는 없을 것이다.
`-f'
`--force'
이미 존재하는 파일을 덮어쓰도록 강제한다.
`-h'
`--help'
이 도움말을 출력하고 종료한다.
`--version'
버전 정보를 출력하고 종료한다.

만약 directory가 주어진다면, GNU gettext를 사용하려고 준비하는 패키지의 맨 위 디렉토리를 말한다. 만약 주어지지 않았다면 현재 디렉토리가 패키지의 맨 위 디렉토리라고 가정한다.

gettextize 프로그램은 다음 파일들을 제공한다. 하지만, 이미 존재하는 파일들은 --force(-f) 옵션이 지정되지 않는한 덮어쓰지 않을 것이다.

  1. `ABOUT-NLS' 파일이 패키지의 맨 위 디렉토리에 복사된다. 이 파일은 어떻게 고유어 지원 기능을 프로그램에 설치하고 사용하는 지에 대한 주요 안내문을 담고 있다. gettextize를 실행해서 보다 최신의 `ABOUT-NLS' 파일을 사용할 수 있다. 또, 더 최신의 `ABOUT-NLS'를 번역 프로젝트의 사이트와 대부분의 GNU 사이트에서 구할 수 있다.
  2. `po/' 디렉토리는 번역 파일을 담기 위해 만들어졌지만, 처음에는 GNU gettext 배포본에서 나온 `po/Makefile.in.in' 파일만을 가지고 있다 (파일 이름에 `.in'이 두번 있다는 것에 유의하자). 만약 `po/' 디렉토리가 이미 존재한다면, 그 안에 들어 있는 파일들과 함께 그 디렉토리는 그대로 보존될 것이다. 그리고 오직 `Makefile.in.in' 파일만이 덮어 씌워질 것이다.
  3. `intl/' 디렉토리는 본래 GNU gettext 배포본의 `intl/' 디렉토리에 들어 있는 파일들로 만들어진다. 또, 만약 --force(-f) 옵션이 주어진다면, `intl/' 디렉토리는 일단 깨끗이 지워질 것이다.

만약 시스템이 심볼릭 링크를 지원한다면, gettextize는 패키지로 파일들을 복사하지 않고, 대신에 심볼릭 링크만을 만든다. 이렇게 하면, 모든 패키지에 대해서 동일한 파일들로 디스크 공간을 낭비하는 일이 없어진다. 배포본의 tar 아카이브를 만들때 간단히 `-h' 옵션을 사용하면 배포본에 각 링크가 실제로 복사될 것이다. 즉, `Makefile.in'dist 타겟에서 tar의 옵션으로 반드시 `-h' 옵션을 사용해야 한다.

한 패키지내의 GNU gettext 기능들을 지원하기 위한 최신 파일들이 `intl/'`po/' 서브디렉토리로 들어간다는 사실은 재미있는 일이다. 이 두 디렉토리의 단 한 가지 차이점은 `intl/'은 GNU gettext를 사용하는 모든 패키지에서 완전히 동일하고, 새롭게 만들어진 파일들은 `po/' 디렉토리에 들어가고 각 패키지마다 다르다는 점이다. `po/' 디렉토리의 `Makefile.in.in'은 패키지마다 동일하다. 왜냐하면 `po/' 디렉토리는 그 디렉토리를 위해 만들어진 `Makefile'을 필요로 하고, 패키지마다 동일하도록 만들어졌다.

새롭게 만들거나 고쳐야 할 파일

gettextize를 통해 자동으로 첨가된 파일 이외에도, GNU gettext를 제대로 사용하기 위해 고쳐야 할 파일들이 많이 있다. 만약 메이크파일을 만들고, 자동으로 설정하는 데 있어 GNU standards를 충실히 따른다면, 이 작업은 더 쉬울 것이다. 여기에 각각을 위해 무엇을 바꿔야 하는지 쓰여 있다.

자, 여기에 파일의 리스트가 있다, 각각의 파일 다음에는 무엇을 고쳐야 하는지에 대한 설명이 있다. 맣은 예는 GNU gettext 0.10.39 배포본 자체에서 발췌되었다. 실제로 GNU gettext 패키지는 이 패키지의 기능을 사용하는 좋은 예이고, 이 기능의 주요 구현물이 되도록 만들어 졌으므로, GNU gettext의 소스코드를 참조할 수 있다.

`po/'`POTFILES.in' 파일

`po/' 디렉토리는 `POTFILES.in' 이라는 파일이 들어 있어야 한다. 이 파일은 프로그램 소스중에서 어느 파일이 번역 표시된 문자열이 들어 있는지를 알려준다. 여기에 이 파일의 예가 있다.:

# List of source files containing translatable strings.
# Copyright (C) 1995 Free Software Foundation, Inc.

# Common library files
lib/error.c
lib/getopt.c
lib/xmalloc.c

# Package source files
src/gettext.c
src/msgfmt.c
src/xgettext.c

해쉬(`#')로 시작되는 주석과 빈 줄은 무시된다. 다른 줄들은 번역하도록 표시해 놓은 문자열이 들어 있는 소스 파일을 열거해 놓은 것이고 (see section 소스 코드에서 어떻게 표시하는가), `POTFILE.in' 파일의 위치가 아니라, 전체 패키지의 맨 위 디렉토리에서부터의 상대 경로를 쓴다.

맨 위 디렉토리의 `configure.in'

  1. 패키지 이름과 버전을 알려준다. 다음과 같은 줄을 쓰면 된다:
    PACKAGE=gettext
    VERSION=0.10.39
    AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
    AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
    AC_SUBST(PACKAGE)
    AC_SUBST(VERSION)
    
    물론, `gettext'를 당신의 패키지 이름으로 바꾸고, `0.10.39'를 그 버전 번호로 바꾼다. 이 이름은 정확히 당신의 배포본이 tar 파일로 묶여질때 나타난다 (여기서는 `gettext-0.10.39.tar.gz'이 된다).
  2. 사용가능한 번역문을 선언한다. 여기서는, ALL_LINGUAS의 값으로 빈칸으로 구분하고 따옴표를 씌운 사용가능한 언어의 리스트를 한줄로 쓰면 된다.
    ALL_LINGUAS="de fr"
    
    이 예는 독일어와 불어 PO 파일이 사용가능하다는 뜻이므로, 이 언어들이 현재 이 패키지에서 지원된다. 만약 설치할 때 이 언어 메세지를 전부 설치하고 싶지 않다면, `configure.in'dml ALL_LINGUAS를 고쳐서는 안 되고, LINGUAS 환경 변수를 사용해냐 한다 (see section 설치하는 사람을 위한 마술).
  3. 국제화 지원을 체크한다. 국제화 기능을 켜는 주요 m4 매크로이다. 다음 줄을 `configure.in'에 첨가하라:
    AM_GNU_GETTEXT
    
    configure시에 이 매크로 때문에 수많은 체크를 하고 온갖 일들을 하지만, 이 매크로를 사용하는 건 매우 간단하다.
  4. 출력 파일을 만든다. `configure.in' 파일의 끝부분에 있는 AC_OUTPUT은 다음과 같이 수정되어야 한다:
    AC_OUTPUT([이미 있었던 config 파일들 intl/Makefile po/Makefile.in],
    [이미 있었던 action 들])
    
    AC_OUTPUT의 첫번재 인자를 고치는 것은 AC_OUTPUT`intl/'`po/' 디렉토리의 파일들을 치환하도록 한다. `.in'`po/' 디렉토리에만 사용된다는 것에 유의하자. 왜냐하면 배포되는 파일은 실제로는 `po/Makefile.in.in'이기 때문이다.

탑레벨의 `config.guess', `config.sub'

GNU `config.guess'`config.sub' 파일을 배포본에 추가해야 한다. `intl/' 디렉토리가 로케일의 문자 인코딩을 알아내는 데 플랫폼에 의존적인 기능들이 있으므로, 플랫폼이 무엇인지를 알아내는 데 이 파일들이 필요하다

`config.guess'`config.sub'의 최신 버전을 `ftp://ftp.gnu.org/pub/gnu/config/'에서 가져올 수 있다. 덜 최신의 버전들은 GNU automake와 GNU libtool 패키지에도 들어 있다.

보통, `config.guess'`config.sub' 파일들은 배포본의 맨 위 디렉토리에 들어 있다. 하지만 이 파일들을 `install-sh', `ltconfig', `ltmain.sh', `mkinstalldirs', `mission'과 같은 설정 관련 파일들과 함께 서브디렉토리에 넣는 것도 가능하다. 필요한 일은 파일들을 옮기는 것 이외에 다음 줄을 `configure.in'에 첨가하는 것이다.

AC_CONFIG_AUX_DIR([subdir])

맨 위 디렉토리의 `aclocal.m4'

만약 배포본에 `aclocal.m4' 파일이 없다면, 가장 간단한 방법은 GNU gettext`m4/' 디렉토리에서 `codeset.m4', `gettext.m4', `glibc21.m4', `iconv.m4', `isc-posix.m4', `lcmessage.m4', `progtest.m4'를 한 개의 파일로 연결하는 것이다.

이미 `aclocal.m4' 파일이 있다면, 앞에서 말한 매크로 파일들을 `aclocal.m4'에 합쳐 넣어야 한다. 만약에 이전 버전의 GNU gettext에서 업그레이드할 경우에는, 매크로들(AM_GNU_GETTEXT, AM_WITH_NLS 등)을 바꿔야 한다는 것에 유의하자. 이 매크로들은 GNU gettext의 버전마다 조금씩 다르다. 매크로들의 내용은 우리가 여러 가지 이상한 시스템들에 대한 경험을 쌓음에 따라 앞으로 달라질 수 있다.

이 매크로들은 국제화 지원 함수와 관련 정보들을 체크한다. 다행히도 일단 안정화되면, 이 매크로들은 어차피 GNU gettext를 사용하는 모든 프로젝트에서 똑같이 사용될 것이기 때문에, 기본 Autoconf 매크로로 합쳐질 수 있을 것이다.

맨 위 디렉토리의 `acconfig.h'

이전의 GNU gettext에서는 ENABLE_NLS, HAVE_GETTEXT 그리고 HAVE_LC_MESSAGES, HAVE_STPCPY, PACKAGE 그리고 VERSION`acconfig.h' 파일에 집어 넣어야 했다. 더이상 이럴 필요가 없다. 여러분의 패키지가 `intl/' 디렉토리와 독립적으로 동작하지 않는 한 `acconfig.h' 파일에서 이것들을 지워 버릴 수 있다.

맨 위 디렉토리의 `Makefile.in'

다음은 맨 위의 주요 `Makefile.in' 파일에 고쳐야 할 몇 가지 사항들이다.

  1. 다음 줄을 `Makefile.in'의 첫부분에 첨가하면, `dist:'는 제대로 동작할 것이다 (더 뒤에서 설명한다):
    PACKAGE = @PACKAGE@
    VERSION = @VERSION@
    
  2. `ABOUT-NLS' 파일을 DISTFILES 정의에 추가해, 이 파일이 같이 배포되도록 한다.
  3. `Makefile.in'에서 서브 디렉토리를 처리하는 모든 부분에 `intl'`po' 서브디렉토리도 처리하도록 한다. Makefile의 룰(rule)들은 국제화를 사용하지 않는 경우를 고려해서 만들어야 한다. automake로 만들어 내든 손으로 직접 작성하든 간에, Makefile을 사용하는 경우 GNU coding standards를 주의깊게 준수하도록 한다. 새로운 디렉토리가 처리되어야 하는 경우에 대해 바뀌는 부분은 `installdirs', `install', `uninstall', `clean', `distclean'이다. 다음은 디렉토리를 처리하는 순서의 예이다. 이 예에서는, Makefile.in에서 SUBDIRS 변수를 정의해서 나중에 `dist:' 타겟(target)에서 사용되록 하였다.
    SUBDIRS = doc intl lib src @POSUB@
    
    make가 libintl.h 헤더 파일을 사용하는 코드가 들어 있는 디렉토리들보다 먼저 intl 디렉토리로 내려가도록 해야 한다는 것에 유의한다. 이런 이유로 intllib이나 src보다 앞에 썼다. 이 방법을 당신의 패키지에 사용하도록 해야 할 것이다.
  4. 주의할 부분은 `dist:' 타겟인데, `intl/Makefile'`po/Makefile'은 나중에 적절한 디렉토리가 주요 `Makefile'에서 만들어져 있다고 가정하기 때문이다. 다음은 `dist:' 타겟을 작성하는 방법에 대한 예이다:
    distdir = $(PACKAGE)-$(VERSION)
    dist: Makefile
    	rm -fr $(distdir)
    	mkdir $(distdir)
    	chmod 777 $(distdir)
    	for file in $(DISTFILES); do \
    	  ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
    	done
    	for subdir in $(SUBDIRS); do \
    	  mkdir $(distdir)/$$subdir || exit 1; \
    	  chmod 777 $(distdir)/$$subdir; \
    	  (cd $$subdir && $(MAKE) $@) || exit 1; \
    	done
    	tar chozf $(distdir).tar.gz $(distdir)
    	rm -fr $(distdir)
    

`src'`Makefile.in'

주요 `Makefile.in'에 가해졌던 수정사항이 소스 디렉토리의 `Makefile.in'에도 필요하다. 이 디렉토리는 여기에서 `src/' 서브디렉토리라고 가정한다. 다음은 `src/Makefile.in'에 수정해야 할 것들의 리스트이다:

  1. `dist:' 타겟을 보면, `src/Makefile.in'의 처음 부분에 다음과 같은 줄을 첨가해야 한다:
    PACKAGE = @PACKAGE@
    VERSION = @VERSION@
    
  2. 이미 이렇게 되어 있으면, top_srcdir가 정의되어 있는지 확인한다. 이 이 변수는 cpp가 include하는 파일을 위해 사용될 것이다. 다음 줄을 첨가하면 된다.
    top_srcdir = @top_srcdir@
    
  3. `src'subdirs을 정의하면 모든 `Makefile.in'에 비슷하게 통일된 `dist:' 타겟(target)을 사용할 수 있다. 다음 리스트에서, 아래의 `dist:' 타겟(target)은 다음을 사용하고 있다고 가정한다:
    subdir = src
    
  4. 여러분 프로그램의 main 함수는 다음과 같이 bindtextdomain 함수를 불러야 한다 (see section gettext를 동작시키기):
    bindtextdomain (PACKAGE, LOCALEDIR);
    
    LOCALEDIR을 프로그램이 알도록 하려면 다음 줄을 Makefile.in에 넣는다:
    datadir = @datadir@
    localedir = $(datadir)/locale
    DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
    
    @datadir@ 기본값은 `$(prefix)/share'인 것에 유의한다. 그러므로 $(localedir)의 기본값은 `$(prefix)/share/locale'이 될 것이다.
  5. 마지막 링크 작업에서 @INTLLIBS@을 라이브러리로 사용하는지 확인한다. 쉬운 방법은 다음과 같이 LIBS에 첨가하는 것이다:
    LIBS = @INTLLIBS@ @LIBS@
    
    GNU gettext로 국제화된 대부분의 패키지에서, `lib/' 디렉토리 안에 몇 가지 보조 함수들이 들어 있는 것을 찾을 수 있을 것이다. (최소한 gettext 라이브러리 자체가 필요로 하는 몇 가지 함수는 필요하다.) 하지만 `libs/' 디렉토리의 몇몇 함수들은 역시 번역되어야 하는 메세지들을 담고 있다. 위의 예에서 이 보조 라이브러리(예를 들면 `libsupport.a')를 @INTLLIBS@@LIBS@ 사이에 넣으면 안 된다는 것에 유의하자. 대신에 다음과 같이 써야 한다.
    LIBS = ../lib/libsupport.a @INTLLIBS@ ../lib/libsupport.a @LIBS@
    
  6. `intl/' 디렉토리가 모든 경우에 대해 C 전처리기가 include할 파일을 찾는 디렉토리에 포함되어야 한다. 즉, `-I../intl'`-I$(top_srcdir)/intl'이 모두 C 컴파일러에게 주어져야 한다.
  7. `dist:' 타겟은 나머지와 잘 맞아야 한다. 다음은 제대로 정의하는 한 가지 방법이다:
    distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
    dist: Makefile $(DISTFILES)
    	for file in $(DISTFILES); do \
    	  ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
    	done
    


Go to the first, previous, next, last section, table of contents.