yocto - recipe 작성 1. do_fetch(), do_unpack(), do_patch(), license, source_mirror관련

markyang92·2021년 6월 21일
0

yocto

목록 보기
6/53
post-thumbnail

recipe 이름 설정

  • Package Name, Package Version, .bb .bbappend
${PN}_${PV}.bb
bbexample_0.0.1.bb
bbexample_0.0.1.bbappend
  • Yocto는 ${PN}이 같은 경우, ${PV}높을 것을 자동 적용한다.

base Task flow

  • 하나의 레시피에 대해 그냥 build 하면 아래의 태스크 플로우로 진행된다.
    • base.bbclassimplicitly inherit

task                            description
do_fetch()소스코드를 fetch한다.
do_unpack()소스코드를 working directoryunpack한다.
do_patch()patch파일 위치, 적용시킴
do_configure()any build time에 enable/disable에 의한 소스코드 configure와, 빌드되는 소프트웨어용 configure option을 configure한다.
do_compile()compilation directory의 소스를 컴파일
do_install()compilation directory에서 holding area로 파일을 복사
do_package()holding area 내용을 분석, subset으로 나눈다.
do_package_with_rpm()rpm 패키지를 생성하고 그것을 package feed area에 둔다.
do_rootfs()rootfs 이미지를 생성한다.
do_build()build를 하는 태스크. 가장 기본이다.

초기 필수 변수

SUMMARY, SECTION, LICENSE

SUMMARY = "TEST"
SECTION = "TEST"
LICENSE = "CLOSED"
  • meta-mylayer/recipes-example/myhello/myhello_0.1.bb
    • 위 예제는 1)SUMMARY, 2)SECTION, 3)LICENSE 라는 변수를 선언한다.

LICENSE

  • 해당 컴포넌트가 사용할 라이선스 지정
  • LICENSE 미사용일 경우: CLOSED
LICENSE = "CLOSED"

LIC_FILES_CHKSUM

  • LICENSE = "CLOSED"가 아니라면, 해당 컴포넌트는 라이선스를 가질 것이다.
    그렇다면, 라이선스 파일이 있을 것이고, 그에 대한 체크섬을 미리 지정한다.
  • LIC_FILES_CHKSUM 변수는 라이선스 파일 체크섬을 확인하는 변수이다.

Yocto에서 제공해주는 라이선스를 사용할 경우

  • openembedded-core/meta/files/common-licenses/에 많은 라이선스 파일들이 있다.
    • 해당 디렉토리는 ${COMMON_LICENSE_DIR} 변수로 미리 지정되어 있다.
    • Yocto에서 제공해주는 MIT 라이선스를 사용하고 싶다면 아래와 같이
      • LICENSE = "MIT"
      • LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5="md5sum" 을 지정해 사용한다.
      • Yocto는 라이선스의 체크섬을 확인 할 것이다.

자체 소스에서 라이선스를 제공하는 경우

  • 자체 Source에서, COPYING, LICENSE와 같은 파일을 가지면서 제공해주는 경우 (가장 일반적)
    • 라이선스 문구 수정 등으로 법적 의무가 변할 수 있기 때문에, 개발자는 이런 변화를 검토하고 이해해야하는 것이 중요하다.
    • 라이선스 체크섬이 다를 경우 yocto는 이를 감지해 bitbake error를 유발하고, 라이선스가 변경된 프로젝트를 가리킨다.
    • 다시 빌드하기 위해선, 라이선스를 다시 잘 읽어보고 타당하다면, 라이선스 체크섬 값을 바꾼다.
  • gnu/hello 오픈소스를 사용한다고 가정하자.
    $ sha256sum ./COPYING
    8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903  ./COPYING
    sha256 체크섬을 구하고 레시피를 작성해보자.

do_fetch, do_unpack, do_patch 개요

  • u-boot 레시피의 ${WORKDIR}
  • u-boot 레시피의 ${S}
  • u-boot 레시피의 ${WORKDIR}
  • 즉, do_fetch, do_unpack, do_patch${S}에 밀어 넣는 과정이다.

+) devshell

  • 나중에 배울 devshell 태스크는 이러한 do_fetch, do_unpack, do_patch가 끝난 후, ${S} 에서 bitbake 변수들이 먹힌 상태에서 동작한다.
$ bitbake u-boot -c devshell

  • 이 상황에서 ${S} 위에서 bitbake shell이 먹힌 상황에서 동작한다.
  • 추후에 Build는 ${B} 변수에 지정된 디렉토리에서 한다.
    u-boot레시피의 경우 위와 같다.

do_fetch()

  • ${SRC_URI}에서 지정된 소스가 로컬에 다운로드 되어있는가?(${DL_DIR}에!)
    • 없다면!!! PREMIRROR, MIRROR 등도 보면서 소스를 다운 로.컬.에 다운받는다.
  • 레시피 빌드 시, 필요한 모든 파일은 ${WORKDIR}에 정의된 디렉토리에 있어야한다. 그래서 그전에 ${DL_DIR}에 다운되어 있는가...? 하는거다...그래서 있다면 캐싱한다.

source fetch 순서

  1. 현재 사용중인 bitbake의 '${DL_DIR}' (해당 bitbake가 사용 중인 build/conf/local.conf${DL_DIR} 변수) 에 SRC_URI에 명시된 소스 파일이 already download 되었는지 확인

1.1 tarball 일 경우, ${DL_DIR}/[file].tar.gz에 받아, done으로 받아져 있는지 유무확인

  • .done 확인 -> md5 checksum 확인 -> 맞으면 레시피에서 명시한 ${S} 위치로 Copy

1.2 git 에서 받을 경우, ${DL_DIR}/git2/에 받아, done으로 받아져 있는지 유무 확인

  • 레시피가 아래와 같다.
  • .done확인 -> 레시피에서 명시한 ${S}="${WORKDIR}/git" 위치로 Copy

  1. ${DL_DIR}에 없다면, Download
  • 없다면, 새로 현재 사용중인 bitbake의 ${DL_DIR}(해당 bitbake가 사용 중인 build/conf/local.conf${DL_DIR} 변수) 에 Download

Priority, 미러 설정

  • recipe소스를 가져오는 방법은 정말 다양하다.
    • 우선 .done 파일을 찾는 것이 목표다.
  • bitbake는 아래의 순서로 소스를 받아온다.
priorityVariable                                                             Description
1DL_DIR = "${HOME}/common_downloads"
  • rw 권한 필요
  • local로 '저장'해야하기 때문
  • 2SOURCE_MIRROR_URL = "http://myhome/common_downloads/"
    INHERIT += "own-mirrors"

    SOURCE_MIRROR_URL = "file:///home/you/your-mirror-dir/"
    INHERIT += "own-mirrors"
  • 경로 하나만 설정한다.
  • 여기서 .done
  • 2PREMIRRORS
  • 빌드 시스템이 깃, FTP, HTTP, HTTPS 요청을 만나면
    이를 명시한 미러 저장소로 돌려준다.
  • 3SRC_URI
    당연히, Recipe에서 지정되어 있음
    SRC_URI = "git://...." 이면, local의 .gitconfig에서 설정한 대체 URI를 사용할 수 있다.
    4MIRRORS

    소스 관련 추가 변수

    VariableDescription
    BB_GENERATE_MIRROR_TARBALLS = "1"빌드 시스템에 PREMIRRORS를 위한 tar 생성
    미러 서버를 만들기에는 유용하다
    미러 서버를 만드려는 게 아닌 빌드 목적이면 시간 낭비
    BB_FETCH_PREMIRRORONLY = "1"빌드 시스템이 PREMIRRORS 에서만 소스를 가져옴
    이외에는 실패
    BB_NO_NETWORK = "1"bitbake가 인터넷 액세스가 필요한 동작을 만나면 오류 발생
    로컬 소스로만 코드를 빌드 하려는 경우에 사용

    SRC_URI

    • SRC_URI: 소스 경로
      • '소스'를 어디서 받아오거나? Copy해오거나? 를 정함

    지원하는 URI 프로토콜

    Protocol        Description
    az://Fetches files from an Azure Storage account using HTTPS.
    bzr://Fetches files from a Bazaar revision control repository.
    ccrc://Fetches files from a ClearCase repository.
    cvs://Fetches files from a CVS revision control repository.
    file://
  • "file:///absolute/path/tofile/"
  • "file://relative/path/to/file"
  • "file://*/*.patch"

  • 1. FILESPATH는 콜론(:)으로 구분된 경로의 목록을 갖는다. fetcher는 목록의 첫 경로부터 시작해서 파일을 검색한다. 처음 맞는 파일이 나타날 때까지 각 디렉토리를 검색한다. 해당 이름을 갖는 파일이 여러 디렉토리에 있다면 fetcher는 처음 찾은 것을 받는다.
    2. 위 경로에서 어느 것도 해당되지 않는다면, 변수 FILESDIR이 설정돼 있는지 검사한다.

    Fetches files, which are usually files shipped with the Metadata, from the local machine.
    The path is relative to the FILESPATH variable.
    Thus, the build system searches, in order, from the following directories,
    which are assumed to be a subdirectories of the directory
    in which the recipe file (.bb) or append file (.bbappend) resides
    ftp://Fetches files from the Internet using FTP.
    git://Fetches files from a Git revision control repository.
    gitsm://Fetches submodules from a Git revision control repository.
    hg://Fetches files from a Mercurial (hg) revision control repository.
    http://Fetches files from the Internet using HTTP.
    https://Fetches files from the Internet using HTTPS.
    npm://Fetches JavaScript modules from a registry.
    osc://Fetches files from an OSC (OpenSUSE Build service) revision control repository.
    p4://Fetches files from a Perforce (p4) revision control repository.
    repo://Fetches files from a repo (Git) repository.
    ssh://Fetches files from a secure shell.
    svn://Fetches files from a Subversion (svn) revision control repository.

    지원하는 서브 변수

    sub variableDescription
    name서브 이름 붙인다.
    unpackURL component를 unpack할 것인지 다룬다.

  • unpack=1 이 기본 값이고, component는 압축풀기가 수행된다.
  • unpack=0 이면, component를 압축 풀지 않는다.
  • dos.zip, .jar 파일에 적용하고 텍스트 파일에 DOS 줄 끝 변환을 사용할지 여부를 지정합니다.
    striplevel추출 시 파일 이름에서 지정된 수의 선행 구성요소(수준)를 제거합니다.
    subdirspecific URL, 지정된 루트 디렉토리를 포함해, 특정 subdirectory에 unpack한다. 예제는 아래와 같다.

    SRC_URIfile://

    • SRC_URI = "file:///Users/hello"
      SRC_URI = "file://relativefile.patch"
    • 절대경로, 상대경로 다 줄 수 있다.
    • ${FILESPATH}에 포함된 경로에서 찾을 수 있다.
      • 여기서 찾지 못하면 download() 메서드 호출로, ${DL_DIR}에서 찾을 수 있다.
    • directory를 명시하면, directory 전체unpack된다.

    SRC_URI = "file://" + S


    SRC_URI: "http{,s}://, ftp://"

    • SRC_URI: http{,s}://, ftp://에서 파일을 받는 경우
      • wget으로 받는다.
      • fetcherdownloadfilename 파라미터를 지원해, 다운로드 파일을 지정할 수 있다. 다운로드된 파일 이름을 지정하는 것은 DL_DIR 충돌을 피하면서, 하나의 이름으로 여러 파일을 다룰 수 있다.


    압축 파일 일 경우

    • git url을 제외하고는, bitbake는 일반적인 unpack을 수행한다.
      • SRC_URI에, .Z, .z, .gz, .xz, .zip, .jar, .ipk, .rpm. .srpm, .deb, .bz2 extensions as well as various combinations of tarball extensions 파일일 경우, do_unpack은 automatically decompress 및 extracts를 수행함
    • wget으로 .tar.gz와 같은 압축 파일을 받는 경우, ${S}를 지정하지 않아도 알아서 unpack 후, 빌드해야할 위치로 checkout하기 때문에, 따로 ${S}를 지정하는 것은 생략하자.

    SRC_URI = "git"

    • protocol: git, branch: master, commit: 브랜치의 최신
      • SRC_URI= "git://.../<REPO>.git;protocol=git;branch=master"
      • SRCREV= "${AUTOREV}"
    • 오픈 소스라면, AUTOREV 사용을 지양한다. (버전 관리가 매우 힘듬)
    • protocol: git, branch: master, tag = 'myv2.1.1
      • SRC_URI= "git://.../<REPO>.git;protocol=git;branch=master"
        • # matches tag myv2.1.1
      • SRCREV= "<commit_hash>"
      • PV= "2.1.1"
    • do_fetch task 때, ${DL_DIR}/git2/ 경로로 clone 된다.
    • SRCREV 변수는 do_fetch 태스크에서 저장소가 현재 깃 리비전을 확인하고, do_unpack task에서 리비전이 맞지 않은 경우, 해당 버전으로 변경하기 위해 사용된다.
    parameter                         Description
    nocheckoutTells the fetcher to not checkout source code when unpacking when set to “1”. Set this option for the URL where there is a custom routine to checkout code. The default is “0”.
    rebaseableIndicates that the upstream Git repository can be rebased. You should set this parameter to “1” if revisions can become detached from branches. In this case, the source mirror tarball is done per revision, which has a loss of efficiency. Rebasing the upstream Git repository could cause the current revision to disappear from the upstream repository. This option reminds the fetcher to preserve the local cache carefully for future use. The default value for this parameter is “0”.
    nobranchTells the fetcher to not check the SHA validation for the branch when set to “1”. The default is “0”. Set this option for the recipe that refers to the commit that is valid for a tag instead of the branch.
    barecloneTells the fetcher to clone a bare clone into the destination directory without checking out a working tree. Only the raw Git metadata is provided. This parameter implies the “nocheckout” parameter as well.
    branchThe branch(es) of the Git tree to clone. Unless “nobranch” is set to “1”, this is a mandatory parameter. The number of branch parameters must match the number of name parameters.
    revThe revision to use for the checkout. The default is “master”.
    tagSpecifies a tag to use for the checkout.
    To correctly resolve tags, BitBake must access the network.
    For that reason, tags are often not used. As far as Git is concerned, the “tag”
    parameter behaves effectively the same as the “rev” parameter.
    subpathLimits the checkout to a specific subpath of the tree. By default, the whole tree is checked out.
    destsuffixThe name of the path in which to place the checkout. By default, the path is git/.
    useheadEnables local git:// URLs to use the current branch HEAD as the revision for use with AUTOREV. The “usehead” parameter implies no branch and only works when the transfer protocol is file://.

    SRCPV: SRCREV = "${AUTOREV}"를 지양한다.

    • SRCREV = "${AUTOREV}" 사용을 지양해야한다면, SRCPV를 사용한다.
      SRCPV = "${@bb.fetch2.get_srcrev(d)}"meta/conf/bitbake.conf에 지정되어 있다.

    SRC_URI = "crate://"

    • Rust에서, crate://를 서브모듈 fetch용으로 사용한다.
      • 이 것들은 rust libraries, programs to compile
      • 이러한 crates는 일반적으로 https://crates.io/ 에서 공유된다. 하지만, 이 fetcher는 다른 crate registries too.
    SRC_URI = "crate://REGISTRY/NAME/VERSION"
    SRC_URI = "crate://crates.io/glob/0.2.11"
    

    do_unpack()

    do_unpack task의 역할

    1. 컴포넌트 레시피에서 SRC_URI= git:// 일 경우, SRCREV가 지정한 버전으로 리비전

    SRC_URI + SRCREV

    • SRC_URI: fetch할 곳
      • git에서 가져올 경우 GIT_URL, branch까지 지정
    • S: Source를 둘 위치
    • SRCREV: SRC_URI에서 지정한 git repo의 branch에서 branch의 최신을 사용할 것인지, 예전꺼 사용할 것인지 결정
      • SRCREV="${AUTOREV}": SRC_URI에 지정된 repository에서 지정된 브랜치에서 최신 source revision 사용
      • SRCREV="SHA1 커밋 해시 값": fixed revision, 커밋 해시 고정
    SRC_URI                    e.g.,                                                                                  S                                         
    local file
    (files 디렉토리)
    SRC_URI = "file://file1 file://file2 ... "S = "${WORKDIR}"
    git 사용 시,SRC_URI = "<GIT_URL>;protocol=<PROTOCOL>[;branch=<BRANCH>]"S = "${WORKDIR}/git"
    tar 를 다운 시,SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.gz2;name=busybox"S = "${WORKDIR}/busybox"

    SRC_URI 에서 git 사용 시e.g.S, SRCREV
    git인 데, local 사용SRC_URI = "git:///home/where/test;protocol=file"S = "${WORKDIR}/git"
    git, master 브랜치
    https://
    git url : "https://github.com/markyang92/my_settings.git"
    protocol: https
    branch: master
    SRC_URI = "git://github.com/markyang92/my_settings.git;protocol=https;branch=master"
    S = "${WORKDIR}/git"
    SRCREV = "${AUTOREV}"|"커밋 해시"
    git, master 브랜치
    ssh://
    git url : "ssh://github.com/markyang92/my_settings.git"
    protocol: ssh
    branch: master
    SRC_URI = "git://github.com/markyang92/my_settings.git;protocol=ssh;branch=master"
    S = "${WORKDIR}/git"
    SRCREV = "${AUTOREV}"|"커밋 해시"
    git, 특정 브랜치git url: "ssh://github.com/markyang92/my_settings.git"
    protocol: ssh
    branch: thud
    SRC_URI = "git://github.com/markyang92/my_settings.git;protocol=ssh;branch=thud"
    S = "${WORKDIR}/git"
    SRCREV = "${AUTOREV}"|"커밋 해시"
    git, TAGgit url: "ssh://github.com/markyang92/my_settings.git"
    protocol: ssh
    tag: MY_TAG
    SRC_URI = "git://github.com/markyang92/my_settings.git;protocol=ssh;tag=MY_TAG"
    S = "${WORKDIR}/git"
    SRCREV 생략

    do_patch()

    • Patch 파일들을 위치시키고 소스코드에 적용한다.
    • 때때로 fetch된 이후로 코드를 patch할 필요가 있다.
      • .patch, .diff 나 이러한 suffixes 의 압축된 버전(e.g. diff.gz)는 patches로 처리된다.
    • do_patch 태스크는 자동적으로 이러한 patches 적용한다.
    • build system은 "-p1" 옵션 (i.e. path내 dir level 1)으로 patches를 적용할 수 있다.
      • 더 깊은 디렉토리 레벨을 원하면 striplevel 옵션을 patch용 SRC_URI entry내에 사용하여 레벨 숫자 명시

    • src를 local로 관리할 때 자주 사용된다.
    $ git init
    $ git add userprog.c
    $ git commit -m"first"
    ...수정
    $ git add userprog.c
    $ git commit -m"second"
    $ git format-patch -1 -o ~/Yocto/Poky/MyLayer/recipes-myrecipe/mycomponent/files/
    -> files/0001-second.patch 생성
    • recipe에 patch파일 SRC_URI추가!
    SRC_URI = " .... \
                file://0001-second.patch \
    "
    • bitbake!

    u-boot 레시피의 경우

    • u-boot 레시피를 bitbake u-boot 했다.
    • oe-core/meta/recipes-bsp/u-boot
      • u-boot-common.inc

        S= "${WORKDIR]/git"

    • ${WORKDIR}: ${TOPDIR}/work/${ARCH}/${PN}/${PV}-${PR}/
    • S=${WORKDIR}/git
      • ${S}/patches 디렉토리가 있고,

        여기에 SRC_URI = "..., file://*.patch" 했던 파일이 ${WORKDIR}에 가져와 있고, ${S}/patches/softlink로 연결되어 있다.

    noexec: 태스크 실행 안함

    • 아래와 같이 noexec1로 셋하면, 해당 task는 빈 수행한다. 또한 execution required가 없다.
    do_configure[noexec] = "1"
    do_compile[noexec] = "1"
    • Disable Task에 사용된다.
    • 예를 들어, Class에서 특정한 레시피에서 특정 태스크가 필요 없을 때 사용한다.
    • e.g. myhello_0.1.bb 레시피
    DESCRIPTION="myhello!"
    LICENSE = "MIT"
    LIC_FILES_CHKSUM = "...."
    
    SRC_URI = "..."
    S = "..."
    do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} userprog.c -o userprog
    }
    
    do_patch[noexec] = "1"
    
    do_install() {
        ....
    }

    특정 태스크만 수행

    1. 어떤 레시피에 대해(component) 특정 Task만 수행은 아래와 같다.
    $ bitbake -c <TASK> <RECIPE_NAME> 혹은
    $ bitbake <RECIPE_NAME> -c <TASK>
    
    e.g.
    $ bitbake -c compile dropbear	: dropbear 컴포넌트의 레시피에서 do_compile() 태스크만 수행

    1. clean 수행
    $ bitbake -c clean component_name
    
    e.g.
    $ bitbake -c clean dropbear	: dropbear 컴포넌트의 Build에 의해 생성된 artifacts 제거

    1. cleanstate 수행
    $ bitbake -c cleanstate component_name
    
    e.g.
    $ bitbake -c cleanstate dropbear	: dropbear 컴포넌트용 shared state, artifacts를 제거
    profile
    pllpokko@alumni.kaist.ac.kr

    1개의 댓글

    comment-user-thumbnail
    2023년 1월 12일

    fetch 수행하면서 잘 보고 있습니다. linux-yocto fetch 단계만 50분이 넘게 걸리네요. 덕분에 재밌게 보고 있습니다. 도움이 많이 됩니다. 감사합니다.

    답글 달기