yoncho`s blog

7. Build Optimization | Autotools, Build History, rm-work, externalsrc 본문

기술, 나의 공부를 공유합니다./[Vehicle] Yocto

7. Build Optimization | Autotools, Build History, rm-work, externalsrc

욘초 2024. 6. 26. 20:22

 

이번 포스트에서는 빌드 최적화에 대해 배우겠다. 

크게 autotools, build history, rm-work, externalsrc가 있다.

 

#목차

1. GNU Autotools 이용 nano editor build

2. Build History 

3. rm-work로 disk 용량 절감

4. externalsrc 이용 외부 소스로부터 소스 빌드

5. 최종

 

[1] GNU Autotools 이용 nano editor build

GNU Autotools는 GNU build system으로 UNIX 기반 시스템에서 소스 빌드에 도움이되는 빌드 툴이다.

리눅스도 이용 가능하다. Autotools는 다양한 H/W 환경을 개발자에게 동일한 빌드 환경으로 설정해주는 매우 착하고 좋고 똑똑한 친구다.

oe-core build system 내에 이미 Autotools를 다루는 함수가 있어 중요한 부분만 정리하겠다.

추가로 nano editor를 가지고 externalsrc도 예제로 진행할 것이다

externalsrc는 변경하고자하는 소스를 로컬에 저장해 변경가능하게 해준다. 이건 뒷쪽에서 자세히...ㅎ

 

#Autotools 구성

I. autoconf : configure.ac 파싱 => configure script 생성 및 실행 => Makefile 생성

II. automake : Makefile.am파싱 => Makefile.in생성 => configure 파일에서 Makefile 생성시 참고

III. libtool : Library 생성 처리

 

oe-core가 제공하는 Autotools로 쉽게 빌드하는 방법을 최종적으로 배울것이다.

 

#Autotools - nano editor 실습

I. 임시 폴더 생성 및 nano editor 소스 다운로드

#임시폴더생성
mkdir tmp

#tmp/디렉터리 아래 nano editor 소스 다운
wget https://www.nano-editor.org/dist/v6/nano-6.0.tar.gz

II. nano editor checksum 값 구하기 (구할 파일 : nano*.tar.gz / COPYING / COPYING.DOC )

#nano*.tar.gz checksum 값 구하기
md5sum nano-6.0.tar.gz
#결과
191152bb1d26cefba675eb0e37592c4e  nano-6.0.tar.gz

#zip 파일 압축해제
tar -xvf nano-6.0.tar.gz
#nano-6.0/ 디렉터리 하위
cd nano-6.0

#COPYING & COPTING.DOC checksum 값 구하기
md5sum COPYING
#결과
f27defe1e96c2e1ecd4e0c9be8967949 COPYING

md5sum COPYING.DOC
#결과
ad1419ecc56e060eccf8184a87c4285f COPYING.DOC

 

 

III. poky/ 디렉터리 아래 새로운 레이러 생성을 위한 meta-nano-editor/ 디렉터리를 생성한다.

meta-nano-editor/
|--conf/
|	|--layer.conf
|--recipes-nano/
	|--nano_6.0.bb

 

새롭게 만든 meta-nano-editor 디렉터리 아래 위와 같은 구조를 가지게 작업을 해둔다. 

 

IV. meta-nano-editor/ 디렉터리 아래 conf/ 디렉터리 아래 layer.conf파일을 아래와 같이 작업한다.

BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes*/*.bb"
BBFILE_COLLECTIONS += "nano-editor"
BBFILE_PATTERN_nano-editor = "^${LAYERDIR}/"
BBFILE_PRIORITY_nano-editor = "10"
LAYERSERIES_COMPAT_nano-editor = "${LAYERSERIES_COMPAT_core}"

이는 bitbake가 nano_6.0.bb 레시피 파일을 감지할 수 있게 하기 위해 경로를 추가해준 것이다.

 

V. meta-nano-editor/ 디렉터리 아래 recipes-nano/ 디렉터리 아래 nano_6.0.bb파일을 아래와 같이 작업한다.

DESCRIPTION = "Nano editor example"
LICENSE = "GPLv3"
LIC_FILES_CHKSUM = "file://COPYING;md5=f27defe1e96c2e1ecd4e0c9be8967949 \
                   file://COPYING.DOC;md5=ad1419ecc56e060eccf8184a87c4285f"

SRC_URI = "https://www.nano-editor.org/dist/v6/nano-6.0.tar.gz"
SRC_URI[md5sum] = "191152bb1d26cefba675eb0e37592c4e"
DEPENDS = "ncurses"

inherit gettext pkgconfig autotools

여기서 중요한 부분은 맨 마지막 줄로, oe-core에서 제공하는 클래스 파일을 이용해 Autotools 기능을 사용할 수 있다.

추가로 DEPENS의 "ncurses"는 nano editor가 ncurses 패키지를 필요로 해서 의존성 관계를 부여한 것이다.

 

VI. bitbake가 새로 만든 레이어를 감지할 수 있게 build/conf/ 디렉터리 아래 bblayers.conf 파일을 아래와 같이 작업한다.

POKY_BBLAYERS_CONF_VERSION = "2"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/yoncho/poky_src/poky/meta \
  /home/yoncho/poky_src/poky/meta-poky \
  /home/yoncho/poky_src/poky/meta-yocto-bsp \
  /home/yoncho/poky_src/poky/meta-hello \
  /home/yoncho/poky_src/poky/meta-nano-editor \
  "

 

VII. autotools 확인을 위한 nano build

bitbake nano

 위 빌드 명령어가 실행이 완료되면 poky_src/build/tmp/work/core2-...-linux/nano/6.0-r0/image/usr/lib/bin/ 디렉터리 아래 nano 실행파일이 생성되었음을 알 수 있다.

 

지금까지 우리가 해준건 nano 소스 위치를 레시피 파일에 추가하고 Autotools를 상속받은 것 말곤 없다.

하지만, bitbake가 nano를 단순하게 처리한건 절대 아니고 

poky_src/build/tmp/work/core2-...-linux/nano/6.0-r0/temp/ 디렉터리 아래 log.task_order 파일을 열면 bitbake가 알아서 여러 Task를 생성하고 동작시키고 최종 바이너리까지 생성했음을 알 수 있다.

=> bitbake가 wget으로 nano editor s/w package를 외부에서 다운받고 내부에서 oe-core가 제공하는 autotools 클래스와 여러 메타데이터를 이용해 빌드를 한 것이다. 그리고 최종적으로 바이너리를 생성했다.

 

생성한 nano 실행파일을 타깃 시스템에서 동작시키기 위해  다음 단계를 진행하겠다.

 

VIII. rootfs에 등록하기1 - meta-nano-editor/ 디렉터리 아래 recipes-core/images/ 디렉터리 생성 및 core-image-minimal.bbappend 레시피 파일 생성 및 작업

#디렉터리 생성
mkdir -p recipes-core/images

#레시피 확장 파일 생성 및 작업
vi core-image-minimal.bbappend

---core-image-minimal.bbappend 내용---
IMAGE_INSTALL += "nano"

 

IX. rootfs에 등록하기2 -  bitbake가 레시피 확장 파일을 인식할 수 있게 meta-nano-editor/conf/ 디렉터리 아래 layer.conf 파일을 아래와 같이 작업

BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes*/*.bb"
BBFILES += "${LAYERDIR}/recipes*/*/*.bbappend"
BBFILE_COLLECTIONS += "nano-editor"
BBFILE_PATTERN_nano-editor = "^${LAYERDIR}/"
BBFILE_PRIORITY_nano-editor = "10"
LAYERSERIES_COMPAT_nano-editor = "${LAYERSERIES_COMPAT_core}"

위 작업을 끝으로 우린 rootfs에 nano를 올릴 준비가 끝났다.

다음 단계에서 qemu를 실행해봄으로써 확인해볼 수 있다.

 

X. 타깃 시스템에서 nano 동작을 위한 빌드 및 roofs image 생성 그리고 qemu 실행

bitbake nano -c cleanall && bitbake nano
bitbake core-image-minimal -C rootfs
runqemu core-image-minimal nographic

qemu 실행 후 'nano' 명령어를 입력하면 nano editor가 정상적으로 실행되면 성공적으로 동작한 것이다.

 

 

[2] Build History 

Yocto에서 image의 변경점을 추적하고 이미지 수행 결과를 이전과 비교(diff)할 수 있는 기능을 제공하는데.

우리는 이런 변경점과 비교를 Build History라고 한다.

Build History 기능을 사용하려면 local.conf 파일에 buildhistory.bbclass 클래스 파일과 관련 변수를 추가해야한다.

 

#build history 기능 추가

I. build/conf/ 디렉터리 아래 local.conf 파일을 아래와 같이 작업한다.

...
# for build history
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "1"
BUILDHISTORY_COMMIT_AUTHOR = "yoncho <yoncho@poscodx.com>"
BUILDHISTORY_DIR = "${TOPDIR}/buildhistory"
BUILDHISTORY_IMAGE_FILES = "/etc/passwd /etc/group"

참고로 클래스를 활성화 시키는 지시어는 inherit, INHERIT 두가지가 있다. 단순히 소문자/ 대문자 차이가 아니다.

(a) inherit : 클래스 파일을 상속받는 레시피 파일에서 사용

(b) INHERIT : 환경설정파일에서 사용, 전역적인 성격 

=> 즉, inherit은 클래스 상속 받을 레시피 파일 안에서만 사용 가능하고 INHERIT은 전역적으로 모든 레시피 파일에서 클래스를 상속받을 수 있게 한다. 적용 범위의 차이가 있다.

 

+ 추가로

맨 마지막 줄은 rootfs에 설치된 특정 파일에 대한 경로를 할당해 내용을 추적할 수 있게 해준다.

=> /etc/passwd /etc/group은 기본값이며 사용자 및 그룹 항목 변경을 추적한다.

 

II. Build History 테스트를 위한 nano 재빌드

bitbake nano -c cleanall && bitbake nano
bitbake core-image-minimal -C rootfs
runqemu core-image-minimal nographic

위 명령어를 수행하면 로그 결과 마지막 부분에 아래와 같이 표시됨을 알 수 있다.

NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds

빌드가 완료되면 build/ 디렉터리 아래 buildhistory/ 디렉터리가 생성되었다.

그 디렉터리로 가게되면 유용한 정보들이 들어있는데. 전부다 파악하기엔 어렵기 때문에 중요 파일만 설명하겠다.

(a) Image-info.txt : rootfs image 내용의 변경을 추적하는데 사용, image 생성을 위해 사용된 클래스 목록, 패키지, rootfs 내용 관련 기술 (경로 : poky_src/build/buildhistory/images/qemux86_64/glibc/core-image-minimal/image-info.txt)

(b) build-id.txt : image 생성을 위해 사용된 build 환경 정보 제공

(경로: poky_src/build/buildhistory/images/qemux86_64/glibc/core-image-minimal/build-id.txt)

 

III. + 추가로 패키지 추가에 따른 Build History 추적 (usbutils) 1

build/conf/ 디렉터리 아래 local.conf 파일을 아래와 같이 작업한다.

...
# usbutils package
CORE_IMAGE_EXTRA_INSTALL += "usbutils"

여기서 보통 패키지를 rootfs에 추가하려면 레시피의 layer.conf에서는 IMAGE_INSTALL변수를 사용하고

환경 설정 파일인 local.conf에서는 CORE_IMAGE_EXTRA_INSTALL 변수를 사용한다. 

CORE_IMAGE_EXTRA_INSTALL 변수는 core-image.bbclass 클래스를 기반으로 이미지에 추가적인 패키지를 추가하려 할 때 사용한다.

보통 환경 설정 파일인 local.conf에서 IMAGE_INSTALL 변수 재정의 문제를 방지하기 위해 자주 사용된다.

 

우리가 예제로 사용하는 core-image-minimal.bb는 core-image.bbclass 클래스를 기반하기 때문에 CORE_IMAGE_EXTRA_INSTALL 변수에 usbutils를 추가했다.

 

IV. + 추가로 패키지 추가에 따른 Build History 추적 (usbutils) 2

위 작업이 끝났으면 core-image-minimal을 재빌드 시키고 변경된 부분을 확인해보자

#이미지 재빌드
bitbake core-image-minimal

#diff 차이 확인 (단, build/ 디렉터리 에서만 사용 가능)
buildhistory-diff

#결과
...
usbutils was added
...

결과에 보면 추가한 usbutils 패키지에 대한 로그를 확인할 수 있다.

 

 

[3] rm-work로 disk 용량 절감

rm_work.bbclass 클래스는 매우 유용한 기능이다. oe-build system이 빌드를 끝내고 작업한 파일들을 삭제하는 기능을 수행하는 Task가 바로 rm_work Task이다. 그리고 이 Task는 rm_work.bbclass가 제공한다.

 

현업에서 디스크 공간 절감을 위해 자주 사용되며 bitbake가 빌드 과정에서 생성되는 산출물 파일들을 모두 저장할 필요가 없을 때 사용한다. 

기존 nano editor 예제에 이어 진행하겠다.

 

#rm_work실습

I. 레시피 확장 파일로 rm_work 클래스 상속 받기 

아래 구조와 같이 새로운 폴더(appends/)와 그 아래 레시피 확장 파일 (nano_6.0.bbappend)을 만들고 작업한다.

meta-nano-editor/
|--conf/..
|--recipes-nano/..
|--recipes-core/..
|--appends/
	|--nano_6.0.bbappend
    

--- nano_6.0.bbappend 내용 ----
inherit rm_work

위 레시피 확장 파일 내용을 보면 rm_work를 현재 레시피에서만 상속을 받게 했다.

만약 모든 레시피에서 상속을 받고 싶다면 이전에 설명했던 것 처럼 build/conf/ 디렉터리 아래 local.conf 파일에 

'INHERIT += "rm_work"'를 추가하면 된다.

 

II. bitbake가 레시피 확장 파일을 인식할 수 있게 conf/ 디렉터리 아래 layer.conf 파일을 아래와 같이 수정하기

BBPATH =. "${LAYERDIR}:"
BBFILES += "${LAYERDIR}/recipes*/*.bb"
BBFILES += "${LAYERDIR}/recipes*/*/*.bbappend"
BBFILES += "${LAYERDIR}/appends/*.bbappend"
BBFILE_COLLECTIONS += "nano-editor"
BBFILE_PATTERN_nano-editor = "^${LAYERDIR}/"
BBFILE_PRIORITY_nano-editor = "10"
LAYERSERIES_COMPAT_nano-editor = "${LAYERSERIES_COMPAT_core}"

 

III. rm_work 테스트를 위해 현재 nano build directory 메모리 확인 및 재빌드 후 다시 확인

#poky_src/build/tmp/work/core2-...-linux/nano 디렉터리 아래에서
du -sh 6.0-r0/
#결과
804MB	6.0-r0/

#재빌드
bitbake nano -c cleanall && bitbake nano

#메모리 다시 확인
du -sh 6.0-r0/
2.4MB	6.0-ro/

재빌드 후 메모리 용량을 보면 이전보다 훨씬 많이 줄어든걸 확인할 수 있다.

 

따라서 rm_work는 디스크 용량 제한이 있는 경우, 유용하게 쓰이며 매우 편리한 기능이다.

 

 

 

[4] externalsrc 이용 외부 소스로부터 소스 빌드

앞서 빌드한 nano editor의 빌드 시 사용한 소스는 

poky_src/build/tmp/work/core2-...-linux/nano/6.0-r0/nano6.0/ 디렉터리 아래 위치한다.

 

참고로 소스 코드 받는 방법에 따라 저장위치 기본값이 다르다

소스 받는 방법 SRC_URI ${S} 
git으로 받음 SRC_URI = "git://Github.com/...." S = "${WORKDIR}/git"
tarball로 받음 SRC_URI = "https://..../...tar.gz" S = "${WORKDIR}/${BPN}-${PV}"
local에서 직접 SRC_URI = "file://...tar.gz" S = "${WORKDIR}"

위 표는 알고있자.

 

```

추가 정리 中

```

 

externalsrc 정리 : 

외부에서 받은 소스에 변경이 필요해 작업을 한 뒤 잘못 작동 시켜 제거하거나 origin으로 부터 fetch/ patch를 받는다거나 그렇게 되면 변경한 코드들이 날아가게된다.

이런 문제를 해결하고자 oe-core에서 제공하는 externalsrc 클래스이다.

externalsrc.bbclass 클래스는 빌드 대상인 소스를 WORKDIR 아래에서 찾는게 아닌 우리가 지정한 Local 디렉터리에서 찾는 방법을 제공한다.

즉, 외부 소스를 빌드 대상으로 삼을 수 있다..!!

 

 

[5] 최종

Poky가 포함하는 meta 디렉터리를 oe-core라고 부른다. 이건 초반 Poky 글에서 계층 구조를 파악할 때 말했었다.

oe-core에는 정말 많은 유용한 metadata를 가지고 있고, 많은 특정 기능을 포함한다.

여기서 systemd, Autotools, buildhistory, rm-work, externalsrc 클래스 파일을 우리가 다뤄봤다. 

 

정말 대단한건 inherit/ INHERIT 지시어만으로 레시피 파일에 상속함으로써 기능들을 이용할 수 있다는 것이다.

Yocto의 추상화는 정말 잘 되어있다.

 

Comments