繁体   English   中英

Yocto/ Bitbake - 将构建版本(例如 PE、PR 和 PV)合并到 C++ 编译中

[英]Yocto/ Bitbake - incorporate build version (e.g. PE, PR & PV) into C++ compilation

我做了一些搜索,但找不到这个问题的答案。

我有一个 C++ GUI 应用程序,它是在 Yocto/Poky 图像中使用 Autotools 构建的。 PR 服务已启用并用于问题跟踪我想将 C++ 应用程序的构建版本合并到 GUI 中(以便用户可以在 GUI 上看到它的 v 0.9.1002 或类似版本)。

有没有办法通过配方来完成这个,或者我需要修改 Autotools 文件以某种方式构建构建版本?

感谢您的关注,

编辑:感谢您的回复。

我放在一起的项目(基于EGT框架)相当大,并且是从我在 github 的存储库中使用 Yocto/Bitbake 提取的。 PV & PE 我将根据需要增加, PR 生成由 Bitbake 提供。 MRE 类似于:

#include <egt/ui>

extern char __build_ver // Ideally supplied by Bitbake/ Autotools

int main(int argc, char** argv)
{
    egt::Application app(argc, argv);

    egt::TopWindow window;
    egt::Label label(window, __build_ver);
    egt::center(label);
    window.show();

    return app.run();
}

configure.ac类似于

AC_PREREQ([2.69])
AC_INIT([egt-demo],[1.3])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AC_USE_SYSTEM_EXTENSIONS
AC_CANONICAL_TARGET
PKG_PROG_PKG_CONFIG

AM_INIT_AUTOMAKE([1.10 foreign subdir-objects])

# Enable quiet compiles on automake 1.11.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

# Initialize libtool
LT_PREREQ([2.2])
LT_INIT([win32-dll])

AC_LANG(C++)
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX([14], [noext])
AC_PROG_CC
AC_PROG_CPP
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_UINT32_T

AX_PTHREAD([LIBS="$PTHREAD_LIBS $LIBS"
            CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
            CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"],
            AC_MSG_ERROR(Can not find pthreads.  This is required.))

AC_DEFUN([EGT_CC_TRY_FLAG], [
  AC_MSG_CHECKING([whether $CC supports $1])
  egt_save_CFLAGS="$CFLAGS"
  CFLAGS="$CFLAGS $1 -Werror"
  AC_COMPILE_IFELSE([AC_LANG_SOURCE([ ])], [egt_cc_flag=yes], [egt_cc_flag=no])
  CFLAGS="$egt_save_CFLAGS"
  if test "x$egt_cc_flag" = "xyes"; then
    ifelse([$2], , :, [$2])
  else
    ifelse([$3], , :, [$3])
  fi
  AC_MSG_RESULT([$egt_cc_flag])
])

MAYBE_WARN="-Wall -Wextra \
-pedantic \
-Wfloat-equal \
-Wsign-compare \
-Wpointer-arith \
-Wwrite-strings \
-Wmissing-declarations \
-Wpacked \
-Wstrict-aliasing=2 -Winit-self \
-Wno-attributes -Wno-long-long \
-Wno-missing-field-initializers \
-Wno-unused-parameter \
-Wno-psabi" # no warnings about gcc abi changes

# invalidate cached value if MAYBE_WARN has changed
if test "x$egt_cv_warn_maybe" != "x$MAYBE_WARN"; then
    unset egt_cv_warn_cflags
fi
AC_CACHE_CHECK([for supported warning flags], egt_cv_warn_cflags, [
    echo
    WARN_CFLAGS=""
    # Some warning options are not supported by all versions of
    # gcc, so test all desired options against the current
    # compiler.
    #
    # Note that there are some order dependencies
    # here. Specifically, an option that disables a warning will
    # have no net effect if a later option then enables that
    # warnings, (perhaps implicitly). So we put some grouped
    # options (-Wall and -Wextra) up front and the -Wno options
    # last.
    for W in $MAYBE_WARN; do
        EGT_CC_TRY_FLAG([$W], [WARN_CFLAGS="$WARN_CFLAGS $W"])
    done
    egt_cv_warn_cflags=$WARN_CFLAGS
    egt_cv_warn_maybe=$MAYBE_WARN
    AC_MSG_CHECKING([which warning flags were supported])])
WARN_CFLAGS="$egt_cv_warn_cflags"
AC_SUBST(WARN_CFLAGS)

AC_DEFUN([LIBINTL_SRC], [
AC_LANG_PROGRAM([[
#include <libintl.h>
]],[[
char *msg = gettext("test");
]])])

AC_MSG_CHECKING([if libc contains libintl])
AC_LINK_IFELSE([LIBINTL_SRC],
    [AC_MSG_RESULT([yes])
    LIBC_CONTAINS_LIBINTL=Yes],
    [AC_MSG_RESULT([no])
    LIBC_CONTAINS_LIBINTL=])
AC_SUBST([LIBC_CONTAINS_LIBINTL])

AC_CHECK_HEADER([libintl.h],
[NO_GETTEXT=],
[NO_GETTEXT=Yes])
AC_SUBST([NO_GETTEXT])

if test -z "$NO_GETTEXT"; then
    test -n "$LIBC_CONTAINS_LIBINTL" || LIBS="$LIBS -lintl"
fi

PKG_CHECK_MODULES(LIBEGT, [libegt >= 1.3], [], [
   AC_MSG_ERROR(libegt not found.  This is required.)
])

AC_ARG_WITH([sensors],
    AS_HELP_STRING([--without-sensors], [Ignore presence of sensors and disable it]))
AS_IF([test "x$with_sensors" != "xno"],[
   AC_CHECK_HEADER([sensors/sensors.h], [have_sensors=yes], [have_sensors=no])
   if test "x${have_sensors}" = xyes; then
      CXXFLAGS="-DLUA_USE_READLINE ${CXXFLAGS}"
      LDFLAGS="-lsensors ${LDFLAGS}"
      AC_DEFINE(HAVE_SENSORS, 1, [Have sensors support])
   fi
])
AM_CONDITIONAL([HAVE_SENSORS], [test "x${have_sensors}" = xyes])

AC_ARG_ENABLE([lto],
  [AS_HELP_STRING([--enable-lto], [enable gcc's LTO [default=no]])],
  [enable_lto=$enableval], [enable_lto=no])
if test "x$enable_lto" = "xyes" ; then
  AC_MSG_NOTICE([enabling LTO])
  CFLAGS="$CFLAGS -flto"
  CXXFLAGS="$CXXFLAGS -flto"
fi

AC_CONFIG_FILES([Makefile external/Makefile])
AC_OUTPUT

我的 Bitbake 食谱是:

DESCRIPTION = "XXX Application"
LICENSE = "CLOSED"

PACKAGES = "\
    ${PN} \
    ${PN}-dev \
    ${PN}-dbg \
"


# PR service enabled in local.conf
SRC_URI = "git://git@github.com/xxxxx/xxxxxxxxxxx.git;protocol=ssh;branch=main"
SRCREV="${AUTOREV}"
PV = "1.0+git${SRCPV}"

S = "${WORKDIR}/git"

# out-of-tree building doesn't appear to work for this package.
B = "${S}"

inherit pkgconfig autotools gettext

do_configure_prepend() {
    ( cd ${S};
    ${S}/autogen.sh; cd -)
}


FILES_${PN} += " \
    ${datadir}/xxxxxx/* \
"

python __anonymous () {
    endianness = d.getVar('SITEINFO_ENDIANNESS')
    if endianness == 'be':
        raise bb.parse.SkipRecipe('Requires little-endian target.')
}

我仍然不确定我是否完全理解您的问题及其环境(我对 bitbake 和 yocto 完全不熟悉),但以下将显示包版本号为egt::Label ,甚至允许调用configuremake的打包脚本添加更多版本信息。 HTH。

#include "config.h"

#include <egt/ui>

char build_version_string[] =
    PACKAGE_VERSION
#ifdef ADDITIONAL_VERSION_STR
    " (" ADDITIONAL_VERSION_STR ")"
#endif
    ;

int main(int argc, char** argv)
{
    egt::Application app(argc, argv);

    egt::TopWindow window;
    egt::Label label(window, build_version_string);

这应该使标签显示来自AC_INIT()的第二个参数的"1.3"版本字符串。

如果你想添加额外的版本信息,你可以在你的 yocto/bitbake/whatever script/recipe/whatever 构建包时定义ADDITIONAL_VERSION_STR宏:

PR=1002
more_version_info="yocto foobar $PR"
tar xf egt-demo-1.3.tar.gz
cd egt-demo-1.3
./configure CPPFLAGS="-DADDITIONAL_VERSION_STR=\"${more_version_info}\"" --prefix=...
make
make install

这应该使标签显示"1.3 (yocto foobar 1002)"

一些评论,实际上与问题相关的或多或少的递减顺序:

  • grep PACKAGE_ config.h可能会揭示更多有趣的信息,特别是如果您阅读https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Initializing-configure.html并使用两个以上AC_INIT参数.

  • char build_version_string[]放入其单独的编译单元(C 或 C++)中会很有用,例如带有相应 build- build-version.cbuild-version.h ,因为这可以帮助避免对潜在的大型main.cc文件由于config.h的变化。

  • 这避免了以___开头的宏或符号,因为它们通常由 C 或 C++ 语言标准保留。

  • 如果configure调用 Autoconf 或 Automake 未提供的宏,我建议明确地m4_pattern_forbid它们。 如果找不到任何必要的 m4 宏,这将使autoreconf运行提前失败,因此未扩展的宏调用(如PKG_*LT_*AX_*可能会出现在生成的configure脚本中:

     m4_pattern_forbid([PKG_PROG_PKG_CONFIG]) PKG_PROG_PKG_CONFIG
  • 您需要的 Autoconf 版本 2.69 于 2012 年 4 月 25 日发布。 您需要的 Automake 版本 1.10 于 2006 年 10 月 15 日发布。 Automake 1.11 版向AM_INIT_AUTOMAKEAM_SILENT_RULES宏引入了silent-rules选项,于 2009 年 5 月 17 日发布。 因此,您可以合理地假设任何具有 autoconf 2.69 的系统都可能具有不到三年的 automake 版本,并删除AM_SILENT_RULES周围的条件并使用

    AM_INIT_AUTOMAKE([ 1.11 foreign subdir-objects ]) AM_SILENT_RULES([yes])

    或者

    AM_INIT_AUTOMAKE([ 1.11 foreign silent-rules subdir-objects ])

    代替

    # Enable quiet compiles on automake 1.11. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])

    但这开始离题了。

为了帮助其他人,我会将其作为建议的答案发布,这确实归功于ndim ,这只是将他们的答案放入 Bitbake 格式。 我的食谱布局如下:

└── helloworld
    ├── files
    │   ├── config.h
    │   └── helloworld.c
    └── helloworld_0.1.bb

helloworld.c 基于 Yocto 手册示例:

#include <stdio.h>
#include "config.h"

int main() {
   printf("Hello, World!\n");
   printf("PE = %s, PV = %s, PR = $s\n", PE, PV, PR);
   printf("YOCTO_BUILD_VERSION = %s\n", YOCTO_BUILD_VERSION);
   return 0;
}

配置.h:

#define PE "1"
#define PV "2"
#define PR "3"

& 最后是 helloworld_0.1.bb:

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

SRC_URI = "file://helloworld.c  \
           file://config.h      \
           "

S = "${WORKDIR}"

TARGET_CC_ARCH += "${LDFLAGS}"

do_configure() {
    # Make clean required?
    echo "#define YOCTO_BUILD_VERSION \"${PR}\"" >> config.h
}

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

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

这编译没有问题,但我需要在板上尝试。

对于自动工具构建,我认为 do_compile 可能需要替换为 EXTRA_OECONF,但我需要尝试一下。

如果有人提出更好的方法,我将不胜感激。

感谢所有的帮助!

下面使用 sed 对此答案进行可能的进一步改进。

#include <stdio.h>
#include "config.h"

int main() {
   printf("Hello, World!\n");
   printf("Yocto build version = YOCTO_BUILD_VER");
   return 0;
}

&在 Yocto 食谱中:

PV = "0.9.1"

do_configure_prepend() {

# Amend src/buildVersion.h with Yocto Image Version for display in GUI
( cd ${S}/src;
sed -i 's/YOCTO_BUILD_VER/${PV}/' ${S}/helloworld.c; cd -)

}

我还没有测试过这个(但类似的东西确实有效),但我认为这个想法相当简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM