yocto菜譜的重要知識


1、每個菜譜在其工作目錄中都有兩個sysroot,一個用於目文件(recipe-sysroot),一個用於構建主機的本地文件(recipesysroot-native).

  

  recipe-sysroot的文件是目標系統架構(arm)

  

  recipe-sysroot的文件是構建主機架構(x86)

  

2、菜譜不能直接填充sysroot目錄

  應該在${D}目錄中的do_install任務期間將文件裝到標准位
3、可以通過修改SYSROOT_DIRS來修改要填充到sysroot的目錄列表 

  SYSROOT_DIRS變量定義,do_populate_sysroot任務將使用do_install任務安裝的文件的子集來自動sysroot
  例如將opt目錄添加到目錄列表里
  SYSROOT_DIRS += "opt"

4、virtual 提供程序
  在構建之前,如果您知道幾種不同的菜譜提供相同的功能,則可以使用虛擬提供程序(即virtual/*)作為實際提供程序的占位符,實際的提供者是在構建時確定。

  使用虛擬提供程序的常見方案是內核recipes ,假如有3個內核菜譜:PN值分別為 kernel-big、kernel-mid、kernel-small,

  這3個菜譜都使用PROVIDES將自己標識為能夠提供virtual/kernel
5、內核類提供virtual/kernel的方法

PROVIDES += "${@"virtual/kernel"if (d.getVar("KERNEL_PACKAGE_NAME") == "kernel") else""}"

  繼承內核類的任何菜譜都可以利用PROVIDES語句,表面自己能夠提供virtual/kernel項目.
6、構建鏡像需要指定內核菜譜,怎么確定用哪個內核菜譜呢?

  使用PREFERRED_PROVIDER 指定哪個菜譜,使用PREFERRED_VERSION 指定菜譜的版本

  一個例子:/meta/conf/machine/include/x86-base.inc

PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
PREFERRED_VERSION_linux-yocto ??= "5.2%"

  另一個例子:meta-ti/conf/machine/include/ti33x.inc

PREFERRED_PROVIDER_virtual/kernel = "linux-ti-staging"
PREFERRED_PROVIDER_virtual/bootloader = "u-boot-ti-staging"
PREFERRED_PROVIDER_u-boot = "u-boot-ti-staging"

7、當菜譜需要使用virtual提供的依賴項時,不必硬編碼需要依賴的菜譜名稱,可以使用DEPENDS量來聲明菜譜構建依賴於virtual/kernel

DEPENDS = "virtual/kernel"

8、在構建最終鏡像期間, OpenEmbedded構建系統將根據PREFERRED_PROVIDER變量選擇virtual/kernel賴所需的正確recipes

     如果要使用kernel-small內核,則可以用下面的方式配置構建環境選擇的菜譜

PREFERRED_PROVIDER_virtual/kernel ??= "kernel-small"

 9、如果沒有被PREFERRED_PROVIDERPROVIDES virtual/* 項目的任何菜譜都不會生成,這提供了選擇內核菜譜的機制

10、菜譜發布前需要正確設置版本

       例如:irssi_0.8.16-rc1.bb此菜譜處於候選發布階段(rc1),當正式發布時菜譜更名為irssi_0.8.16.bb

       版本從irssi_0.8.16-rc1.bb ->  irssi_0.8.16.bb 被看作是構建系統和包管理器的下降,因此產生的程序包將無法正確地觸發升級

       為了確保版本比較正確,建議的慣例是將菜譜中的PV 設置為 previous_version + current_version

       您可以使用其他變量,以便可以在其他地方使用當前版本。這是一個例子

REALPV = "0.8.16-rc1"
PV = "0.8.15 +${REALPV}"

11、postinst 腳本

  主要完成軟件包(eg ".deb")安裝完成后所需的配置工作。安裝程序在目標上安裝程序包之后postinst 腳本立即運行。

  要向軟件包中添加安裝后腳本,請pkg_postinst_PACKAGENAME()數添加到菜譜文件(.bb),后將PACKAGENAME為您要附加到postinst 腳本的軟件包的名稱。

  要將安裝后腳本應用於菜譜的主軟件包(通常必需的),請指定用${PN}代替PACKAGENAME. 

  postinst 格式

pkg_postinst_PACKAGENAME(){
#行執創建根文件系統的命令時,將調用postinst功能中定義的腳本.如果腳本成功,則將該軟件包標記為已安裝.如果腳本失敗,則將包標記為已解壓縮,並在再次引導映像時執行腳本.
}

  有時有必要將postinst腳本的執行延遲到首次啟動之前。例如,腳本可能需要在設備本身上執行。若要將腳本執行延遲到啟動時間,則必須顯式標記postinst才能推遲到目標設備。

  您可以使用pkg_postinst_ontarget()或pkg_postinst()調用 postinst-intercepts defer_to_first_boot,pkg_postinst()腳本的任何失敗(包括 exit 1)都會在do_rootfs 任務執行期間觸發錯誤.

  如果您擁有使用pkg_postinst功能的菜譜, 並且他們需要使用非標准本機工具,這些工具在rootfs構造過程中具有依賴性,則需要在菜譜中使用PACKAGE_WRITE_DEPS變量來列出這些工具。

  如果不使用此變量,則可能會缺少工具,並且postinst腳本的執行將推遲到首次啟動時執行。將腳本推遲到第一次啟動是不希望的,並且對於只讀rootfs是不可能的。
  注意:通過pkg_preinstpkg_prermpkg_postrm分別存在對預安裝,預卸載和后卸的等效持。這些腳本與pkg_postinst的工作方式完全相同, 同的是它們在不同的時間運行
  另外,由於它們不同的運行時間,它們不適用於在映像創建時像pkg_postinst一樣運行。
12、使用本地文件的菜譜文件3中情況
  12.1、使用單個hello.c文件
    從本地存儲的單個文件(例如,在files下構建應用程序需要菜譜包含SRC_URI 變量中列出的文件 此外,您需要手動編寫 do_compile和 do_install任務。

    S 變量定義包含源代碼的目錄,在這種情況下,WORKDIR 目錄被設置為 BitBake用於構建的目錄。

     SUMMARY = "Simple helloworld application"
     SECTION = "examples"
     LICENSE = "MIT"
     LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

     SRC_URI = "file://helloworld.c"

     S = "${WORKDIR}"

     do_compile() {
     	${CC} helloworld.c -o helloworld
     }

     do_install() {
     	install -d ${D}${bindir}
     	install -m 0755 helloworld ${D}${bindir}
     }

  默認情況下,helloworld,helloworld-dbg,helloworld-dev 包會被構建 

  12.2、自動工具包

    使用 Autotools 的應用程序(例如:autoconf 和 automake )需要一個在SRC_URI中列出了源歸檔文件的菜譜,並且該菜譜還繼承了autotools,該類包含構建基於Autotool的應用程序所需的所有步驟的定義
   構建結果將自動打包。並且,如果應用程序使用NLS進行本地化,則會生成帶有本地信息的程序包(每種語言一個程序包)。

   以下是一個示例:(hello_2.3.bb

     SUMMARY = "GNU Helloworld application"
     SECTION = "examples"
     LICENSE = "GPLv2+"
     LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"

     SRC_URI = "${GNU_MIRROR}/hello/hello-${PV}.tar.gz"

     inherit autotools gettext

  12.3、基於Makefile的軟件
    使用GNU make的應用程序還需要一個菜譜,該菜譜的源歸檔文件列在SRC_URI中。不需要添加do_compile設置,因為默情況下BitBake啟動make命令編譯應用程序。

    如果需要其他make屬性, 則應將其存儲在EXTRA_OEMAKEPACKAGECONFIG_CONFARGS量中。BitBake將這些選項傳遞到GNU make調用中。

    注意, 然需要do_install任務。否則,默認情況下BitBake行一個空的do_install任務.。

    某些應用程序可能需要額外的參數才能傳遞給編譯器。例如,應用程序可能需要附加頭文件路徑,您可以通過添加到CFLAGS變量來完成此操.
    下面的示例顯示了這一點:

 CFLAGS_prepend = "-I ${S}/include "

    在下面這個例子中,mtd-utils是一個makefile-base的包 

     SUMMARY = "Tools for managing memory technology devices"
     SECTION = "base"
     DEPENDS = "zlib lzo e2fsprogs util-linux"
     HOMEPAGE = "http://www.linux-mtd.infradead.org/"
     LICENSE = "GPLv2+"
     LIC_FILES_CHKSUM = "file://COPYING;md5=0636e73ff0215e8d672dc4c32c317bb3 \
                         file://include/common.h;beginline=1;endline=17;md5=ba05b07912a44ea2bf81ce409380049c"

     # Use the latest version at 26 Oct, 2013
     SRCREV = "9f107132a6a073cce37434ca9cda6917dd8d866b"
     SRC_URI = "git://git.infradead.org/mtd-utils.git \
                     file://add-exclusion-to-mkfs-jffs2-git-2.patch \
     "

     PV = "1.5.1+git${SRCPV}"

     S = "${WORKDIR}/git"

     EXTRA_OEMAKE = "'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'CFLAGS=${CFLAGS} -I${S}/include -DWITHOUT_XATTR' 'BUILDDIR=${S}'"

     do_install () {
             oe_runmake install DESTDIR=${D} SBINDIR=${sbindir} MANDIR=${mandir} INCLUDEDIR=${includedir}
     }

     PACKAGES =+ "mtd-utils-jffs2 mtd-utils-ubifs mtd-utils-misc"

     FILES_mtd-utils-jffs2 = "${sbindir}/mkfs.jffs2 ${sbindir}/jffs2dump ${sbindir}/jffs2reader ${sbindir}/sumtool"
     FILES_mtd-utils-ubifs = "${sbindir}/mkfs.ubifs ${sbindir}/ubi*"
     FILES_mtd-utils-misc = "${sbindir}/nftl* ${sbindir}/ftl* ${sbindir}/rfd* ${sbindir}/doc* ${sbindir}/serve_image ${sbindir}/recv_image"

     PARALLEL_MAKE = ""

     BBCLASSEXTEND = "native"

13、將應用程序拆分為多個程序
  可以使用變量PACKAGESFILES用程序拆分為多個程序包
  以下是使用libxpm配方的示例默認情況下,此配方會生成一個包含程序庫和一些二進制文件的包

     require xorg-lib-common.inc

     SUMMARY = "Xpm: X Pixmap extension library"
     LICENSE = "BSD"
     LIC_FILES_CHKSUM = "file://COPYING;md5=51f4270b012ecd4ab1a164f5f4ed6cf7"
     DEPENDS += "libxext libsm libxt"
     PE = "1"

     XORG_PN = "libXpm"

     PACKAGES =+ "sxpm cxpm"
     FILES_cxpm = "${bindir}/cxpm"
     FILES_sxpm = "${bindir}/sxpm"

  在這個的示例中,我們希望將sxpm 和cxpm二進制文件分別打包。由於 默認情況下bindir會打包到主程序 PN包中,因此我們在PACKAGES 變量之前加上了前綴,以便將其他程序包名稱添加到列表的開頭。

  這將導致FILES_* 變量定義哪些文件和目錄被包含進哪些程序包的信息。較早版本的軟件包包含的文件被較早版本的軟件包跳過。因此,主PN軟件包不包括上面列出的文件。

14、打包外部生成的二進制文件
  有時,您需要向鏡像中添加預編譯的二進制文件。例如,假設存在專有代碼的二進制文件,這些二進制代碼是由公司的特定部門創建的。

  公司需要將這些二進制文件用作要使用OpenEmbedded構建系統構建的映像的一部分。

  因為您只有二進制文件,而沒有源代碼,所以您不能使用期望獲取SRC_URI中指定的源,然后進行編的典型菜譜
  14.1、一種方法是打包二進制文件,然后將其安裝為映像的一部分。通常,打包二進制文件不是一個好主意,因為,它可能會阻礙復制生成文件的能力,並可能導致將來與ABI的兼容性問題。但是,有時您別無選擇 
  14.2、最簡單的解決方案是創建一個使用bin_package類的菜譜,並確保您使用默認位置生成構件
     在大多數情況下,bin_package該類負責“跳過”配置和編譯步驟,並進行設置以從適當的區域獲取軟件包。

     特別是bin_pacgage這個類在do_configure 和 do_compile 任務中都設置noexec。

     設置FILES_${PN}為"/" 以便他選擇所有的文件,並設置一個do_install任務,該任務將所有文件從${S}復制到${ D}

     提取到${S}中的文件已經按照在目標上的布局方式進行布局時, bin_package類可以很好地工作 

  14.3、如果無法使用bin_package,則需要確保您執行以下操作

    14.3.1、創建一個菜譜,使其中do_configuredo_compile任務起作用:

     通常只要不在菜譜中定義這些任務就足夠了,因為除非在$(S}中找到Makefile,否則默認實現不執行任何操作 
     ${S}可能包含一個Makefile,或者你繼承了一個用自定義版本替換do_configure和do_compile的類,那么你可以使用[noexec]標志,將任務轉變為(no-ops)無操作

     如下所示:

     do_configure[noexec] = "1"
     do_compile[noexec] = "1"

   14.3.2、與 deleting the tasks 任務不同,noexec標志會將依賴關系鏈從do_fetchdo_unpackdo_patch任務保留do_install任務
   14.3.3、確保您的do_install任務正確安裝了二進制文件
   14.3.4、確保您將FILES(通常是FILES_${PN})設置為指向已安裝的文件,這當然取決於安裝它們的位置以及這些文件是否位於默認位置之外的其他位置
15、菜譜的語法

https://www.yoctoproject.org/docs/3.0.2/mega-manual/mega-manual.html#bitbake-user-manual-metadata

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM