본문 바로가기

도구의발견

우분투(Ubuntu) 패키지 만들기

ubuntu

리눅스(ubuntu)에서 서버 개발을 시작하면서 가장 귀찮은 것중에 하나는 개발환경 셋팅이었다. 서버 프레임워크에 boost, curl, json, mysql을 사용하고 있어서 새로 서버를 셋팅하거나 개발환경이 필요한 경우 매번 위 라이브러리들을 설치하는 작업을 해야 했고, 이게 자주 있는 일이 아니다 보니 할때 마다 뭘 설치해야 할지 까먹어 매번 새로운 작업 처럼 느껴졌다(그리고 빌드 과정 또한 복잡했다).

그래서 이 일련의 반복되는 작업들을 쉽게 할수 있는 방법이 없을까 찾아 보던 중 '패키징'이라는 것을 알게 되었고 필요한 라이브러리들 미리 빌드하여 바이너리 형태의 패키지로 묶어 한번에 설치할 수 있도록 하니, 개발환경을 새로 셋팅할 때 마다 몇 시간씩 들던 노력이 몇 분으로 줄어 들었다.

자, 이제 부터 패키지를 만드는 방법에 대해서 알아보자. 

0. 들어가기 전에..

Ubuntu 리눅스(:12)는 Debian GNU/Linux 배포판을 기반으로하는 운영체제(:12)입니다. 배포판에 대한 구분은 대게가 패키징 관리시스템에 따라 달라집니다. 예를 들어 CentOS나 Fedora는 RedHat 계열 운영체제로 분류를 하는데, 이들은 RPM 패키징 시스템을 이용하고 있습니다. 데비안 계열은 독자적인 deb 패키징 시스템을 가집니다. 확장자도 .deb 이고요.데비안을 기반으로 하는 Ubuntu 역시 deb 패키징 시스템을 사용합니다.
from. JoinC - 리눅스 패키지 관리

위에 인용된 글 처럼 Ubuntu에서는 데비안 패키징 시스템을 사용한다. 우리가 지금 부터 알아볼 방법은 RPM아니라 deb 시스템이다. 그리고 설명을 쉽게하기 위해 'pkg-build-essential'이라는 개발환경 라이브러리 설치용 패키지를 만든다고 가정하자.

1. 패키지 디렉토리 생성

우선 패키징이 될 디렉토리를 생성한다. 이 디렉토리의 이름을 'pkg-build-essential'라고 한다. 이 디렉토리 밑에 두개의 하위 디렉토리를 만들어야 하는데 하나의 이름은 무조건 DEBIAN이다. 이 디렉토리에는 뒤에 설명될 control, preinst, postinst 등의 설정, 의존성, 버젼 관련 정보들이 들어가는 디렉토리이다.

그리고 usr 디렉토리를 만들것인데 이 부분은 실제 root 디렉토리 밑에 생성(or 복사) 될 디렉토리다. 이 예에서는 /usr/local 밑에 모든 라이브러리들을 설치할 것이기 때문에 /usr 라는 디렉토리를 생성했지만 각자가 필요한대로 만들어도 된다(DEBIAN이 아닌 여러 디렉토리를 만들었을때 그것이 모두 반영되는지는 모르겠다)

$ mkdir pkg-build-essential
$ mkdir pkg-build-essential/DEBIAN
$ mkdir pkg-build-essential/usr

2. control 파일 작성

control 파일은 의존성, 버젼, 이름, 설명 등등 패키지의 전반적인 정보를 담고 있는 파일이다. control 파일은 위에서 생성한 DEBIAN 디렉토리 밑에 위치하며 패키지에 관련된 각종 정보를 담고 있다. 각 항목은 "태그: 내용" 형식으로 구성 되며 각 태그는 줄바꿈으로 구분된다. 예를 들어 패키지 이름을 적는다고 하면 'Package: pkg-build-essential' 가 되겠다. 그리고 여러 줄에 걸쳐 내용을 적어야 할 때는 두번째 줄부터 tab이나 space같은 공백 문자가 라인의 가장 앞에 있어야 한다.

  • control 파일 예 :
Package: pkg-build-essential
Version: 1.3.4
Section: devel
Priority: optional
Architecture: all
Depends: build-essential, subversion, openjdk-7-jdk, libmysqlclient-dev, libmysql++-dev,
 libcurl4-openssl-dev,libjson0, libjson0-dev, libjsoncpp0, libjsoncpp-dev, python-twisted-core, 
 flex, cmake
Recommends: libjson0-dbg, python-mysqldb
Maintainer: Developers <kukuta@gmail.com>
Homepage: http://kukuta.tistory.com
Description: Server Development base library install package
 1.0.1 : bug fetch..#1
 1.1.1 : bug fetch..#2
 1.2.0 : bug fetch..#3

주요 항목들에 대해 간략한 설명을 하면, Package는 패키지의 이름을 , Version은 동일한 이름의 패키지가 설치되어 있는 경우 버젼이 높을 때만 설치를 한다. 그외 항목들에 대해서는 Debian Policy Manual Chapter 5 - Control files and their fields 의 5.3 섹션을 참고 하도록 한다(여기서 바이너리 패키지와 소스 패키지의 차이점이 있다는 것을 처음 알았다. 본 문서에서는 바이너리 패키지에 대해서 설명하고 있다).

그 외에도 preinst, postinst 파일등을 작성해 줄수 있다. preinst는 패키지 인스톨 이전에 하는 일, postinst는 패키징 이후에 하는 일들에 대해 기술한다. 우리가 만드는 'pkg-build-essential'의 경우엔 so 라이브러리들을 모두 /usr/local/lib에 설치하며, 활성화를 위해 인스톨이 끝난후 ldconfig를 호출해야 한다. 그래서 postinst를 다음과 같이 작성하여 DEBIAN 디렉토리 밑에 위치 시킨다 :

ldconfig /usr/local/lib

3. usr 디렉토리 생성

위에 작성한 DEBIAN 디렉토리 외에 패키지 디렉토리 아래에 생성되어 있는 디렉토리는 패키지 설치시 root 디렉토리 밑에 그대로 복사된다. pkg-build-essential의 경우엔 /usr/local 밑에 include, lib, bin 디렉토리를 만들고 거기 각종 헤더 파일과, 라이브러리 파일 및 실행 파일들을 각각 넣기로 한다.

  • 디렉토리 구조 :
/pkg-build-essential
    /DEBIAN
        control
        postinst
    /usr
        /local
            /include
                boost, curl, mysql 등의 각종 헤더 파일
            /lib
                *.a, *.so 등 각종 라이브러리 파일들
            /bin
                실행파일들..

예를 들기 위해 위 디렉토리 구조를 그렸지만, 중요한 것은 usr 디렉토리 이하 내용들이 root 디렉토리 밑으로 복사 된다는 것이다. 설치되었으면 하는 라이브러리나,헤더, 실행 파일들을 적절한 위치에 넣으면 된다.

4. 패키징

패키징은 간단하다. dpkg를 이용하여 패키징 대상 디렉토리의 이름을 인자로 넘기면 된다. 

$ dpkg -b pkg-build-essential

위 과정이 완료되고 나면 pkg-build-essential.deb 파일이 생성된다. 필자의 경우 저 패키지 파일을 패키지 서버에 등록하지 않고(패키지 서버 만드 것도 일이다..) svn에 등록하고 팀원들에게 패키지를 체크아웃 받아서 사용하도록 했다.

5. 설치

기본적으로 dpkg에 -i 옵션을 주어서 패키지를 빌드 할 수 있으나 dpkg는 Depends에 기술된 패키지를 자동으로 다운로드 해주지 않고 그런 패키지가 필요하지만 설치가 안되었다고 에러를 낸다(How to let `dpkg -i` install dependencies for me? 참조). 의존 관계를 가진 패키지들을 자동으로 설치 되게 하기 위해 gdebi를 이용하도록 한다.

$ sudo apt-get update
$ sudo apt-get install gdebi-core
$ sudo gdebi pkg-build-essential.deb 

이상 데비안 패키지를 생성하는 방법에서 부터 설치까지 간략하게 알아 보았다. 요점은 패키지 디렉토리를 만들고 그 아래에 DEBIAN 그리고 설치되어야 할 디렉토리를 생성한다. DEBIAN 디렉토리에는 control, preinst, postinst 같은 설정 파일을, 긜고 나머지(예제에서는 usr) 디렉토리에는 설치되어야 할 파일들을 넣는다. 패키징은 dpkg를 이용하여 하지만 설치는 의존성 걸린 다른 패키지들까지 자동으로 설치 되게 하기위해 gdebi를 이용한다.

부록 1. 같이 읽으면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!