티스토리 뷰
spec 파일을 작성해 rpm 패키징 하는 방법을 소개하겠습니다.
복잡한 빌드 설정들을 제거하고 순수하게 packaging 방법만 확인할 수 있도록,
빌드 자체는 거의 수동에 가깝게 작성하였습니다.
※Ubuntu 12.04 64bit 환경에서 Test 하였습니다.
※fedora project wiki를 참조했습니다. (How to create an RPM package)
※Sample Code 위치입니다. (https://github.com/z-wony/c_tutorial/tree/master/Tutorial1_RPM_packaging)
- 패키지 directory 생성. (여기서는 "hello-rpm" 이라 하겠습니다.)
- ~/$mkdir hello-rpm
- source 작성 (간단히 hello를 출력하는 코드를 작성합니다.)
- ~/hello-rpm$vi src.c
- 패키징 할 spec 파일 생성. (packaging 폴더를 만든 후, "hello-rpm.spec"을 작성합니다.)
- ~/hello-rpm$mkdir packaging
- ~/hello-rpm$vi hello-rpm.spec
- (spec 파일에 대한 설명은 글 하단에 별도로 하겠습니다.)
- 다음과 같은 File Tree를 만들었습니다.
- rpmbuild 사용이 완전히 처음이시라면, Build Fail이 나더라도 1회 수행해서 기본 directory를 생성하도록 합니다.
- ~/hello-rpm$rpmbuild -ba packaging/hello-rpm.spec
~/hello-rpm$ rpmbuild -ba packaging/hello-rpm.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.gEuW8g
+ umask 022
+ cd /home/jwkim/rpmbuild/BUILD
+ cp -a /home/jwkim/rpmbuild/SOURCES/hello-rpm-0.1.tar.gz /home/jwkim/rpmbuild/BUILD/
cp: cannot stat `/home/jwkim/rpmbuild/SOURCES/hello-rpm-0.1.tar.gz': No such file or directory
error: Bad exit status from /var/tmp/rpm-tmp.gEuW8g (%prep)
RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.gEuW8g (%prep)
- 이렇게 하면 home 폴더에 "rpmbuild" 라는 폴더가 생기고 그 밑에 여러 폴더 트리가 구성됩니다.
- 소스코드가 들어있는 hello-rpm 폴더를 압축합니다.
- 위 3의 spec파일의 Source에 명시한대로, 이름-버젼.tar.gz으로 묶습니다.
- $tar zcvf hello-rpm-0.1.tar.gz hello-rpm/
- 해당 파일을 ~/rpmbuild/SOURCE로 이동시킵니다.
- $mv hello-rpm-0.1.tar.gz ~/rpmbuild/SOURCE/
- 이번엔 진짜 빌드를 수행합니다.
- ~/hello-rpm$rpmbuild -ba packaging/hello-rpm.spec
- 에러라는 글자 없이 잘 지나갔으면 성공입니다.
- rpm을 찾아 설치해봅니다.
- $cd ~/rpmbuild/RPMS/<자기 PC 아키텍쳐 폴더>/
- $sudo rpm -ivh --nodeps hello-rpm-0.1-1.<아키텍쳐>.rpm
- -ivh : i가 인스톨, v는 설치내역 상세히 출력, h는 해시 출력
- --nodeps : no-dependency를 의미합니다. 설치시 패키지 의존성 체크를 무시하도록 합니다.
- 잘 설치되었는지 확인
- hello-rpm.bin을 실행해봅니다.
- $hello-rpm.bin
- rpm 명령으로도 확인해 봅니다.
- rpm -qa
- 실습 끝, 패키지 삭제
- $sudo rpm -e hello-rpm-0.1-1.*
#include <stdio.h> int main(int argc, char *agrv[]) { printf("hello\n"); return 0; }
Name: hello-rpm Version: 0.1 Release: 1 Summary: Test rpm-packaging Source: %{name}-%{version}.tar.gz License: N/A %define package_name %{name}-%{version} %description This is my first test about rpm packaging %prep cp -a %_sourcedir/%{package_name}.tar.gz %_builddir/ cd %_builddir tar xvf %{package_name}.tar.gz rm %{package_name}.tar.gz #%setup -q %build gcc -o hello-rpm.bin %{name}/src.c %install rm -rf $RPM_BUILD_ROOT #%make_install mkdir -p $RPM_BUILD_ROOT/%{_bindir} cp hello-rpm.bin $RPM_BUILD_ROOT/%{_bindir}/ %files %{_bindir}/hello-rpm.bin
spec 파일 구문 별 설명
Name: hello-rpm Version: 0.1 Release: 1 Summary: Test rpm-packaging Source: %{name}-%{version}.tar.gz License: N/A %define package_name %{name}-%{version} %description This is my first test about rpm packaging
- Name : 패키지 이름을 기재합니다.
- Version : 버젼입니다.
- 숫자나 하이픈이 막 섞여도 됩니다. (e.g. 1.0.2-rev3)
- Summary : 패키지 요약, 자유롭게 작성
- Source: 소스코드 압축파일 이름으로 이부분 매우 중요합니다.
- fedora의 example에서 %{name}-%{version}.tar.gz로 사용하고 있네요. 권장사항인듯 합니다.
- %{}는 변수들입니다. 본 Sample에서는 hello-rpm-0.1.tar.gz이 됩니다.
- 패키징 전에 지정 folder (default는 ~/rpmbuild/SOURCES/)에 코드를 압축 해 저 이름으로 넣어놓아야 하며,
패키징을 수행하면 저 파일을 압축 풀어 자신을 Build directory로 이동시킵니다. - URL도 기재 가능하다는데, 어떻게 쓰는진 모르겠습니다.
- License : Open Source 등 라이선스 사항을 기재합니다.
- %define 은 C언어의 define과 유사합니다. 변수를 선언할 수 있습니다.
- 위의 "package_name"은 제가 그냥 필요해서 선언했습니다.
- %description
- 패키지 설명입니다. 여러 줄 장문 작성 가능합니다.
%prep cp -a %_sourcedir/%{package_name}.tar.gz %_builddir/ cd %_builddir tar xvf %{package_name}.tar.gz rm %{package_name}.tar.gz #%setup -q
- %prep
- 패키징을 수행하게 되면 이 부분이 먼저 수행됩니다.
- 이 부분에서 ~/rpmbuild/SOURCE/ 에 있는 소스 압축파일을 찾아 ~/rpmbuild/BUILD/에 압축을 풀어놓는 동작을 수행합니다.
- 다음과 같이 pre-define된 변수를 이용할 수 있습니다.
- %_sourcedir : ~/rpmbuild/SOURCE/
- %_builddir : ~/rpmbuild/BUILD/
- "%setup -q" 구문을 주석 처리해 놓았는데, 이것만 있으면 사실 위의 쉘 내용은 필요가 없습니다. 자동으로 수행됩니다. 학습 목적으로 일일이 해보았어요.
- %setup 을 이용하려면 예제의 spec 내용도 살짝 바뀝니다. (직접 공부해보시기 바랍니다.)
- 본 예제에서는 hello-rpm 폴더를 그냥 압축해서 사용하였지만, setup -q를 이용하려면 hello-rpm-<버젼> 폴더로 이름을 변경한 후 압축해야 합니다.
- %setup 에서 <이름>-<버젼>.tar.gz 을 압축 푸는 동작과 압축 푼 후 <이름>-<버젼> 폴더로 이동하는 동작을 포함하고 있기 때문입니다. 폴더 이름이 안 맞으면 에러가 납니다.
%build gcc -o hello-rpm.bin %{name}/src.c %install rm -rf $RPM_BUILD_ROOT #%make_install mkdir -p $RPM_BUILD_ROOT/%{_bindir} cp hello-rpm.bin $RPM_BUILD_ROOT/%{_bindir}/
%files %{_bindir}/hello-rpm.bin
- %build
- 실제 빌드 명령을 기술합니다.
- 보통은 cmake나 make 명령을 여기에 기재합니다.
- 본 예제는 간단하게, 원리를 보여주기 위해 직접 gcc 명령을 칩니다.
- %install
- 실제 설치되는 부분은 아니며, $RPM_BUILD_ROOT 라는 공간에 rpm 설치 후의 동작을 기술합니다.
- $RPM_BUILD_ROOT 를 실제 설치될 타깃 시스템의 root directory (/)로 생각하고 명령을 작성하면 됩니다.
- 저 명령이 수행될 directory는 build가 수행되었던, ~/rpmbuild/BUILD/ 입니다.
- %build 구문에서 생성한 hello-rpm.bin 파일을 설치될 타깃의 /usr/bin/ 에 복사하고 싶으면 cp hello-rpm.bin $RPM_BUILD_ROOT/usr/bin/ 으로 기재할 수 있습니다.
- 위의 예제와 같이 /usr/bin/ 을 직접 기재하기 보다는 %{_bindir}로 pre-define된 변수로 사용함이 좋습니다.
- 실제 타깃에는 /usr/bin/ 디렉토리가 있을테니 그냥 옮기면 되지만, 현재 build root에는 없기 때문에 폴더를 생성하기 위에 mkdir -p 로 디렉토리 생성을 했습니다.
- %files
- 패키지가 설치되면서 생성할 모든 파일들을 기재합니다.
- 본 예제는 /usr/bin에 hello-rpm.bin을 생성할 것이므로 이에 대한 한줄을 기재했습니다.
- %defattr(<file_permission>, <user>, <group>, <directory_permissions>) 를 기재하면 생성할 파일들의 접근 권한을 설정할 수 있습니다.
- e.g. %defattr (755, root, app, -)
- -는 default 설정을 사용한다는 의미입니다.
- 본 구문은 한번만 기재하면 모든 파일에 default로 설정됩니다.
- %attr(<file_permission>, <user>, <group>) 로 각 파일 별 별도 권한 설정도 가능합니다.
- e.g. %attr(644, root, root) /usr/lib/libexample.so
- %post
- 패키지 설치 시점 기준 설치 직후 수행할 쉘 내용을 기재할 수 있습니다.
- e.g.
%post
echo 'Installation complete!' - %postun : 삭제 직후
- %pre : 설치 직전
- %preun : 삭제 직전
참조 : Fedora Project Wiki (https://fedoraproject.org/wiki/How_to_create_an_RPM_package)
'Linux 개발' 카테고리의 다른 글
casync 알아보기 (Content Addressable Data Synchronizer) (0) | 2017.06.28 |
---|---|
Node.js 용 c++ Addon을 gcc로 컴파일하기 (node-gyp 없이) (0) | 2017.06.10 |
표준출력 stderr, stdout 을 파일 등으로 redirection 하기 (0) | 2016.09.18 |
명령어 자동완성을 위한 Bash script 작성 (우분투) (0) | 2016.04.23 |
CMake를 이용한 패키지 빌드 (0) | 2016.04.13 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- content-addressable storage
- Tizen Studio
- NPPi
- gear
- 푸시
- libfuse
- Tizen Emulator
- IOT
- Wearable
- 타이젠
- Samsung Push
- Container
- systemd/casync
- node.js
- Push Service
- content addressable storage
- Push
- Tizen Push
- node-gyp
- casync
- Tizen
- Lennart Poettering
- CUDA
- GCM
- Tizen SDK
- Samsung gear
- Gear S3
- nodejs
- samsung
- Gear s2
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함