Yocto 내부 파일 분석

기술 2016. 10. 2. 15:50 Posted by 아는 개발자

Yocto 프로젝트를 다운 받고 나면 c 코드는 하나도 없고 대부분 .bb, .inc로 이뤄진 스크립트 파일들이 대부분인 것을 확인 할 수 있다. 소스코드 하나 없이 위 파일들만 있으면 설정한 보드에서 동작하는 이미지가 나온다는 것이 신기하기도 하다.


눈치를 챈 사람들도 있겠지만 이 .bb, .inc 파일들은 스크립트이다. 이미지를 만들 때 필요한 소스 코드들을,


  • 어디서 읽어올 것인지 (do_fetch)
  • 어떤 설정을 줄 것인지 (do_configure)
  • 어떤 컴파일 명령을 줄 것인지 (do_compile)
  • 어디에 설치 할 것인지(do_install)
에 대한 정보들을 담고 있다. 잘 생각해보면 위의 작업들은 우리가 특정 파일들을 다운받고 빌드 할 때까지 이뤄지는 작업들과 굉장히 유사하다. 예를 들면 linux 4.2 버전을 받고 커널을 빌드 할 때 개발자의 과정들을 보면

  1. 원격 저장소로부터 소스코드들을 다운받는다. ( git clone ~ )
  2. .config 파일을 만든다 ( make config )
  3. 컴파일 실행 make ARCH=x86 ~
  4. 빌드 이미지를 특정 경로로 옮기기 cp zImage { directory }

로 이뤄져 있다. yocto는 이러한 수작업들을 하나의 파일내에서 모두 정리 될 수 있도록 만들어 주는 편리한 시스템이다.


직접 코드를 한 번 보자. poky/meta/recipes-core/glibc/glibc_2.23.bb 스크립트의 내용은 다음과 같다.

 
require glibc.inc

LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
      file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
      file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \
      file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c"

DEPENDS += "gperf-native"

SRCREV ?= "e742928c1592b43db6809db4f39e67be151cdd27"

SRCBRANCH ?= "release/${PV}/master"

GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)"

SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
           file://0005-fsl-e500-e5500-e6500-603e-fsqrt-implementation.patch \
           file://0006-readlib-Add-OECORE_KNOWN_INTERPRETER_NAMES-to-known-.patch \
           file://0007-ppc-sqrt-Fix-undefined-reference-to-__sqrt_finite.patch \
           file://0008-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch \
           file://0009-Quote-from-bug-1443-which-explains-what-the-patch-do.patch \
           file://0010-eglibc-run-libm-err-tab.pl-with-specific-dirs-in-S.patch \
           file://0011-__ieee754_sqrt-f-are-now-inline-functions-and-call-o.patch \
           file://0012-Make-ld-version-output-matching-grok-gold-s-output.patch \
           file://0013-sysdeps-gnu-configure.ac-handle-correctly-libc_cv_ro.patch \
           file://0014-Add-unused-attribute.patch \
           file://0015-yes-within-the-path-sets-wrong-config-variables.patch \
           file://0016-timezone-re-written-tzselect-as-posix-sh.patch \
           file://0017-Remove-bash-dependency-for-nscd-init-script.patch \
           file://0018-eglibc-Cross-building-and-testing-instructions.patch \
           file://0019-eglibc-Help-bootstrap-cross-toolchain.patch \
           file://0020-eglibc-cherry-picked-from.patch \
           file://0021-eglibc-Clear-cache-lines-on-ppc8xx.patch \
           file://0022-eglibc-Resolve-__fpscr_values-on-SH4.patch \
           file://0023-eglibc-Install-PIC-archives.patch \
           file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \
           file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \
           file://CVE-2016-3706.patch \
           file://CVE-2016-4429.patch \
"

SRC_URI += "\
           file://etc/ld.so.conf \
           file://generate-supported.mk \
"

SRC_URI_append_class-nativesdk = "\
           file://0001-nativesdk-glibc-Look-for-host-system-ld.so.cache-as-.patch \
           file://0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch \
           file://0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch \
           file://0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch \
"

S = "${WORKDIR}/git"
B = "${WORKDIR}/build-${TARGET_SYS}"

PACKAGES_DYNAMIC = ""

# the -isystem in bitbake.conf screws up glibc do_stage
BUILD_CPPFLAGS = "-I${STAGING_INCDIR_NATIVE}"
TARGET_CPPFLAGS = "-I${STAGING_DIR_TARGET}${includedir}"

GLIBC_BROKEN_LOCALES = " _ER _ET so_ET yn_ER sid_ET tr_TR mn_MN gez_ET gez_ER bn_BD te_IN es_CR.ISO-8859-1"

#
# We will skip parsing glibc when target system C library selection is not glibc
# this helps in easing out parsing for non-glibc system libraries
#
COMPATIBLE_HOST_libc-musl_class-target = "null"
COMPATIBLE_HOST_libc-uclibc_class-target = "null"

EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
                --without-cvs --disable-profile \
                --disable-debug --without-gd \
                --enable-clocale=gnu \
                --enable-add-ons \
                --with-headers=${STAGING_INCDIR} \
                --without-selinux \
                --enable-obsolete-rpc \
                ${GLIBC_EXTRA_OECONF}"

EXTRA_OECONF += "${@get_libc_fpu_setting(bb, d)}"
EXTRA_OECONF += "${@bb.utils.contains('DISTRO_FEATURES', 'libc-inet-anl', '--enable-nscd', '--disable-nscd', d)}"


do_patch_append() {
    bb.build.exec_func('do_fix_readlib_c', d)
}

do_fix_readlib_c () {
	sed -i -e 's#OECORE_KNOWN_INTERPRETER_NAMES#${EGLIBC_KNOWN_INTERPRETER_NAMES}#' ${S}/elf/readlib.c
}

do_configure () {
# override this function to avoid the autoconf/automake/aclocal/autoheader
# calls for now
# don't pass CPPFLAGS into configure, since it upsets the kernel-headers
# version check and doesn't really help with anything
        (cd ${S} && gnu-configize) || die "failure in running gnu-configize"
        find ${S} -name "configure" | xargs touch
        CPPFLAGS="" oe_runconf
}

rpcsvc = "bootparam_prot.x nlm_prot.x rstat.x \
	  yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
	  rusers.x spray.x nfs_prot.x rquota.x key_prot.x"

do_compile () {
	# -Wl,-rpath-link <staging>/lib in LDFLAGS can cause breakage if another glibc is in staging
	unset LDFLAGS
	base_do_compile
	(
		cd ${S}/sunrpc/rpcsvc
		for r in ${rpcsvc}; do
			h=`echo $r|sed -e's,\.x$,.h,'`
			rm -f $h
			${B}/sunrpc/cross-rpcgen -h $r -o $h || bbwarn "${PN}: unable to generate header for $r"
		done
	)
	echo "Adjust ldd script"
	if [ -n "${RTLDLIST}" ]
	then
		prevrtld=`cat ${B}/elf/ldd | grep "^RTLDLIST=" | sed 's#^RTLDLIST="\?\([^"]*\)"\?$#\1#'`
		if [ "${prevrtld}" != "${RTLDLIST}" ]
		then
			sed -i ${B}/elf/ldd -e "s#^RTLDLIST=.*\$#RTLDLIST=\"${prevrtld} ${RTLDLIST}\"#"
		fi
	fi

}

# Use the host locale archive when built for nativesdk so that we don't need to
# ship a complete (100MB) locale set.
do_compile_prepend_class-nativesdk() {
    echo "complocaledir=/usr/lib/locale" >> ${S}/configparms
}

require glibc-package.inc

BBCLASSEXTEND = "nativesdk"


스크립트 내용이 많은데 여기서 몇가지만 간추려서 설명을 하고자 한다.


  • SRC_URI: 저장소를 읽어오는 위치와 적용할 패치 파일들이 담겨있다. 가장 상위에 있는 텍스트, ${GLIBC_GIT_URI}는 읽어올 주소를 의미하고, branch는 어떤 브랜치로 checkout할 것인지이다. 그 아래 있는 패치 파일들은 소스코드를 받은 후 적용할 패치파일들이다. Yocto에서 빌드 할 때 패치파일들을 자동으로 적용해준다.
  • do_configure(): 빌드할 config 파일을 만들어 주는 작업이다. 여기에 새로운 내용을 넣어서 config 파일을 만들 수 있다.
  • do_compile(): compile 명령을 내리는 작업이다. compile시에 넣고 싶은 명령을 넣을 수 있다.
  • do_install(): 위 코드에는 빠져있지만 컴파일이 완료된 후 생성되는 빌드 결과물들을 특정 이미지에 놓는 명령들이 포함되어있다.
위의 작업들은 한 파일내에 모두 존재하는 것이 아니고 여러 개의 파일들이 얽혀서 이뤄진다. require * 은 다른 파일들을 포함하는 작업(C언어의 include와 유사)인데 다른 파일의 스크립트 내용도 포함해서 작업이 이뤄진다. 한 파일 내에 모든 작업이 없다면 다른 파일에 있을 가능성이 높으니 참고하자.

가끔 %.bbapend라는 파일이 있는데 이 파일은 말 그래도 bb 파일에 덧붙이는 용도다. 주로 메인 보드가 아닌 다른 보드에서 컴파일 옵션이나 패치파일을 추가 해줘야 하는 경우에 사용한다.


위 설명 yocto파일들을 완벽히 이해 할 수는 없지만 어떻게 수정하면 되겠구나 감 정도는 잡을 수 있게 된다.

728x90

'기술' 카테고리의 다른 글

objdump 를 이용한 바이너리 깨보기  (0) 2018.05.29
그래픽 소프트웨어, 라이브러리 정리  (0) 2018.05.06
Yocto 내부 파일 분석  (1) 2016.10.02
Yocto 작동방식  (0) 2016.10.01
Yocto 튜토리얼  (2) 2016.10.01
Yocto란?  (4) 2016.09.16
  1. 로카 2021.01.28 12:16  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~ Bitbake patch 관련해서 문의드립니다.
    일반 patch 파일의 경우, patch apply 명령어가 수행되어서 괜찮은데
    binary를 포함한 patch (git am 00-binary.patch와 같이 적용) 하는 경우에는,
    bb(append) 에 어떻게 추가해야 할까요?
    일반 방식으로 file://00-binary.patch 로 하면 patch fail 이 떠서... ㅠㅠ
    도움 부탁드립니다