안녕하세요
뚱보 프로그래머 입니다.
오늘은 리눅스 패키지 rpm에 대해서 알아봅니다.
RPM
1. RPM 정보
ftp.redhat.com
ftp.bora.net
ftp.rpmfind.net
2. RPM 사용시 시스템 요구사항
RPM을 사용하기 위해서는 cpio 버전 2.4.2 이상이 필요하다. RPM은 리눅스에서는 물론이고 다른 유닉스 시스템에서도 사용 가능하다. SunOS, Solaris, AIX, Irix, AmigaOS 등 여러 유닉스 시스템에서 모두 컴파일된다. 주의할 것은 서로 다른 유닉스 시스템에서 만들어진 바이너리 패키지는 호환되지 않는다는 사실이다. RPM을 설치하기 위해서는 RPM을 소스에서 빌드하고 패키지를 컴파일하기 위한 gcc, make 등이 필요하다.
3. RPM 사용
1) 패키지 설치
패키지를 설치하는 방법은 보통 3가지로 제시된다. 시스템에 패키지를 설치하는 방법과 이전 패키지가 설치되어 있을 경우에만 설치가 이루어지는 방법과 이전 패키지가 설치되어 있으면 업그레이드를 하고 이전 패키지가 설치되어 있지 않으면 설치를 하는 방식이다.
1] 설치만
#rpm -i foobar-1.0-1.i386.rpm
이전 버전에 상관없이 설치를 진행한다.
#rpm –F foobar-1.0-1.i386.rpm
이전 버전의 패키지가 설치되어 있을 경우에만 설치를 진행한다.
2] 정보와 함께 설치
#rpm -ivh foobar-1.0-1.i386.rpm
#rpm –Fvh foobar-1.0-1.i386.rpm
2) 패키지 업그레이드
1] 업그레이드만
#rpm -U foobar-1.0-1.i386.rpm
2] 정보와 함께 설치
#rpm -Uvh foobar-1.0-1.i386.rpm
3) 패키지 제거
#rpm -e foobar
4) FTP를 이용한 설치
네트웍에 연결되어 있고 새로운 패키지를 설치하고 싶다면 파일의 정확한 URL과 함께 파일의 위치를 정하는 것이다.
#rpm –i ftp://ftp.pht.com/pub/linux/redhat/rh-2.0-beta/RPMS/foobar-1.0-1.i386.rpm
4. 질의하기
#rpm –Va
설치되어 있는 rpm 정보 및 변경이나 수정된 패키지를 확인하는 옵션이며 시스템 사용중 패키지 관련 파일들 중 변경된 파일을 출력한다. 보안을 염두에 둔 옵션인 듯 하지만 사용자가 해당 패키지의 파일들을 알고 있어야 하며 이는 시스템 관리자의 기본적인 역할이다.
#rpm -qf /bin/vi
이미 설치되어 있는 rpm의 버전 정보를 출력한다.
#rpm -qR foobar-1.0-1.i386.rpm
해당 패키지와 의존성을 갖는 파일들, 주로 라이브러리 파일들을 출력한다.
#rpm -qi foobar-1.0-1.i386.rpm
해당 파일에 대한 파일 목록 표시, spec파일에 쓰인 정보등을 출력한다. 일반적으로 패키지에 대한 정보를 확인하고자 할 때 이 옵션을 사용한다.
#rpm -ql foobar-1.0-1.i386.rpm
해당 패키지가 설치할 파일의 목록을 표시한다.
#rpm –qf /bin/vi
특정 파일이 어떤 패키지에 속하는지 확인하고자 할 경우이 이 옵션을 사용한다.
5. RPM의 옵션(--help 설명)
--help 도움말
--version 사용 중인 rpm의 버전
1) 모든 모드에서 지원
--rcfile <file> /etc/rpmrc 와 $HOME/.rpmrc 대신 <file>을 사용한다
-v 자세한 출력
-vv 디버깅을 위해 아주 상세한 출력
-q 질의 모드
--root <dir> <dir>을 상위 레벨 디렉토리로 사용
--dbpath <dir> <dir>을 데이터베이스 디렉토리로 사용
--queryformat <qfmt> 헤더 형식으로 <qfmt>를 사용 (-i 내포)
2) 설치, 업그레이드, 질의 (-p 추가)
ftp URL을 파일 이름 대신 적을 수 있으며 다음 옵션 사용 가능
--ftpproxy <host> ftp 프록시의 호스트 이름 또는 IP
--ftpport <port> ftp 서버(또는 프록시)의 포트 번호
--httpproxy <host> http 프록시의 호스트 이름 또는 IP
--httpport <port> http 서버(또는 프록시)의 포트 번호
3) 패키지 명시 옵션
-a 모든 패키지를 질의
-f <file>+ <file>을 소유하고 있는 패키지를 질의
-p <packagefile>+ (아직 설치되지 않은) <packagefile> 패키지를 질의
--triggeredby <pkg> <pkg>에 의해 유발되는 패키지를 질의
--whatprovides <cap> <cap> 기능을 제공하는 패키지를 질의
--whatrequires <cap> <cap> 기능을 필요로 하는 패키지를 질의
4) 정보 선택 옵션:
-I - 패키지 정보를 표시한다
--changelog - 패키지의 변화 기록을 표시한다
-l - 패키지 파일 목록을 표시한다
-s - 파일 상태를 보여준다 (-l 내포)
-d - 문서 파일만 나열한다 (-l 내포)
-c - 설정 파일만 나열한다 (-l 내포)
--dump - - 각 파일에 대하여 검증 가능한 정보를 보여준다
(-l, -c, 또는-d와 함께 사용해야 한다)
--provides - 패키지가 제공하는 기능을 나열한다
--requires
-R - 패키지 의존성을 나열한다
--scripts - 다양한 [언]인스톨 스크립트를 출력한다
--triggers - 패키지 안에 들어있는 유발 스크립트를 보여준다.
5) 검증
-V
-y
--pipe <cmd> - 표준 출력을 <cmd>로 보낸다
--verify - q와 같은 패키지 명시 옵션을 사용하여 패키지 설치를 검증한다
--dbpath <dir> - <dir>을 데이터베이스 디렉토리로 사용한다
--root <dir> - <dir>을 상위 레벨 디렉토리로 사용한다
--nodeps - 패키지 의존성을 검증하지 않는다
--nomd5 - md5 체크섬을 검증하지 않는다
--nofiles - 파일 속성을 검증하지 않는다
--setperms - q와 같은 패키지 명시 옵션을 사용하여 패키지 데이터베이스에 들어있는 파일의
허가권대로 설정한다
--setugid -q와 같은 패키지 명시 옵션을 사용하여 패키지 데이터베이스에 들어있는 파일
소유자와 그룹으로 설정한다
6) 설치
--install <packagefile>
-i <packagefile> 패키지를 설치한다
--excludepath <path> <path> 경로에 있는 파일을 건너뛴다
--relocate <oldpath>=<newpath> <oldpath>로부터 <newpath>로 파일을 재배치
--badreloc 패키지에서 허용하지 않아도 파일을 재배치한다
--prefix <dir> 재배치 가능하면 <dir>로 패키지를 재배치한다
--dbpath <dir> <dir>을 데이터베이스 디렉토리로 사용한다
--excludedocs 문서를 설치하지 않는다
--force --replacepkgs --replacefiles에 대한 축약형
-h
--hash 패키지를 설치할 때 해쉬 표식을 출력한다. (-v와 사용하면 좋다)
--allfiles 다르면 설치하지 않을 설정 파일 포함하여 모든 파일을 설치한다
--ignorearch 패키지 아키텍쳐는 검증하지 않는다
--ignoresize 설치 전에 디스크 공간 검사를 하지 않는다
--ignoreos 패키지 운영체제를 검증하지 않는다
--includedocs 문서를 설치한다
--justdb 데이터베이스는 갱신하되 파일 시스템은 변경하지 않는다
--nodeps 패키지 의존성을 검증하지 않는다
--noorder 의존성을 충족시키기 위한 패키지 설치 순서 재조정을 하지 않는다
--noscripts 설치 스크립트를 실행하지 않는다
--notriggers 패키지에 의해 유발되는 스크립트를 실행하지 않는다
--percent 패키지를 설치할 때 퍼센트를 출력한다
--replacefiles 패키지가 설치된 파일을 교체하더라도 설치한다
--replacepkgs 패키지가 이미 설치되어 있어도 다시 설치한다
--root <dir> <dir>을 상위 레벨 디렉토리로 사용한다
--test 설치하지는 않고 성공 실패 여부만 통보한다
7) 업그레이드
--upgrade <packagefile>
-U <packagefile> 패키지 업그레이드 (--install과 같은 옵션에 몇 가지 더)
--oldpackage 더 예전 버전의 패키지로 업그레이드한다.
(--force를 사용하면 자동으로 선택된다)
8) 삭제
--erase <package>
-e <package> 패키지를 지운다(언인스톨한다)
--allmatches <package>와 일치하는 모든 패키지를 제거한다.
(보통은 <package>가 여러 개의 패키지와 일치하면 에러가 발생한다)
--dbpath <dir> <dir>을 데이터베이스 디렉토리로 사용한다
--justdb 데이터베이스는 갱신하되 파일 시스템은 변경하지 않는다
--nodeps 패키지 의존성을 검증하지 않는다
-noorder 의존성을 충족시키기 위한 패키지 설치 순서 재조정을 하지 않는다
--noscripts 패키지 고유의 스크립트를 하나도 실행하지 않는다
--notriggers 패키지에 의해 유발되는 스크립트를 실행하지 않는다
--root <dir> <dir>을 상위 레벨 디렉토리로 사용한다
9) spec 옵션
-b<stage> <spec>
-t<stage> <tarball> 패키지를 제작한다. <stage>는 다음과 같다:
p 준비한다. (소스를 풀고 패치를 적용한다)
l 파일 목록 점검 (%files에 대하여 자세한 점검을 행한다)
c 컴파일한다. (준비 과정과 컴파일)
I 설치한다. (준비, 컴파일, 설치)
B 바이너리 패키지 (준비, 컴파일, 설치, 패키지)
A 바이너리/소스 패키지 (준비, 컴파일, 설치, 패키지)
--short-circuit skip straight to specified stage (only for c,i)
--clean remove build tree when done
--rmsource 작업을 마치고 나서 소스와 spec 파일을 지운다
--sign PGP/GPG 서명을 발생시킨다
--buildroot <dir> 제작 루트로 <dir>을 사용한다
--target=<platform>+ 목표 플랫폼1...플랫폼N에 대한 패키지를 제작한다
--nobuild 어떠한 단계도 실행하지 않는다
--timecheck <secs> 시간 점검을 <secs> 초로 설정한다. (0은 해제)
10) 소스 rpm 옵션
--rebuild <src_pkg> 소스 패키지를 설치하고 바이너리 패키지를 만든 후 spec 파일과 소스,
패치, 아이콘을 삭제한다
--rmsource <spec> 소스와 spec 파일을 삭제한다
--recompile <src_pkg> --rebuild와 같지만 패키지는 만들지 않는다
--resign <pkg>+ 패키지에 사인한다. (기존의 서명은 버린다)
--addsign <pkg>+ 패키지에 서명을 추가한다
11) 패키지 서명
-K
--checksig <pkg>+ 패키지의 서명을 검증한다
--nopgp PGP 서명을 건너뛴다
--nogpg GPG 서명을 건너뛴다
--nomd5 MD5 서명을 건너뛴다
--querytags 질의 형식에서 사용할 수 있는 태그를 나열한다
--initdb 올바른 데이터베이스가 있는지 확인한다
--rebuilddb 기존의 데이터베이스로부터 데이터베이스를 다시 만든다
--dbpath <dir> <dir>을 데이터베이스 디렉토리로 사용한다
--root <dir> <dir>을 상위 레벨 디렉토리로 사용한다
6. RPM 파일의 구분과 만들 때의 기본적 개념
1) SRPM과 RPM의 구분
rpm -ba foobar-1.0-1.i386.rpm를 하여 RPM을 실행을 시키면 SRPM과 RPM이 만들어진다. 전자를 소스파일, 후자를 바이너리 파일이라 한다. 전자는 foobar-1.0-1.tar.gz과 foobar-1.0-1.spec 파일 및 이에 관한 patch 파일 등 rpm을 만드는 데 있어 재료가 된 파일들을 함께 묶어 놓고, 후자가 위 명령으로 만들어진 RPM 실행 파일이기 때문이다.
2) spec의 용도
rpm -ba foobar-1.0-1.i386.rpm과 같이 RPM 명령을 내리면 이 파일을 읽어들여서 처리를 하게 된다. 이것은 특별한 스크립트 파일이며, %Prep 이후로부터 스크립트 명령이 시작된다. 그래서 주의할 점은 이 파일에 다른 명령어가 들어 있지 않은지 항상 확인하라는 것이다.
만약 'rm -rf' 등과 같은 명령어가 들어가 있다면 시스템을 다시 설치해야 할지도 모른다. 앞 부분은 만들어진 파일들에 대한 정보가 들어간다. spec 파일은 SRPM에서 얻을 수 있으며, foobar-1.1-1.tar.gz과 같은 파일만 있을 때에는 직접 편집하여 사용하면 된다.
3) RPM의 원리
RPM은 같은 종류의 시스템에서 패치한 부분까지를 포함한 소스를 그대로 사용하게 하는 것이다.
시스템에 이미 최적화되어 컴파일된 소스들을 묶어서 같은 종류의 다른 시스템에서 그대로 풀어서 사용할 수 있게 하는 것이다.
따라서, spec 파일에는 원래 소스인 foobar-1.1-1.tar.gz 파일을 푸는 과정과 makefile을 실행하여 컴파일하는 과정이 들어가 있으며, 이 컴파일된 파일들을 한데 모으는 과정을 거치게 된다. 또한 그렇기 때문에 다른 종류의 운영체제에서는 이미 만들어진 rpm 파일이 실행되지 않는다.
7. 소스 RPM 빌드
일반적으로 소스 rpm 패키지를 rpm 패키지로 인스톨하는 과정을 간단하게 살펴보면 다음과 같은 과정을 거친다.
#rpm --rebuild 소스rpm
자동으로 /usr/src/redhat/BUILD 디렉토리에 임시로 컴파일되면서 저장된후
--target으로 지정하지 않으면 /usr/src/redhat/RPMS/i386 디렉토리에 저장됨
#rpm -ivh /usr/src/redhat/RPMS/i386/리빌드된rpm 패키지명
1) RPM 설치, 소스 풀기
RPM 설치, 업그레이드 전에 해당 패키지의 존재 여부를 확인하고, 필요한 경우는 old 파일 삭제후 새로 설치하도록 한다.
# rpm -qa | grep 패키지명 (패키지명 검색)
# rpm -e 패키지명 (패키지 삭제)
설치 명령은 다음과 같다.
# rpm -ivh[또는 -Uvh] 패키지명.src.rpm
이 경우 SRPMS의 경우는 /usr/src/redhat의 /SOURCES, /SPECS에 소스와 spec 파일이 나누어 풀려진다.
만약 삭제나 설치시에 의존성 문제가 발생한다면, --nodeps 옵션으로 의존성을 무시하고 설치하거나
--force 옵션을 이용하여 강제 설치할 수도 있다.
# rpm -e --nodeps 패키지명
# rpm -e --force 패키지명
# rpm -e --nodeps --force 패키지명
2) 소스 컴파일 : rpm -b{a,b,s...기타}
먼저 RPM 패키지의 경로를 확인한다.
/usr/src/redhat -+- BUILD : RPM 작업(컴파일, 패키지) 경로
+- RPMS -+- athlon : 애슬론용 바이너리 제작 위치
+ +- i386 : 일반 제작 위치
+ +- i486 : CPU 타입에 따라 rebuild된 바이너리 제작 위치
+ +- i586 : ''
+ +- i686 : ''
+ +- noarch : 아키텍쳐, CPU를 구분하지 않는 파일들(폰트, 맨페이지)
+- SOURCES : *.tar.gz 등 실제 소스
+- SPECS : spec 파일 저장 위치
+- SRPMS : SRPMS 저장 위치
패키지명.spec 파일의 위치에서 다음 옵션을 사용한다.
(1) rpm -bb 패키지명[.spec] : RPM 바이너리 제작 (RPMS/i386에 위치)
(2) rpm -bs 패키지명[.spec] : SRPMS 제작 (SRPMS에 위치)
(3) rpm -ba 패키지명[.spec] : SPRPMS, RPM 모두 제작 (SRPMS, RPM 모두 제작)
참고) *.src.rpm 에서 바로 rpm 파일만 생성할 경우는 다음 방법을 따른다.
# rpm --rebuild 패키지명.src.rpm
이 경우 제작된 RPM 파일은 /usr/src/redhat/RPMS의 각 CPU 디렉토리에서 확인할 수 있으며 rpm 관련 일반 명령어를 이용해서 설치할 수 있다.
8. 소스 파일을 rpm 패키지로 만들기
1) Source file을 재 패키징하여 rpm 패키지 만들어 설치하기.
1] 참조 사이트
다음은 관련 문서들의 참조 사이트들이다.
http://www-106.ibm.com/developerworks/library/l-rpm1/
http://www.linux.sarang.net/paper/rpm
http://www.linux.sarang.net/paper/package
http://kldp.org/KoreanDoc/RPM_Guide-KLDP
2] 작업 구분
작업은 크게 세가지로 나뉜다.
첫 째로 원격설치이고 두 번째는 소스 rpm 파일을 받아서 일단 풀어놓은 후 spec 파일만 남겨놓은채 나머지는 제거한다. 그 후에 다시 소스 파일을 받아 수정한 spec 파일을 이용해 재패키징 한다. 세번째는 현재 깔려있는 indent를 확인하고 , 업그래이드된 버전을 소스로 다운 받는다. 그리하여 rpm 패키지로 만들어 설치후 버전을 확인한다.
3] 원격 설치
원격 설치는 로컬에서의 설치와 다를 바가 없다. 예를 들면 로컬에서 할수 있는 질의를 원격 설치시에 할 수 있다는 것이다.
다음은 하나의 과정을 예로들어 설명한다.
[root @edu00 /root]#rpm –i --percent --test \
>ftp://ftp.proftpd.org/distrib/packages/RPMS/proftpd-1.2.5rc1-1.i386.rpm
error: failed dependencies:
libc.so.6(GLIBC_2.2.3) is needed by proftpd-1.2.5rc1-1
--percent는 설치시 설치량(?)을 보여주고 test는 설치는 하지 않고 의존성 검사만 한다.
즉, 위의 메시지를 보면 proftpd-1.2.5rc1-1을 설치하기 위해서는 libc.so.6인 라이브러리, 즉 GNU library 버전 2.2.3이 필요하다는 의미이다.
[root @scol/root]#rpm -i --percent --nodeps \
>ftp://ftp.proftpd.org/distrib/packages/RPMS/proftpd-1.2.5rc1-1.i386.rpm
%% 98.954694
%% 99.659433
%% 99.978757
%% 99.989547
%% 100.000000
위의 명령은 원격으로 설치를 하는데 설치량을 보여주고 의존성을 무시하라는 의미이다.
[root@scol /root]# rpm -qpl \
>ftp://ftp.proftpd.org/distrib/packages/RPMS/proftpd-1.2.5rc1-1.i386.rpm
/etc/pam.d/ftp
/home/ftp
/usr/bin/ftpcount
/usr/bin/ftpwho
/usr/man/man1/ftpcount.1.gz
/usr/man/man1/ftpwho.1.gz
/usr/man/man5/xferlog.5.gz
옵션 –ql은 rpm으로 설치된 관련 파일들을 보여주고, 옵션 -p는 아직 설치되지 않은 파일을 가리킨다.
위의 명령은 아직 설치되지 않은 rpm 파일이 설치된다면 생성될 파일들에 대한 질의를 원격의 ftp 서버에 하는 것이다.
만약 rpm –qip의 명령을 주면 설치될 패키지의 정보를 보여 줄것이다.
4] 재패키징
여기에서도 proftp를 이용하여 예를 든다.
우선 ftp의 소스 rpm을 다운받는다.
사이트는 http://proftpd.org이며, 다운받는 위치는 /usr/src/redhat/SRPM 이다
proftpd-1.2.5rc1-1.src.rpm
여기에서 주의할 것은 시스템 사양에 맞는 즉 타겟 아키텍처 rpm을 만드는 방법이다.
방법은 spec 파일을 수정하는 것과 그렇게 하지 않는 방법이다.
[root @edu00 SRPMS]#pwd
/usr/src/redhat/SRPMS
[root @edu00 SRPMS]# rpm --rebuild --target=i686 proftpd-1.2.5rc1-1.src.rpm
Installing proftpd-1.2.5rc1-1.src.rpm
Building target platforms: i686
Building for target i686
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.92855
+ umask 022
[root @edu00 i686]# pwd
/usr/src/redhat/RPMS/i686
[root @edu00 i686]# ls
proftpd-1.2.5rc1-1.i686.rpm proftpd-inetd-1.2.5rc1-1.i686.rpm proftpd-standalone-1.2.5rc1-1.i686.rpm
위의 예에서 보듯이 i686 아키텍처 rpm 패키지가 만들어졌다. 이 외에 더 많은 아키텍처는
/usr/lib/rpm/rpmrc 파일에 있다.
다음은 spec 파일을 수정하여 만드는 방법이다.
spec 파일을 수정한다는 의미는 내 시스템 환경에 맞게 패키지를 재 패키징 한다는 의미이다.
spec 파일을 수정하려면 일단 소스 rpm을 풀어야 한다. 다운받은 위치로 이동한다.
/usr/src/redhat/SRPMS 디렉토리이다.
[root @edu00 SRPMS]# rpm -Uvh proftpd-1.2.5rc1-1.src.rpm
1:proftpd ########################################### [100%]
위 명령을 실행해도 현재 디렉토리엔 아무 변화가 없다.
/usr/src/redhat/SPECS이란 디렉토리에 profptd.spec이라는 파일이 생성되고, ../SOURCE 디렉토리에 tar.gz 파일이 생성된다.
즉 재 패키징이란 tar.gz + spec의 수정으로 이루어진다는 의미이다.
그 후 spec 파일을 수정하고 저장한다. 다음의 명령을 실행할 디렉토리의 위치를 주의한다.
[root @edu00 SPECS]#rpm –ba --target=i686 proftpd.spec
위의 명령은 바이너리 패키지와 소스 패키지를 모두 i686 아키텍쳐로 만들라는 의미이다.
다음의 옵션을 기억해야 한다.
i 는 컴파일과 설치만 한다.
b 는 바이너리 패키지만 만들어낸다.
a 는 바이너리와 소스패키지 둘다 만들어 낸다.
/usr/src/redhat/SRPMS 에는 소스 파일이 생성되고, /usr/src/redhat/RPMS/i686 에는 패키지 파일이 생성된다.
일반적으로 spec 파일을 수정할 수 있으면 소스 rpm 파일 받아서 설치하고 , spec 파일 수정한 후에 재패키징하면 된다.
5] 소스파일의 패키징
여기서는 tar.gz 파일을 받고 spec파일을 직접 생성해서 rpm파일을 만들고 설치하는 것이다.
Indent.tar.gz 파일을 다운받고, proftpd.spec 파일을 참조해서 패키징을 한다.
먼저 현재 시스템에 있는 indent의 버전을 확인한다.
[root @edu00 /root]# rpm -qa | grep indent
indent-2.2.6-1
현재 indent-2.2.7-1의 버전이 있으므로 이 소스를 받아 재패키지를 하여 업그래이드 형식으로 설치를 한다.
다음의 spec 파일을 참조한다.
#header
summary: GNU indent
name: indent
version: 2.2.7
release: 1
source0: %{name}-%{version}.tar.gz
license: GPL
group: Development/Tools
#body
%description
The GNU indent program reformats C code to any of a variety of formatting standards, or you can define your own.
%prep
%setup -q
%build
./configure
make
%install
make install
%files
%defattr(-,root,root) 기본적인 퍼미션을 의미한다.
/usr/local/bin/indent
%doc /usr/local/info/indent.info
%doc %attr(0444,root,root) /usr/local/man/man1/indent.1 이것은 각 파일의 소유자와 파일을의 퍼미션을 변경할수 있다는 의미이다.
%doc COPYING AUTHORS README NEWS
#header
일반적인 내용을 포함하고 있다.
중요시 봐야 할 것은 name 과 버전이다.
소스에 보면 %{name}-%{version}.tar.gz 라고 되어있기 때문이다. 이유는 #body 부분에 편리루틴중에 %setup 이라는 것이 있다. 이것은 소스파일을 풀고 그 디렉토리로 들어가는 것까지가 임무인데, 소스파일을 풀 때 위에 source부분을 참조한다.
원래 source부분은 소스를 얻은 경로를 나열하라고 하였지만, 어차피 참조하는건 맨 마지막인 파일 이름이므로 다 적지는 않았다. 무사히 패키징 되는걸로 봐서는 그렇게 중요한 것 같지는 않다. 또한 %setup 이라고 해주지 않아도 된다.
tar xvzf indent-2.2.7-1
cd indent-2.2.7-1
이라고 해주어도 무방하다는 얘기이다. 이유는 확장자가 tgz 이라고 올수 있기 때문에, 그때에는 %setup의 기본적인 명령이 먹히지 않을수 있다는 것이다.
옵션에 대해서 알아보자.
%setup -n linuxone
이렇게 명령을 주면 linuxone 라는 디렉토리로 이동하게 한다.
다음에 여기서 사용하지는 않았지만 %patch 라는것이 있다.
이것은 말그대로 패치하는데 make 하기전데 소스에 패치를 하는 것이다.
%setup 전에 %prep 이라는 것은 준비단계를 의미한다. 즉 아래 스크립트 파일을 받는 다는 얘기이다.
패치에서 알아야할 옵션에는 –p 라는 것이 있다. 이는 없앨 슬래쉬 겟수이다. 즉, patch < new.patch 라는 파일을 패치 하려고 하면 애러가 발생될 것이다. 만약 경로가 정확해도 말이다. 이 경우에는 패치 파일의 위에 보면 경로가 나와 있는데,
---usr/src/redhat/old.c oldfile
+++usr/src/redhat/new.c newfile
비슷하게 되어 있을것이다.
여기서 패치를 하려면 %patch –p3 < new.patch 라고 해주어야 할것이다. 즉 이렇게 해주면 슬래쉬 3개를 제외한 디렉토리의 파일에 패치를 가하는 결과는 갖는다.
즉 usr/ 빠지고 src/ 빠지고 redhat/ 빠지면 남는 파일을 패치하라는 의미이다.
diff -uNr dirname.orig dirname > ../SOURCES/dirname-linux.patch 이것은 패치파일을 만드는 명령어 이다.
다음으로 %build 라는 플래그가 있다.
이는 빌드, 즉 컴파일을 하는 과정이다.
./configure
make
물론 CFLAGS=$RPM_OPT_FLAGS ./configure 방식을 따르거나 make CFLAGS=$RPM_OPT_FLAGS 방식으로 지정할 수도 있다.
%install 부분은 make install 을 입력한다.
%files
명령어의 경로명을 입력한다.
예를 들면 proftpd의 spec 파일을 보면 /usr/sbin/*, /usr/bin/* 라고 정의 되어있다.
Sbin과 bin 의 모든 명령어를 같이 패키징 한다는 의미이다.
이것이 제대로 되지 않으면 패키징이 되지 않는다. 필요한 파일들을 나열해 준다.
[root @edu00 i386]# rpm -e indent
error: removing these packages would break dependencies:
indent is needed by ORBit-devel-0.5.7-3
[root @edu00 i386]# rpm -e --nodeps indent
[root @edu00 i386]# rpm -Uvh indent-2.2.7-1.i386.rpm
Preparing... ########################################### [100%]
1:indent ########################################### [100%]
아래는 위에 spec 파일을 다시 릴리즈해서 재 패키징 한 내용이다.
참고사항.
BuildRoot:라는 필드를 사용하였다면 rpm은 BuildRoot:로 정의된 경로를 '/'로 인식하여 위의 파일들을 찾는다.
BuildRoot를 사용하였다면 %install 과정에서 파일들을 $RPM_BUILD_ROOT의 환경변수를 사용하여 패키지를 BuildRoot:로 정의된 하위 디렉토리로 인스톨해야 한다.
summary: GNU indent
name: indent
version: 2.2.7
release: 2 => 이부분이 증가 했다.
source0: %{name}-%{version}.tar.gz
license: GPL
group: Development/Tools
BuildRoot: %{_builddir}/%{name}-root => 추가된 부분
%description
The GNU indent program reformats C code to any of a variety of formatting standards, or you can define your own.
%prep
%setup -q
%build
./configure
make
%install
rm -rf $RPM_BUILD_ROOT =>추가 부분: build가 이루어질 부분을 미리 지워줌.
대부분 /usr/src/redhat/BUILD 이다.
make DESTDIR=$RPM_BUILD_ROOT install => 추가 부분: 빌드될 곳을 DESDIR에 넣어준다.
%clean
rm -rf $RPM_BUILD_ROOT => build 가 이루어진 부분을 삭제한다.
%files
%defattr(-,root,root)
/usr/local/bin/indent
%doc /usr/local/info/indent.info
%doc %attr(0444,root,root) /usr/local/man/man1/indent.1
%doc COPYING AUTHORS README NEWS
[root@scol i386]# rpm -Uvh indent-2.2.7-2.i386.rpm
Preparing... ########################################### [100%]
1:indent ########################################### [100%]
[root@scol i386]# rpm -qa | grep indent
indent-2.2.7-2
9. 패치파일
1) 패치파일 만들기
소스 자체에 수정을 가하기보다는 소스는 그냥 놔두고 패치 파일을 만들어 수정한다.
- 소스의 압축을 풀어 그 디렉터리 이름을 *.orig 로 바꾸고 다시 한번 압축을 푼다.
즉 똑같은 내용의 디렉터리를 두개 만들어 하나는 *.orig 로 다른 것은 원래의 이름으로 둔다.
다시 말해 ls 했을 때 source.orig 와 source 의 디렉터리가 동시에 있어야 한다.
- 소스의 수정은 원래 이름의 디렉터리에서 하고 끝났으면 상위 디렉터리로 이동해서 다음의 명
령을 입력한다. (ls 했을 때 두 디렉터리가 보이는 곳에서)
diff -uNr source.orig source > source.patch
2) 패치파일의 적용
일반적으로 패치를 적용할 프로그램의 소스 디렉터리로 이동해서 다음의 명령을 수행한다.
patch -p1 < patchfile
만약 패치 파일에서 수정한 파일 이름이 gau-0.4.1/src/main.c 라면 '-p0' 는 파일 이름 그대로
'-p1'은 첫번째 슬래쉬 앞쪽을 뺀 src/main.c 으로 패치가 적용된다. 그러므로 다른 사람이 만
든 패치를 이용한다면 이런 점을 고려해서 spec 파일을 만든다.
3) export CFLAGS="$RPM_OPT_FLAGS"
%build 에서 컴파일을 할 때 최적화를 위한 것으로 기본으로 /usr/lib/rpm/rpmrc 를 이용하지만
/etc/rpmrc 를 만들어서 수정할 수도 있다. (예를 들어 펜티엄 옵션으로 컴파일한다든가 할 때)
4) devel 패키지 (헤더 파일)
아무리 spec 파일이 정상적으로 만들어져있다 할지라도 프로그램을 컴파일하는데 필요한 헤더파
일들이 없다면 컴파일이 되지 않으므로 패키지가 만들어지지 않는다. 최소한 다음의 패키지들은
설치되어 있어야 할 것이다. (rpm -qa |grep devel 로 확인)
- glib-devel
- glibc-devel
- kernel-header
- XFree86-devel (X-Window 용 프로그램을 컴파일 한다면)
5) 패키지가 만들어지지 않을 때
BuildRoot: 에서 지정한 디렉터리(여기선 /var/tmp)에 보면 rpm-숫자 형식의 파일이 있는데 그
내용을 살펴보면 어디에서 문제가 발생했는지 알 수 있다.
rpm이란 호환 문제도 있고 그 호환 문제 때문에 커널또한 업그레이드가 필요한 경우가 종종 발생하는것 같습니다.
상황에 맞게 진행하시면 될것 같습니다.