如何使用替代实用程序(即除 strip 之外的其他实用程序)有条件地剥离/压缩二进制文件

如何使用替代实用程序(即除 strip 之外的其他实用程序)有条件地剥离/压缩二进制文件

在我们基于 yocto 的嵌入式应用程序中,我们现在有几个 Golang 二进制文件,它们可能会变得非常大。例如,docker(来自meta-virtualization)和相关二进制文件如果不压缩,则重达几百兆字节。因此,我们创建了使用 upx 压缩这些二进制文件的配方。例如,这是我们的docker-ce_git.bbappend

do_install_append() {
  /usr/bin/upx --brute ${D}/${bindir}/docker
  /usr/bin/upx --brute ${D}/${bindir}/dockerd
  /usr/bin/upx --brute ${D}/${bindir}/docker-proxy
}

这导致烘焙过程中出现以下错误:

ERROR: docker-ce-19.03.2-ce+git6a30dfca03664a0b6bf0646a7d389ee7d0318e6e-r0 do_package: QA Issue: File '/usr/bin/docker' from docker-ce was already stripped, this will prevent future debugging! [already-stripped]
ERROR: docker-ce-19.03.2-ce+git6a30dfca03664a0b6bf0646a7d389ee7d0318e6e-r0 do_package: QA Issue: File '/usr/bin/docker-proxy' from docker-ce was already stripped, this will prevent future debugging! [already-stripped]
ERROR: docker-ce-19.03.2-ce+git6a30dfca03664a0b6bf0646a7d389ee7d0318e6e-r0 do_package: QA Issue: File '/usr/bin/dockerd' from docker-ce was already stripped, this will prevent future debugging! [already-stripped]

好的,这很有道理。如果我们想创建调试版本,我们就不会删除这些二进制文件。

但:我们如何正确地进行条件剥离?我猜测存在某种仅针对非调试版本执行的剥离阶段,我们可以用它do_strip_append()或类似的东西附加它,但到目前为止,我在文档中搜索却一无所获。

答案1

我找到了一种解决这个问题的办法。你可以将自己附加到图像生成中,而不是将自己附加到与包相关的配方中。由于我们将其用作core-image-minimal目标,因此我创建了一个core-image-minimal.bbappend包含以下内容的:

ROOTFS_POSTPROCESS_COMMAND += "compress_docker_binaries;"

# Need to run in bash because pysh has no job control
compress_docker_binaries() {
  /bin/bash -x -c '
    set -e
    files=(containerd containerd-shim containerd-ctr docker dockerd \
      docker-proxy runc)
    for (( i=0; i<${#files[@]}; i++ )); do
      /usr/bin/upx --brute "$0/$1/${files[${i}]}" &
      pids[${i}]=$!
    done;
    for pid in ${pids[@]}; do
      wait ${pid}
    done
  ' "${IMAGE_ROOTFS}" "${bindir}"
}

通过附加compress_docker_binariesROOTFS_POSTPROCESS_COMMAND,我们确保在提取任何调试符号后文件也被压缩。

这个解决方案有一些缺点:

  • 您不需要附加到实际的包装配方,而是附加到更通用的图像配方。
  • 您仍然可以.bbappend使用单独的函数将文件保存在单独的目录中。但是,yocto 将按顺序执行它们,尽管在这种情况下您可以并行运行upx二进制文件。
  • 或者,您可以强制作业并行运行(就像我使用小 bash hack 所做的那样(pysh 没有作业控制)),但所有内容都必须放在一个文件中。它还会对并行运行的作业数量进行硬编码。

答案2

来晚了,但你可以加上

INSANE_SKIP_${PN} += "already-stripped"

查看参考文档了解更多信息。

相关内容