Yocto - dependency : $(R)DEPENDS, $RRECOMMANDS, (BAD|NO)_RECOMMENDATIONS, PACKAGE_EXCLUDE

markyang92·2021년 8월 22일
0

yocto

목록 보기
23/53
post-thumbnail

Dependency

  • 대부분의 sw package는 require package list가 있음
    • e.g., make menuconfig 시, ncurses library를 필요로한다.
  • 이러한 dependency는 2개의 메인 카테고리로 나뉜다.
    1. build-time dependency: sw가 빌드될 때, requirement
      • SW가 특정한 라이브러리를 사용할 때
      • e.g.) sw가 pthread, openssl을 필요로 한다면, 그 sw는 pthread, openssl 라이브러리가 없이는 빌드할 수 없다.
    2. rutime dependency: target에서 설치되어, sw가 실행에 필요한 requirement
      • SW가 내부적으로 개별적인 커맨드를 call할 때
        e.g.) lspci
      • SW가 dynamic library를 runtime에서 로딩할 때
        e.g.) dlopen
      • 이들은 빌드할 때는 상관없지만, 실행 동안 필요하다.

Dependency의 특징

  • 의존성이 없는 레시피들은 병렬로 빌드한다.
  • 의존성이 있는 레시피의존성을 만족시키는 방향으로 순차적으로 빌드한다.
  • 레시피가 의존 하는 것: DEPENDS
  • 레시피가 제공 하는 것: PROVIDES
  1. 레시피 foo_1.0.bbbar를 의존한다면, 비트베이크는 bar를 제공하는 모든 레시피를 나열한다.
    1.1. bar의 의존성은 다음에 의해 만족된다.
    1.1.1. bar_<version>.bb 형식의 모든 레시피
    1.1.2. PROVIDES 변수에 bar가 있는 레시피
  2. 하나의 의존성이 여러가지 레시피로 만족될 수 있다.
    2.1. 두 개 의상의 레시피가 PROVIDES += "bar"가 있는 레시피
  3. virtual/kernel프로바이더는 이런 매커니즘이 적용되고 있는 좋은 예이다.
    virtual/<namespace>는 하나의 모듈에 대해 여러 프로바이더가 존재할 때 사용하는 규칙이다.
    빌드를 위해 커널을 필요로하는 모든 레시피는 DEPENDS 변수에 virtual/kernel을 추가할 수 있고, 비트베이크는 이 의존성을 보장한다.
    여러 프로바이더가 있으면 PREFERRED_PROVIDER_virtual/kernel = "linuxmymachine" 처럼 하나를 선택할 수 있다.
    동일한 시스템에서 두 개의 레시피가 같은 의존성을 위해 다른 프로바이더를 사용할 수 없다. 비트베이크가 다른 버전의 두 개의 프로바이더를 갖고 있다면 기본적으로 높은 버전을 사용한다. PREFERRED_VERSION을 사용해 다른 버전을 사용하게 강제할 수 있다. 이러한 경우는 주로 BSP에서 발견되고, 부트로더처럼 벤더가 보드에 따라 다른 버전을 사용하는 경우이다.
    개발 중이거나 안정적이지 않은 버전의 레시피가 있고 이 버전이 기본으로 사용되길 원하지 않으면 DEFAULT_PREFERENCE = "-1"을 레시피에 설정하면된다. 이 경우 버전이 더 높더라도 PREFERRED_VERSION을 통해 명시적으로 버전을 선택하지 않으면 사용되지 않는다.

$DEPENDS

  • DEPENDSbuild-time dependency를 명시한다.
  • 레시피를 빌드하기 전에 빌드할 패키지 목록을 통해 build-time dependency를 지정
  • Recipe내에 DEPENDS가 있으면 먼저 dependency로써, bitbake build 한다.
    • myhellodo_configure 태스크를 실행하기 전, myhellolibdo_populate_sysroot태스크가 수행된다.

DEPENDS 예

1. myhellolib

  • myhellolib_0.1.bb 레시피
DESCRIPTION = "Static library recipe"

LICENSE = "MIT"
LIC_FILES_CHKSUM="file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI="git://XXXXXXX/myhello.git;protocol=ssh;branch=master"
SRCREV="${AUTOREV}"
S="${WORKDIR}/git"

do_compile() {
    ${CC} ${CFLAGS} -c print.c
    ${CC} ${CFLAGS} -c arith.c
    ${AR} rcs libmyhello.a print.o arith.o

}


do_install() {
    install -d ${D}${libdir}
    install -m 0755 libmyhello.a ${D}${libdir}
    install -d ${D}${includedir}
    install -m 0644 mylib.h ${D}${includedir}
}
  • 아직 bitbake build하지 않음

2. myhello

  • myhello_0.8.bb

  • 아래 소스를 보면 알겠지만
  1. print()함수는 mylib.h, libmyhello.a를 필요로함 --> Build Dependency : DEPENDS에 명시
  2. lspci는 --> Runtime Dependency: 그래서 현재 레시피로 build까지는 성공!

  • myhello/userprog_lspic.c
#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
int main(){
    print("myhello component\n",5);
    print("I will use lspci!\n",5);
    system("lspci");
    return 0;
}

$RDPENDS

  • RDPENDSrutime dependency를 명시한다.
  • 현재 패키지를 설치하기 전에 설치할 패키지 목록을 통해 runtime dependency를 지정
  • RDEPENDSRDEPENDS_${PN}=package_name 형식으로 넣어야한다.
    • RDEPENDS_${PN} += "레시피이름"이 아니다!!
    • RDEPENDS_${PN} += "Package_name"이다.
      • RDEPENDSdo_rootfs 태스크에서 final image를 생성할 때, package에 추가되는 것이다.
    • RDEPENDS_${PN} = "T"P.bb에 있다면, Pdo_build task가 depend Tdo_build task로 하여 만들어진다.

  • RDEPENDS_${PN}-dev += "perl"
    요렇게 하면 나(${PN}-dev package) 에서 perl을 참조한다.

RDEPENDS versioning

  • shlibdeps : runtime package가 shared library (.so)를 포함한다면, build process the library in order to determine other libraries to which it is deynamically linked. The Build process adds these libraries to RDEPENDS when creating the runtime package.
  • pcdeps : If the package ships a pkg-config information file, the build process uses this file to add items to the RDEPENDS variable to create the runtime packages.

BitBake, which the OpenEmbedded build system uses, supports specifying versioned dependencies. Although the syntax varies depending on the packaging format, BitBake hides these differences from you. Here is general syntax to specify version with the RDEPENDES variable:

RDEPENDS_${PN} = "package (operator version)"

For operator, you can specify the following:
  =
  <
  >
  <=
  >=
  
For example, the following sets up a dependency on version 1.2 or greater of the package foo:
  RDEPENDS_${PN} = "foo (>= 1.2)"

RDEPENDS 예

1. myhello 내 lspci

  1. $ lspci 명령어
  • 장비에 장착된 RAID 카드 / HBA 카드 / VGA카드 / USB Controller / NIC 등 메인보드의 주변 장치 종류와 정보를 확인하기 위해서 사용됨
➜  build git:(dunfell) ✗ lspci
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (rev 05)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x16) (rev 05)
00:01.1 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x8) (rev 05)
00:01.2 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x4) (rev 05)
00:08.0 System peripheral: Intel Corporation Xeon E3-1200 v5/v6 / E3-1500 v5 / 6th/7th/8th Gen Core Processor Gaussian Mixture Model
...
중략
  • lspci를 사용하는 프로그램은 runtime dependency라 build는 되지만 qemu에서 lspci: command not found
  • RDEPENDS는 RDEPENDS_${PN}=package_name 형식으로 넣어야한다.

0-1. myhello 컴포넌트의 src인 userprog_lspci.c

#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
int main(){
    print("myhello component\n",5);
    print("I will use lspci!\n",5);
    system("lspci");
    return 0;
}

0-2. myhello 컴포넌트 레시피


0-3. RDEPENDS_${PN}=package_name 형식으로 넣어야 하기 때문에, 현재 컴포넌트에서 어떤 패키지가 RDEPENDS를 요구하는지 볼 것

  • 현재 RDEPENDS에서 요구하는 프로그램이 어디 패키지에 있는가?
  1. userprog_lspic 바이너리에서 필요로한다.
  2. ${WORKDIR}/packages-split 에서 보자.
  3. RDEPENDS_${PN} 하면 되겟네

  1. RDEPENDS_${PN}="pciutils" 로 RDEPENDS를 걸어준다.
    1-1. myhello 컴포넌트 레시피

  1. myhello 컴포넌트를 사용하는 간단한 image를 만들어본다.

  1. runqemu
$ runqemu core-image-minimal-tiny

3-1. /usr/lib


3-2. /usr/bin


3-3. 실행


$RRECOMMENDS

  • RRECOMMENDSsoft, RDEPENDS 라 생각하면 된다. 따라서 필수 requirement는 아니다.

RRECOMMENDS 예

packagegroup-dhyang.bb, lshw

  • my packagegroup인 packagegroup-dhyang.bbRRECOMMENDS를 사용해보자.
    • RRECOMMENDS_${PN}: 빌드할 패키지 리스트
  • RRECOMMENDS_${PN} = "lshw" 패키지를 명시해보았다.
$ bitbake packagegroup-dhyang
  • meta-oe layer가 추가되어 있지 않으면 ERROR 발생할 것임

  • 본 블로그 layer search site 에서 OpenEmbedded에 들어가 mata-openembedded layer clone
    git://git.openembedded.org/meta-openembedded

    내부에 많은 meta-* 레이어들이 있음 그중 meta-oe만 사용할 것임 (lshw 컴포넌트가 meta-oe 에만 있어서...)

  • 본인은 poky를 dunfell 버전 사용하므로, 이 레이어도 dunfell 버전으로 맞추기
    $ git checkout dunfell

  • build 디렉토리인 ${TOPDIR}에서 conf/bblayers.conf에서 meta-oe 를 추가한다.

  • 이렇게 하면 다시 packagegroup-dhyangbitbake build 될 것이다.
$ bitbake packagegroup-dhyang

  • Custom Image에 'packagegroup-dhyang'을 IMAGE_INSTALL에 추가하고 bitbake build, runqemu
  • lshw 명령어가 잘 먹는다.

RRECOMMEND 를 막는 변수

NO_RECOMMENDATIONS

NO_RECOMMENDATIONS = "1"
  • NO_RECOMMENDATIONS = "1" 로 set하면, 모든 recommended-only packages의 설치를 막는다.
  • ${TOPDIR}/conf/local.conf에 이 변수를 set하면, global하게 적용된다.

BAD_RECOMMENDATIONS

BAD_RECOMMENDATIONS = "package_name package_name ..."
  • BAD_RECOMMENDATIONS = "package_name package_name ..."특정 recommended-only package 설치를 막는다.

PACKAGE_EXCLUDE

PACKAGE_EXCLUDE = "package_name package_name ... "
  • image에 install 하지 않을 패키지를 지정한다.
  • 당연히 RDEPENDS에 리스트된 것이면 build 시, fatal installation error 발생

Dependency Version

DEPENDS = "package (>= 1.2)"
RDEPENDS_${PN} = "package (>= 2.1)"

과 같이 버전을 지정할 수 있다.

  • 사용할 수 있는 operator는 다음과 같다.
    • =, >, <, >=, <=
  • 당연히 버전은 레시피.major.minor 이다.

Recipe Dependency 정보

$ bitbake -g recipe

  • 레시피에 dependency 정보를 생성할 수 있다.
$ bitbake -g recipename

위 커맨드는 '현재 build'에서 다음의 파일을 생성해 Write한다.


pn-buildlist

  • 위 명령에 의해, myhello 컴포넌트에 의해 빌드되는 레시피이름
    • 위에서 RDEPENDS로 걸어둔 pciutils도 보인다.

task-depends.dot

  • 태스크간 디펜던시를 그래프로 보여줌
  • DOT format 임. Graphviz tool 필요


'myhello'등만 남겨뒀는데 엄청나게 복잡한 디펜던시..가 보인다.


dot -> pdf

$ dot -Tpdf task-depends.dot -o outfile.pdf

로 변환할 수 있다.

$ evince outfile.pdf


띄운 pdf 파일인데 겁나 복잡하다...


$ bitbake -g -u taskexp recipe

  • 이 커맨드는 buildtime, runtime dependency를 GUI windows로 보여줌
$ bitbake -g -u taskexp core-image-minimal-tiny
  • 사용 파이썬 버전: python 2.7.18
    • 사용 파이썬 패키지: gi
      • 패키시 설치 커맨드: python2 -m pip install (gi|pgi)

profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글