我们正在使用 Yocto 并构建两个略有不同的图像。一个只是标准映像“bitbake standard-image”,另一个是调试映像“bitbake debug-image”,其中将部署其他程序等。在这两个配方中,都会设置变量
IMAGE_TYPE
(=标准/调试)。该变量应用于将不同的 sshd_conf
文件部署到映像。为了实现这一点,我编辑了 openssh_%.append
文件,它最初看起来像这样:
FILESEXTRAPATHS_prepend := "${THISDIR}/openssh:"
SRC_URI += " \
file://sshd_config \
"
现在看起来像这样:
python () {
if d.getVar('IMAGE_TYPE') == 'debug':
d.appendVar('FILESEXTRAPATHS_prepend', '${THISDIR}/debug:')
d.appendVar('SRC_URI', ' \\ file://sshd_config \\ ')
if d.getVar('IMAGE_TYPE') == 'standard':
d.appendVar('FILESEXTRAPATHS_prepend', '${THISDIR}/openssh:')
d.appendVar('SRC_URI', ' \\ file://sshd_config \\ ')
}
我的问题是它没有按预期工作。经过修改,我的
sshd_config
文件都没有被部署。相反,会部署该层附带的默认 sshd_conf
。
我认为我的问题是变量${THISDIR}
没有立即扩展,但我不知道如何在“匿名Python函数”中做到这一点。
有人知道如何让我的改变发挥作用吗? 也许这不是正确的方法,有没有更好的方法为不同的图像部署不同的文件?
提前致谢 平子
您可能应该使用
d.prependVar("FILESEXTRAPATHS", ...)
而不是 d.appendVar("FILESEXTRAPATHS_prepend", ...)
。
我们也尝试了你的方法(在Python中),对我们来说它失败了,因为
${THISDIR}
没有扩展到存储.bbappend
文件的目录,而是原始.bb
文件的父目录。也许这是(或曾经是)一个 bitbake bug?
每个图像类型都有一个具有各自名称的子目录怎么样(不需要Python块):
FILESEXTRAPATHS_prepend := "${THISDIR}/files_${IMAGE_TYPE}:"
这并不完全是你想要的(子目录名称与图像类型不同),但效果很好。
您实际上是在描述 DISTRO_FEATURES 的目的。
公平警告,这不会完全按照您最初的想法工作,因为这不是系统设计的工作方式,但它是可以实现的。
它不起作用,因为您试图在图像级别实现此目的,并且
bitbake
不允许IMAGE
“范围”访问/修改其他食谱行为。
这意味着在
image1.bb
(在您的情况下为 standard-image.bb
)上设置变量不会对 recipeA.bb
(在您的情况下为 openssh.bbappend
)产生任何影响,因为 recipeA.bb
都无法访问 image1.bb
和 的变量image1.bb
可以访问 recipeA.bb
的变量,这是设计使然。
因此,对于您的场景,当您尝试通过匿名 python 读取
IMAGE_TYPE
中的 openssh.bbappend
变量时:
if d.getVar('IMAGE_TYPE') == 'debug':
什么也没有发生,因为据
openssh.bb
所知,该变量甚至没有设置。
这就是
DISTRO
发挥作用的地方,您可以根据您正在构建的DISTRO
修改不同配方的行为,这正是DISTRO_FEATURES
存在的原因。
您可以在现有代码库中找到几个示例,让我们看一下 wpa_supplicant 来了解一个简单的示例:
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}/${systemd_system_unitdir}
install -m 644 ${S}/wpa_supplicant/systemd/*.service ${D}/${systemd_system_unitdir}
fi
如果
systemd
是正在构建的 DISTRO_FEATURES
的 DISTRO
的一部分,那么 bitbake
将为该包安装其他文件(在本例中为 systemd 服务)
因此,如果您通过以下方式将 systemd 添加到
DISTRO_FEATURES
中的 DISTRO.conf
:
DISTRO_FEATURES:append = " systemd"
您将在映像中获得这些文件(无论您正在构建哪个映像),如果 systemd 不存在,这些文件也不会出现在生成的映像中。
您可以执行类似的操作,向您的发行版添加“我的调试功能”:
DISTRO_FEATURE:append = " my-debug-feature"
然后对食谱进行与上面相同的检查:
if ${@bb.utils.contains('DISTRO_FEATURES','my-debug-feature','true','false',d)}; then
install -m 644 ${S}/sshd_standard_config ${D}/${sysconfdir}/sshd_config
else
install -m 644 ${S}/sshd_debug_config ${D}/${sysconfdir}/sshd_config
fi
还有其他几个示例,您可以找到 bluez、connman、inetutils,如果存在某个
DISTRO_FEATURE
,它们会以某种方式修改安装或修改配方的行为。
现在,我知道您通过使用两个图像想到了这一点,并且您可能会发现这个答案令人沮丧,因此,您当然可以拥有两个图像而不是两个发行版,但它需要以不同的方式构建(推荐的方式仍然是使用
DISTRO_FEATURES
因为从长远来看它更干净)。
如果您真的想使用图像而不是单独的发行版,您可以做的就是不要尝试根据变量做出反应(
IMAGE_TYPE
),只需将额外的文件放在不同的包上,例如openssh-standard-config
vs openssh-debug-config
(为了简单起见,这些可以是单独的配方,因此您不必处理太多冲突)并在每个图像上安装属于它的包。
标准图像.bb:
IMAGE_INSTALL:append = " openssh-standard-config"
调试图像.bb
IMAGE_INSTALL:append = " openssh-debug-config"
您可能会想查看IMAGE_FEATURES,但您很快就会意识到,出于与上述相同的原因,它不会让您实现您想要的目标