비트베이크란?

  • 비트베이크는 GNU Make와 유사한 도구로 Python과 Shell Script가 혼합된 형태의 코드를 파싱하여 타겟 플랫폼 이미지를 빌드하는 툴(엔진)이다.
  • 비트베이크는 메타데이터라는 것을 파싱하여 빌드를 수행하며, 메타데이터에는 3가지 유형이 존재한다.
    • 환경설정(*.conf): 빌드 전체 동작 방식과 정책을 결정하는 변수 집합, 어떠한 레이어와 머신 등을 사용할 지 결정
    • 레시피(*.bb, *.bbappend): “하나의 패키지를 어떻게 빌드할지”를 정의, Python과 Shell Script를 활용
    • 클래스(*.bbclass): 여러 레시피에서 공통으로 사용하는 빌드 로직을 정의, Python과 Shell Script를 활용
    • 레이어(meta-*): 비트베이크가 참조할 메타데이터(환경설정, 레시피, 클래스)를 논리적으로 묶어서 관리하는 단위
  • 비트베이크는 일반적으로 다음과 같은 처리 순서를 가진다.
    (각 과정에서 더 상세한 내용이 있지만 간략하게만 작성하면..)

    1. 타겟 플랫폼 이미지를 빌드시키기 위한 비트베이크의 빌드 환경 준비 (source oe-init-build-env <target>)
    2. 타겟 플랫폼 이미지인 <target>을 빌드하기 위한 비트베이크 실행 (bitbake <recipe_name>)
    3. 비트베이크가 실행되면서 <target> 디렉터리 하위의 conf/bblayers.conf 확인
    4. conf/bblayers.conf의 BBLAYERS 변수에 선언된 레이어(meta-*)들의 경로를 확인
    5. 레이어 디렉터리의 하위에 존재하는 conf/layer.conf를 확인
    6. conf/layer.conf의 BBFILES 변수에 선언된 레시피들의 경로를 참조하여 의존성에 맞춰서 빌드 수행

 

환경 설정 파일(bblayers.conf, layer.conf)에 대해서

bblayers.conf

<target>/conf/bblayers.conf

  • "source oe-init-build-env <target>"를 시행하면 기본적으로 위 그림과 같은 bblayers.conf 파일이 생성된다.
  • bblayers.conf에서 BBPATH와 BBFILES는 그다지 중요하진 않으며, BBLAYRES가 가장 중요하다.
  • BBLAYERS 변수에는 <target>을 빌드하기 위해 필요한 레이어 목록을 선언하며, 각 레이어는 공백으로 구분된다.
  • 비트베이크가 실행(bitbake 명령으로)되면 이 BBLAYERS에 있는 레이어 목록을 찾아가 레시피를 찾는다.

layer.conf

meta-poky/conf/layers.conf

  • 비트베이크는 conf/bblayers.conf의 BBLAYERS에 선언된 레이어를 접근한 뒤 conf/layer.conf를 찾는다.
  • layer.conf에는 패키지를 빌드하기 위한 레시피의 경로가 작성되어 있다. (패키지가 합쳐저 <target> 이미지 생성)
  • layer.conf의
    • BBPATH는 레이어 경로를 비트베이크로 전달하기 위해 사용하는 변수이다.
    • BBFILE은 레이어 하위의 패키지를 빌드하기 위한 레시피 파일의 경로를 나타내는 변수이다.
    • BBFILE_COLLECTIONS는 레이어가 비트베이크로 식별되기 위한 본인의 식별자(ID)를 등록하는 변수이다.
    • BBFILE_PATTERN_<collection>은 BBFILE 중에서 식별자가 바라볼 레시피를 구분하기 위한 변수이다.
    • BBFILE_PRIORITY_<collection>은 식별자가 식별하고 있는 레시피의 우선순위를 설정하기 위한 변수이다.
    • 일반적으로 BBFILE_COLLECTIONS와 BBFILE_PATTERN, BBFILE_PRIOIRTY는 한몸처럼 움직인다.
    • LAYERDEPENDS_<collection>은 레이어가 의존하는 레이어가 무엇인지 나타내기 위해 사용하는 변수이다.

 

bitbake-layers show-layers 실행 결과

  • "bitbake-layers show-layers" 명령을 활용해 <target>을 빌드하기 위해 필요한 레이어 목록을 확인할 수 있다.
  • 이 명령은 "source oe-init-build-env" 명령을 실행시켜서 비트베이크가 실행될 수 있는 환경을 세팅한 후에 실행 가능하다.

 

비트베이크의 빌드 과정 중 의존성 처리

  • 비트베이크는 빌드 과정에서 아래 두가지 유형의 의존성을 처리한다. 
    • 컴파일(빌드) 의존성: 타겟 이미지에 들어가는 바이너리 혹은 실행 환경(QEMU 등) 등을 컴파일하기 위해 호스트에서만 필요한 의존성으로, -native 접미사를 레시피 파일에 붙여(Ex. qemu-native_6.2.0.bb) 표현된다.
    • 런타임 의존성: 타겟에서 특정 바이너리를 실행하기 위한 의존성으로, 동적 라이브러리나 인터프리터 등이 존재한다. 컴파일 의존성과 다르게 -native 접미사가 붙지 않은 레시피 파일로 표현된다. 
  • 또한, 비트베이크는 레시피 간의 의존성을 처리하기 위해 DEPENDS와 RDEPENDS 변수를 작성한다.
    (PROVIDES도 있는데 이는 그렇게 중요한지는 모르겠다.. 나중에 중요해보이면 추가로 정리해야겠다.)
    • DEPENDS: 해당 레시피가 빌드하기 전에 반드시 먼저 빌드되어야 하는 패키지를 의미한다.
    • RDEPENDS: 컴파일된 패키지가 타겟 환경에서 실행될 때 반드시 필요한 패키지를 의미한다.

 

비트베이크의 태스크 종류

  • 비트베이크는 빌드를 위해 태스크를 실행시키며, 이 태스크는 레시피 파일에 의해서 작성된다.
  • 비트베이크는 레시피 파일에 태스크를 정의하기 위한 프레임워크를 제공한다.
  • 비트베이크에서 제공하는 태스크는 다음과 같으며, 이를 실행되는 순서대로 정리하였다.
    1. do_fetch
      • 패키지를 빌드하기 위한 소스를 가져오는(다운로드하는) 단계이다.
      • 소스를 가져올 때에는 Remote(Git 등)나 Local(Disk)에서 가져올 수 있다.
    2. do_unpack
      • do_fetch를 통해서 가져온 소스를 빌드할 수 있도록 풀어내는 단계이다.
      • 만약, 소스가 tar 등으로 압축되어 있다면 압축을 해제한다.
      • 만약, 소스가 Git을 통해 Clone 되었다면 Checkout을 수행한다.
    3. do_patch
      • do_unpack이 끝난 빌드 소스에 Patch를 적용시키는 단계이다.
      • 이 단계에서 *.patch 파일을 통해서 소스를 Patch 할 수 있다.
      • Patch가 적용된 소스가 최종적으로 이미지 빌드에 사용된다.
    4. do_configure, do_compile, do_install
      • do_configure, do_compile, do_install 단계별로 빌드를 수행한다.
      • do_congiure: 패키지를 빌드하기 위해 설정하는 단계이다.
      • do_compile: 패키지를 실제 컴파일하는 단계이다.
      • do_install: 컴파일된 패키지를 임시 디렉터리(${D})에 설치하는 단계이다.
      • 동일한 환경 변수의 이름이더라도 각 단계마다 사용 목적이 다르다.
    5. do_package
      • do_install로 인해서 임시 디렉터리에 설치된 패키지를 논리적으로 분할하는 단계이다.
      • 논리적으로 분할할 때에는 패키지의 유형(디버깅 심볼, 문서, 라이브러리 등)에 따라 수행된다.
    6. do_rootfs
      • do_package에 의해서 논리적으로 분할된 패키지들을 활용해 Root File System을 생성하는 단계이다.

 

비크베이크가 do_fetch 단계에서 소스 다운로드하는 방법

(Yocto 학습을 위해 살펴보고 있는 서적에서 소스 다운로드하는 부분을 상세히 설명하고 있어서 추가로 정리한다.)

  • 비트베이크는 패키지들을 빌드하는 태스크의 가장 첫 단계인 do_fetch에서 소스를 다운로드 받는다.
  • 비트베이크는 소스코드를 다운로드 받기 위해 OpenSSH, cURL, Git 등을 백엔드(Fetcher Backend)로 사용한다.
    • OpenSSH는 Remote에 존재하는 tar.gz 등과 같은 압축 파일을 가져오기 위해 주로 활용한다.
    • cURL은 Remote에 존재하는 tar.gz 등과 같은 압축 파일을 가져오기 위해 활용된다.
    • Git은 Remote에 존재하는 Git Repository를 가져오기 위해 활용된다.

meta/recipes-bsp/pm-utils/pm-utils_1.4.1.bb

  • 비트베이크는 do_fetch 단계에서 레시피 파일에 작성된 SRC_URI를 참고하여 소스를 가져온다.
    • SRC_URI의 ${PV}는 패키지 버전을 의미하며, 레시피 이름에 있는 버전(pm-tuils_1.4.1.bb)으로 대체된다.
    • SRC_URI가 ssh://로 되어 있다면 OpenSSH를 활용해 소스를 다운로드 받는다.
    • SRC_URI가 http:// 혹은 https://로 되어 있다면 cURL을 활용해 소스를 다운로드 받는다.
    • SRC_URI가 git://으로 되어 있다면 Git을 활용해 소스를 다운로드(Clone) 받는다.
    • SRC_URI가 file://로 되어 있다면 cp 등의 명령을 활용해 Local(Disk)에 존재하는 소스를 복사한다.
  • 다운로드가 완료된 소스의 경우에는 DL_DIR 환경 변수에 등록된 경로에 저장된다.
    • 기본적으로 ${DL_DIR}은 <target>/downloads 디렉터리로 설정된다.
    • <target>/conf/local.conf 파일에서 ${DL_DIR}의 경로를 재정의 가능하다.
  • Remote에서 다운로드 할 때에는 MIRRORS, PREMIRROS 환경 변수로 미러 서버를 설정가능하다.
    • <target>/conf/local.conf 파일에서 MIRRORS와 PREMIRROS를 재정의 가능하다.
  • Remote에서 다운로드 할 때 네트워크 접근을 할 수 없게 하려면 BB_NO_NETWORK를 활성화하면 된다.
    • <target>/conf/local.conf 파일에서 BB_NO_NETWORK = "1"을 작성해서 활성화 가능하다.

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기