RPM
Wanho Choi
RPM: Redhat Package Manager
Redhat Linux 시스템에서 소프트웨어의 설치 및 관리를 해주는 유틸리티
RPM Mode
설치 (install)
제거 (uninstall)
업그레이드 (upgrade)
질의 (query)
검증 (verify)
How to install an RPM package
[root@rnd-wanho ~]# ls *.rpm
freeglut-devel-2.8.1-3.el7.x86_64.rpm
[root@rnd-wanho ~]# rpm -ivh freeglut-devel-2.8.1-3.el7.x86_64.rpm
Preparing… ################################# [100%] Updating / installing…
1:freeglut-devel-2.8.1-3.el7 ################################# [100%]
[root@rnd-wanho ~]# rpm -qa | grep freeglut
freeglut-2.8.1-3.el7.x86_64
freeglut-devel-2.8.1-3.el7.x86_64
[root@rnd-wanho ~]# rpm -e freeglut-devel-2.8.1-3.el7.x86_64
[root@rnd-wanho ~]# rpm -qa | grep freeglut
RPM Setup
[root@rnd-wanho ~]# yum install rpmdevtools rpmlint rpm-build
[root@rnd-wanho ~]# rpm -qa | grep rpm
rpmlint-1.5.4.el7.noarch rpm-python-4.11.1-16.el7.x86_64 perl-srpm-macros-1-8.el7.noarch rpm-4.11.1-16.el7.x86_64 python-deltarpm-3.6-3.el7.x86_64 rpm-build-libs-4.11.1-16.el7.x86_64 rpm-sign-4.11.1-16.el7.x86_64 rpm-devel-4.11.1-16.el7.x86_64 rpmdevtools-8.3-5.el7.noarch rpm-libs-4.11.1-16.el7.x86_64 deltarpm-3.6-3.el.x86_64 rpm-build-4.11.1-16.el7.x86_64 redhat-rpm-config-9.1.0-63.el7.centos.noarch
Naming Convention
Architecture
i386: 인텔 80386 계열의 프로세서를 가진 플랫폼에서 컴파일 되었음.
i586: 인텔 80586 계열의 프로세서를 가진 플랫폼에서 컴파일 되었음.
i686: 인텔 80686 계열의 프로세서를 가진 플랫폼에서 컴파일 되었음.
x86: x386, x586, x686 등 모든 플랫폼에서 동작이 가능함.
x86_64: 64비트 플랫폼에서 동작이 가능함.
alpha: 알파칩 계열의 프로세서를 가진 플랫폼에서 컴파일 되었음.
ppc: Power PC 계열의 프로세서를 가진 플랫폼에서 컴파일 되었음.
noarch: 문서나 글꼴처럼 아키텍쳐에 종속되지 않음.
Binary RPM vs Source RPM
Binary RPM (확장자: .rpm)
: 컴파일된 결과 바이너리 파일과 설정 파일 등을 묶어놓은 패키지
Source RPM (확장자: .src.rpm)
: 바이너리 RPM을 만드는데 재료가 되는 파일들을 묶어놓은 패키지
1) 소스코드 공개 의무 규정이 있는 GPL 라이센스의 경우
2) 각 시스템에 보다 최적화된 RPM 패키지를 만들기 위한 경우
※ 최신 소프트웨어 패키지는 binary RPM이 나오기 전에source RPM만 존재하는 경우가 많음
Directories for Packaging RPM
BUILD
빌드(압축 풀기 & 컴파일)가 이루어지는 디렉토리
RPMS
binary RPM이 생성되는 디렉토리
SOURCES
소스 파일(*.tar.gz)을 넣어두어야 하는 디렉토리
SPECS
명세 파일(.spec)을 넣어두어야 하는 디렉토리
SRPMS
source RPM이 생성되는 디렉토리
How to create directories #1
[wanho.choi@rnd-wanho ~]$ mkdir -p ./rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
[wanho.choi@rnd-wanho ~]$ ls -R rpmbuild
rpmbuild:
BUILD RPMS SOURCES SPECS SRPMS rpmbuild/BUILD:
rpmbuild/RPMS:
rpmbuild/SOURCES: rpmbuild/SPECS:
[wanho.choi@rnd-wanho ~]$ rpmdev-setuptree
[wanho.choi@rnd-wanho ~]$ ls -R rpmbuild
rpmbuild:
BUILD RPMS SOURCES SPECS SRPMS rpmbuild/BUILD:
rpmbuild/RPMS:
rpmbuild/SOURCES: rpmbuild/SPECS:
rpmbuild/SRPMS:
%_topdir %(echo $HOME)/rpmbuild
%_smp_mflags %( \
[ -z "$RPM_BUILD_NCPUS" ] \\\
&& RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\ if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
echo "-j16"; \\\
elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\ echo "-j$RPM_BUILD_NCPUS"; \\\
else \\\
echo "-j3"; \\\ fi )
%__arch_install_post \
[ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \
case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \ /usr/lib/rpm/check-buildroot
~/.rpmmacros
rpmbuild에 필요한 각종 환경 변수를 설정하는 파일이다.
rpmdev-setuptree를 실행하면 실행 위치에 상관없이
$HOME/rpmbuild 디렉토리가 자동으로 만들어지는데
이는 $HOME/.rpmmacros 파일에 있는 %_topdir 설정 때문이다.
$HOME/.rpmmacros 파일에 있는 %_topdir 설정에 따라
rpmbuild 디렉토리가 생성되는 위치가 결정된다.
만약 $HOME/.rpmmacros 파일이 없으면
rpmdev-setuptree 실행시 자동적으로 만들어진다.
RPM Packaging Process
패키징 하려는 파일을 모아 소스 파일(.tar.gz)을 만든다.
명세 파일(.spec)을 만든다.
Cautions when Packaging RPM
패키지를 만들 때 root 사용자 계정을 사용하지 말것!
RPM 패키징시 cp, rm, mkdir 등의 시스템 명령어들을 사용하기 때문에
시스템이 엉망이 될 가능성이 있기 때문.
Compile / Test
[wanho.choi@rnd-wanho ~]$ vi main.cpp
[wanho.choi@rnd-wanho ~]$ g++ -o main main.cpp
[wanho.choi@rnd-wanho ~]$ ./main
Hello RPM
[wanho.choi@rnd-wanho ~]$ rm -f main
#include <iostream> using namespace std;
int main( int argc, char* argv[] ) {
cout << “Hello RPM” << endl; }
Collect / Compress
[wanho.choi@rnd-wanho ~]$ tar cvfz MyPackage-1.0.0.tar.gz main.cpp
[wanho.choi@rnd-wanho ~]$ ls *.tar.gz
MyPackage-1.0.0.tar.gz
[wanho.choi@rnd-wanho ~]$ rpmdev-setuptree
[wanho.choi@rnd-wanho ~]$ ls -R rpmbuild
rpmbuild:
BUILD RPMS SOURCES SPECS SRPMS rpmbuild/BUILD:
rpmbuild/RPMS:
rpmbuild/SOURCES: rpmbuild/SPECS:
rpmbuild/SRPMS:
[wanho.choi@rnd-wanho ~]$ mv MyPackage-1.0.0.tar.gz rpmbuild/SOURCES
[wanho.choi@rnd-wanho ~]$ cd rpmbuild/SPECS
[wanho.choi@rnd-wanho SPECS]$ vi MyPackage.spec
[wanho.choi@rnd-wanho SPECS]$ cd ..
[wanho.choi@rnd-wanho rpmbuild]$ rpmbuild -ba SPECS/MyPackage.spec
Create .spce file / Build RPM
rpmbuild -bb: binary only
rpmbuild -bs: source only
[wanho.choi@rnd-wanho rpmbuild]$ ls -R
.:
BUILD RPMS SOURCES SPECS SRPMS ./BUILD: main main.cpp ./BUILDROOT: ./RPMS: x86_64 ./RPMS/x86_64: MyPackage-1.0.0-1.el7.centos.x86_64.rpm MyPackage-1.0.0-1.x86_64.rpm ./SRPMS: MyPackage-1.0.0-1.el7.centos.src.rpm MyPackage-1.0.0-1.src.rpm
MyPackage.spec (1/3)
Name: MyPackage
Version: 1.0.0
Release: 1%{?dist}
Summary: My First RPM Package
License: Copyright 2018 by Wanho Choi
URL: http://WanoChoi.com
Group: Applications/Tools
Packager: Wanho Choi (wano@choi.com)
Source0: %{name}-%{version}.tar.gz
%description
This is a simple example for explaining how to build our own RPM package. Author: Wanho Choi
BuildRequires: gcc >= 4.8.2
Requires:
MyPackage.spec (2/3)
%prep cp %{_sourcedir}/%{archive_file} %{_builddir} cd %{_builddir} tar xvf %{archive_file} rm %{archive_file} %build g++ -o main main.cpp %install mkdir -p %{buildroot}/home/wanho.choi/zzz cp main %{buildroot}/home/wanho.choi/zzz/ %clean rm -rf %{buildroot} %files /home/wanho.choi/zzz/mainMyPackage.spec (3/3)
%changelog
* Fri Mar 30 2018 Wanho Choi - 1.0.0 - Initial RPM packaging
Group
Amusements/Games Amusements/Graphics Applications/Archiving Applications/Communications Applications/Databases Applications/Editors Applications/Emulators Applications/Engineering Applications/File Applications/Internet Applications/Multimedia Applications/Productivity Applications/Publishing Applications/System Applications/Text Development/Debuggers Development/Languages Development/Libraries Development/System Development/Tools Documentation System Environment/Base System Environment/Daemons System Environment/Kernel System Environment/Libraries System Environment/Shells User Interface/Desktops User Interface/X User Interface/X Hardware SupportPre-defined Built-in Macros
%_prefix /usr %_exec_prefix %{_prefix} %_bindir %{_exec_prefix}/bin %_sbindir %{_exec_prefix}/sbin %_libexecdir %{_exec_prefix}/libexec %_datadir %{_prefix}/share %_sysconfdir %{_prefix}/etc %_sharedstatedir %{_prefix}/com %_localstatedir %{_prefix}/var %_libdir %{_exec_prefix}/lib %_includedir %{_prefix}/include %_oldincludedir /usr/include %_infodir %{_prefix}/info %_mandir %{_prefix}/man[wanho.choi@rnd-wanho ~]$ rpm --eval %{_prefix}
Fields (1/6)
Name: 패키지의 기본 이름. *.spec 파일의 이름과 같아야 함.
Version: 패키징할 소프트웨어의 버전.
Release: 현재 버전의 소프트웨어가 몇 번째로 릴리즈 되었는가를 나타냄.
보통의 경우 1%{?dist}로 적고, 릴리즈할 때마다 하나씩 증가시켜줌. 버전이
바뀌게 되면 다시 1부터 시작.
Summary: 패키징할 소프트웨어에 대한 한 줄의 간단한 설명.
Fields (2/6)
License: 패키징할 소프트웨어의 라이센스.
URL: 패키징할 소프트웨어의 정보를 얻을 수 있는 인터넷 주소.
Group: 이 패키지가 속하게 될 그룹.
Packager: 이 패키지를 유지/보수하는 담당자.
Source0: 아카이브 파일(*.tar.gz)의 경로. 여러 개의 아카이브 파일을 포함
시킬 수도 있는데, 이 때에는 Source1, Source2, Sourc3, ... 등으로 적어서
추가해주면 됨.
Fields (3/6)
Description: 패키징할 소프트웨어에 대한 보다 자세한 설명. Summary는
한 줄로만 적어야 하는 반면, Description은 여러 줄로 적어도 되고 여러 문단
으로 기술할 수 있음.
BuildRequires: 빌드할 때 필요한 패키지들. 콤마(,)나 빈칸으로 구분하여
추가해주면 됨.
Requires: 실행할 때 필요한 패키지들. 콤마(,)나 빈칸으로 구분하여 추가해
주면 됨.
%define: 사용자 정의 매크로.
Fields (4/6)
%pre: 패키지가 install 되기 직전에 실행되는 부분
%post: 패키지가 install 된 직후에 실행되는 부분
%preun: 패키지가 uninstall 되기 직전에 실행되는 부분
%postun: 패키지가 uninstall 된 직후에 실행되는 부분
Fields (5/6)
%build: 빌드를 하는 명령어들을 적어주는 곳.
%install: 빌드가 완료된 후 결과 파일들을 패키징할 곳으로 옮겨주는 명령어
들을 적어주는 곳. 보통의 경우 ~/rpmbuild/BUILD에서 ~/rpmbuild/
BUILDROOT로 필요한 파일들을 복사하게 되며, 이 때 ~/rpmbuild/
BUILDROOT에 필요한 디렉토리들을 생성해줌. 여기에 적은 명령어들은 패키
징을 할 때 실행될 뿐이며, 최종 사용자가 패키지를 설치할 때 실행되는 것은
아님.
%clean: 설치가 완료된 후에 실행되며, 보통 빌드된 파일들을 지워주는 명령
을 수행하게 됨.
Fields (6/6)
%files: 최종적으로 패키지에 포함될 파일 또는 디렉토리들을 모두 이곳에 적
어주어야 함. 최종 사용자가 패키지 설치 경로이기도 함. 단, 패키징을 할 때에
는 적어준 경로 앞에 %{buildroot}가 prefix로 붙어서 해석됨.
%changelog: 패키지의 버전이가 릴리즈 번호가 바뀔 때마다 바뀐 사항들
을 적어주는 곳. 쉘(shell)에서 “rpm -q --changelog MyPackage” 명령으
로 확인할 수 있음.
[root@rnd-wanho rpmbuild]# cd RPMS/x86_64
[root@rnd-wanho x86_64]# ls
MyPackage-1.0.0-1.el7.centos.x86_64.rpm MyPackage-1.0.0-1.x86_64.rpm
[root@rnd-wanho x86_64]# rpm -ivh MyPackage-1.0.0-1.x86_64.rpm
Preparing… ################################# [100%] Updating / installing…
1:MyPackage-1.0.0-1 ################################# [100%]
[root@rnd-wanho x86_64]# /home/wanho.choi/zzz/main
Hello RPM
[root@rnd-wanho x86_64]# rpm -qa | grep MyPackage
MyPackage-1.0.001.x86_64
[root@rnd-wanho x86_64]# rpm -e MyPackage-1.0.001.x86_64