yocto - do_package(), package에 관해

markyang92·2021년 6월 10일
1

yocto

목록 보기
9/53
post-thumbnail

do_package()

  • basic task flow
  • 개요
    • do_package()는 레시피의 ${D} 디렉토리를 Source로 사용한다.
      • ${D}do_install()의 결과이다.
      • ${D}default로, ${D}=${WORKDIR}/image이다.
    • 이, image 디렉토리에 생성된 결과를 이용한다.
  • 주의! libmyhello 가 제일 앞에 매칭되고, FILE_libmyhello = 에서 너무 많이 가져가버리면, 다른 패키지가 쓸게 없음


package

  • oe-core/meta/recipes-bsp/u-boot의 예:
    • u-boot${WORKDIR}

  • ${D}를 이용해
  1. do_package(): ${D}(${WORKDIR}/image) -> package
  • ${D} = "${WORKDIR}/image"
  • ${WORKDIR}/package

  1. do_package() : 아래의 PACKAGES 변수 내 지정된 값으로 packages-split 내부에 디렉토리들 생성한다.
  • ${WORKDIR}/packages-split

  • do_packagedata() :
    • do_populate_sysroot() 가 하위 태스크로 실행된다.
    • 더 자세한, 하위 태스크:
    • do_populate_ipk()local.conf에서
      PACKAGE_CLASSES = "package_ipk"로 설정했기 때문에 실행되는 것이다.

PACKAGES 변수

  • 사용 변수: PACKAGES
    • PACKAGES변수에는 global-PACKAGES, local-PACKAGES 가 있다. (가칭임)
    • PACKAGES 변수가 package-split에서 directory를 생성한다.

global-PACKAGES

  • global-PACKAGES는 말그대로, bitbake build에서 default로 설정되어 있는 PACKAGES 값이다.
    • 당연히 local.conf등에서 수정가능하다.
$ bitbake -e | egrep "^PACKAGES="
PACKAGES="defaultpkgname-src defaultpkgname-dbg defaultpkgname-staticdev defaultpkgname-dev defaultpkgname-doc defaultpkgname-locale  defaultpkgname"
  • 이렇게 먹힌다.
${PN}-deb ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}

local-PACKAGES

  • local-PACKAGES는 한 레시피에서 append 하는 것이다.
  • u-boot레시피 에서의 예
PACKAGE_BEFORE_PN += "${PN}-env ${PN}-extlinux"

packages-split

  • ${WORKDIR}/packages-split: global-PACKAGES + local-PACKAGES append 로 directory 생성됨

$FILES_${PN} 변수

  • do_package() 태스크에서 package-split을 구성할 때, ${FILES} 변수가 사용된다.
    • FILES 변수는, (이전에 PACKAGES변수가 package-split내부 디렉토리를 만들었다면)
      내부에 파일들이 위치할 장소가 명시된다.
    • 즉, ${FILES}_${PN}을 보고 위치시킨다.

  • 변수 확인
$ bitbake -e | egrep "^FILES_*"
$ bitbake -e myhello | egrep "^FILES_*"
  • 결국 PACKAGES에서 들어갈 디렉토리는 FILES와 융합되어 들어가는 것임
    • AND 느낌으로 첫 매칭되면 바로 들어감


$FILES_ 변수 테이블

  • PACKAGES나, FILES를 건들이지 않은 기본적인 FILES의 테이블
FILES_path
FILES:${PN}/usr/bin/*
/usr/sbin/*
/usr/libexec/*
/usr/lib/lib*.so.*
/etc
/com
/var
/bin/*
/sbin/*
/lib/*.so.*
/lib/udev
/usr/lib/udev
/lib/udev
/usr/lib/udev
/usr/share/${PN}
/usr/lib/${PN}/*
/usr/share/pixmaps
/usr/share/applications
/usr/share/idl
/usr/share/omf
/usr/share/sounds
/usr/lib/bonobo/servers
FILES:${PN}-bin
PACKAGES:${PN}-bin이 없는 경우가 많음
PACKAGES:${PN}에 흡수됨
/usr/bin/*
/usr/sbin/*
FILES:${PN}-dbg/usr/lib/debug
/usr/lib/debug-static
/usr/src/debug
FILES:${PN}-dev/usr/include
/lib/lib*.so
/usr/lib/lib*.so
/usr/lib/*.la
/usr/lib/*.o
/usr/lib/pkgconfig
/usr/share/pkgconfig
/usr/share/aclocal
/lib/*.o
/usr/lib/defaultpkgname/*.la
/lib/*.la
/usr/lib/cmake
/usr/share/cmake
FILES:${PN}-doc/usr/share/doc
/usr/share/man
/usr/share/info
/usr/share/gtk-doc
/usr/share/gnome/help
FILES:${PN}-locale/usr/share/locale
FILES:${PN}-src-
FILES:${PN}-staticdev/usr/lib/*.a
/lib/*.a
/usr/lib/defaultpkgname/*.a
FILES_SOLIBSDEV/lib/lib*.so
/usr/lib/lib*.so

Custom-Package 만들어보기

  1. packages-split${PN}-libmyhello 생성
  2. ${PN}-libmyhello에 들어갈 파일은 ${bindir}/*, {docdir}/*
  3. do_install()과정에서 원하는 파일이 ${bindir}/*, {docdir}/*에 잘들어가면 상관 없지만,
    그렇지 않을 수도 있으니 Specific 하게 do_install()에서 명시
  4. 확인
$ bitbake -e myhello | grep ^PACKAGES

$ bitbake -e myhello | grep ^FILES_

  1. 확인

Package

  • 패키지: 하나의 Component => 다수의 패키지
    • 레시피가 생성한 모든 패키지는 레시피 변수내 리스트되어 있음
    • 지원 패키지 형식
      • .rpm: 레드햇 계열 패키지. SuSE, OpenSuSE, Red Hat, Fedora, CentOS 등의 배포판에서 사용
      • .deb: 데비안 계열 패키지. Ubuntu 등의 데비안 계열 배포판에서 사용
      • .ipk: 잇시 패키지 관리 시스템(Itsy Package Management System). 데비안 패키지 형식을 닮은 임베디드 디바이스를 위한 경량화 패키지 관리 시스템
        요즘은 OpenMoko에서 만들어진 Opkg로 많이 넘어감. oe-core에서 Opkgipk 지원을 위해 사용한다.
      • .tar: 타르볼 파일

$PACKAGE_CLASSES

  • build/conf/local.conf에서 PACKAGE_CLASSES 변수에서 패키지 형식 지정한다. (여러 개 가능)
    • 주의: imagePACKAGE_CLASSES에 정의된 첫 번째 형식으로 만들어진다.
  • package_deb, package_ipk, package_rpm 을 선택 가능하다.

$PACKAGES 변수

(global)PACKAGES

  • PACKAGES 변수: 레시피가 생성하는 패키지 리스트
  • PACKAGES 변수는 global, component local 이 있다.(가칭임)
    • PACKAGES 변수에따라, 기본적인 (global) PACKAGES
    • bitbake.conf에 (global) PACKAGES가 default로 set되어 있다.
    • ${PN}-deb ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}
  • Check for PACKAGES variable in all over bitbake build environment
$ bitbake -e | egrep "^PACKAGES="

(local)PACKAGES

  • 특정 component에서 localPACKAGES 변수를 셋팅할 수 있다.
  • check for PACKAGES variable of specific component
$ bitbake -e <COMPONENT> | egrep "^PACKAGES="
  • PACKAGES의 기본 값: ${PN}-deb ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}

레시피에서 패키지 지정

  • meta/recipes-multimedia/libtiff/tiff_4.0.10.bb 레시피가 있다.
  1. meta(layer) / recipes-multimedia (멀티미디어 관련 레시피들) / libtiff (컴포넌트) / tiff_4.0.10.bb (컴포넌트 레시피)

  2. PACKAGES 에서 만들 패키지 이름 지정
PACKAGES =+ "tiffxx tiff-utils"
  • 컴포넌트에 의해 tiffxx tiff-utils 라는 두 가지 패키지 생성된다.

단일 library가 생성되는 경우 자동 package 생성

  • 예를들어, openembedded/meta/recipes-devtools/json-c/json-c_0.15.bb 와 같은 레시피를 보자.
  • 내부에, PACKAGES += "libcjson-c5"가 없는데,
  • 위 처럼, libjson-c5.ipk가 자동 생성된다. 이러한 경우는, library만 생성하는 레시피의 경우 PACKAGES += "라이브러리이름'버전'"를 자동 추가해서 넣어준다.

bitbake에 의해 생성되는 pkgs

packages-split

  • 컴포넌트를 bitbake build 생성물인 ${WORKDIR}로 가면 packages-split 이 있다.
    • PACKAGES 변수에 담긴대로 naming된 디렉토리들이 있다.
  1. packages-split 내부

$PACKAGES

3-1. PACKAGES변수 확인

$ bitbake -e | grep "^PACKAGES="		# bitbake에서 global PACKAGES variable
$ bitbake -e myhello | grep "^PACKAGES="	# myhello 컴포넌트에서 PACKAGES variable

do_package()에서 PACKAGES 변수 내 지정된 값으로 packages-split 내부에 디렉토리들 생성한다.

  • PACKAGES 변수
    • ${PN}
    • ${PN}-src
    • ${PN}-dbg
    • ${PN}-staticdev
    • ${PN}-dev
    • ${PN}-doc
    • ${PN}-locale

$FILES_${PN}

3-2. FILES_${PN} 변수 확인

$ bitbake -e | egrep "^FILES_*"			# bitbake에서 global FILE_* variable
$ bitbake -e myhello | egrep "^FILES_myhello="	# bitbake에서 myhello 컴포넌트의 FILE_myhello variable

  • 위 변수들은 meta/conf/bitbake.conf에 있다.

  • 예제로 하는 myhello 컴포넌트에 대해 FILES를 찍어보자
$ bitbake -e myhello | grep "^FILES_myhello"

  • FILES_myhello="/usr/bin* /usr/sbin/* /usr/libexec/* /usr/lib/lib*.so* ..."로 되어 있다.
  • FILES_myhello-dbg="/usr/lib/debug ... "로 되어 있다.
    이는 이 컴포넌트가 pkg를 만들 때 packages-split 에서 내부에 파일들이 위치할 장소가 명시된다.
    본 블로그에서 packages-split을 살펴 봤는 데, 아래와 같이 $PACKAGES$FILES과 엮이게 된다.

  1. 즉, package를 만들 때, $PACKAGES를 보고 packages-split 에서 구성하는데,
    1-1. packages-split /${PN}-*을 구성할 때, $FILES_{PN}-* 을 참고하여 매칭이되면
    1-2. 해당 packages-split /${PN}-*에 위치시킴

  1. FILES_${PN}, FILES_${PN}-dbg 에서 사용하는 경로가 같다면?
    레시피 에서, 아래와 같이 설정되있다고 가정한다.
do_install() {
	${CC} userprog.c ${LDFLAGS} -o ${bindir}/userprog
}

FILES_${PN}-dbg += "${bindir}/userprog"
FILES_${PN} += "${bindir}/userprog"

2.1 아래와 같이 첫 번째 FILES_${PN}FILES_${PN}-dbg 에 먹힌다.


2.2 즉, FILES 값에 매치되는 첫 번째 패키지에 파일들이 간다!


Readme.txt 예로 PACKAGES, FILES 관계 보기

  1. component에 Readme.txt를 추가해보자!
    1.1 예제로 쓰는 'myhello' component 디렉토리 (git으로 관리함)

    1.2 간단하게 Readme.txt파일을 추가한다.

    1.3 알아서 remote server에 push 하고..

  1. component의 recipe를 수정해야한다.
    2.1 poky/meta-mylayer/recipes-myrecipes/myhello/myhello_0.4.bb (혼동하지말자.. 여기는 '레시피'파일)

    2.2 레시피에서 do_fetch() 에서 fetch한 파일은 ${S} = "${WORKDIR}/git"에 fetch된다.
    2.3 레시피에서 do_install()에서 ${S}/Readme.txt${D}${docdir}로 옮긴다.
    2.4 빌드
$ bitbake myhello

  • 결과물
  1. ${D}${docdir}= ${WORKDIR}/image${docdir}/Readme.txt 생성

  1. ${WORKDIR}/packages ${docdir}/Readme.txt 생성

  1. ${WORKDIR}/pakcages-split / myhello-doc${docdir}/Readme.txt 생성


custom-package 만들기

  • 어짜피 package는 ${WORKDIR}/packages <- ${WORKDIR}/image 들어간다.
  • 나눠 지는 것은 ${WORKDIR}/packages-split
  1. source
    1-1. git: git://github.com/markyang92/myhello.git

  1. recipe

    2-1. 레시피에 PACKAGES =+ "libmyhello" FILES_libmyhello = "${bindir}/* ${docdir}/*" 삽입

  1. bitbake에 찍히는 결과 보기
    3-1. bitbake -e myhello | grep ^FILES_
    3-2. bitbake -e myhello | grep ^PACKAGES

  1. build
    4-1. $ bitbake myhello
    4-2. packages-split 에 가면 libmyhello 패키지가 잘 만들어짐

$ALLOW_EMPTY

  • 기본적으로 bitbake는 빈 패키지를 만들지 않는다.
    • 패키지의 존재 유무가 RDEPENDS / runtime requirement에 영향을 끼칠 수 있기 때문이다.
  • ALLOW_EMPTY 변수는 비었음에도 불구하고 결과 패키지를 생성할 것인지 지정한다.
ALLOW_EMPTY_${PN} = "1"
ALLOW_EMPTY_${PN}-dev = "1"
ALLOW_EMPTY_${PN}-staticdev = "1"

  1. packages-split/${PN}-staticdev 패키지만 존재

  1. ${WORKDIR}/deploy-rpms/

  1. Custom Image에 저 패키지만 설치

  1. dependency 문제

  1. 빈 패키지라도 만들어라 설정.

  1. ${PN}-${PV}-${PR}.arch.rpm으로 생성

  1. custom image 생성 완료

$PACKAGE_CLASSES 의한 패키징

deploy-{rpms, debs}

  • 위 본문에서 $PACKAGE_CLASSES 변수 (build/conf/local.conf)에서 패키지 형식을 지정 한다고 했는데, 기본적으로 .rpm 이므로 아래의 환경처럼 패키징이된다.
  1. ${WORKDIR}/deploy-${PACKAGE_CLASSES}
profile
pllpokko@alumni.kaist.ac.kr

2개의 댓글

comment-user-thumbnail
2022년 12월 28일

근데 근본적인 질문이 있는데요... 이 packaging split 을 왜하는건가요...?
그리고 저 만들어진 결과의 rpm 은 어떻게 쓰이나요?ㅜㅜ
마지막에 rootfs이미지 만들때 쓰이는건가요:?;

1개의 답글