简体   繁体   English

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

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

I've done a bit of searching but can't find an answer to this issue.我做了一些搜索,但找不到这个问题的答案。

I have a C++ GUI application that is built using Autotools in a Yocto/ Poky image.我有一个 C++ GUI 应用程序,它是在 Yocto/Poky 图像中使用 Autotools 构建的。 The PR service has been enabled & for issue tracking I'd like to incorporate the build version of the C++ application into the GUI (so the user can see it's v 0.9.1002 or similar on the GUI). PR 服务已启用并用于问题跟踪我想将 C++ 应用程序的构建版本合并到 GUI 中(以便用户可以在 GUI 上看到它的 v 0.9.1002 或类似版本)。

Is there a way of accomplishing this with a recipe or so I need to amend the Autotools files to build in the build version somehow?有没有办法通过配方来完成这个,或者我需要修改 Autotools 文件以某种方式构建构建版本?

Thanks for looking,感谢您的关注,

Edit: Thanks for the responses.编辑:感谢您的回复。

The project I put together (based on the the EGT framework) is fairly big & pulled from my repo in github with Yocto/ Bitbake.我放在一起的项目(基于EGT框架)相当大,并且是从我在 github 的存储库中使用 Yocto/Bitbake 提取的。 PV & PE I'll increment as necessary & the PR generation is supplied by Bitbake. PV & PE 我将根据需要增加, PR 生成由 Bitbake 提供。 A MRE is something like: 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();
}

And the configure.ac is similar to: 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

My Bitbake recipe is:我的 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.')
}

I am still not sure I completely understand your problem and its environment (I am completely unfamiliar with bitbake and yocto), but the following will show the package version number as an egt::Label , and even allow the packaging scripts calling configure and make to add more version information.我仍然不确定我是否完全理解您的问题及其环境(我对 bitbake 和 yocto 完全不熟悉),但以下将显示包版本号为egt::Label ,甚至允许调用configuremake的打包脚本添加更多版本信息。 HTH. 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);

This should make the label show the "1.3" version string from the second argument to AC_INIT() .这应该使标签显示来自AC_INIT()的第二个参数的"1.3"版本字符串。

And if you want to add additional version information, you can define the ADDITIONAL_VERSION_STR macro when your yocto/bitbake/whatever script/recipe/whatever build the package:如果你想添加额外的版本信息,你可以在你的 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

This should make the label show "1.3 (yocto foobar 1002)" .这应该使标签显示"1.3 (yocto foobar 1002)"

Some remarks, in more or less decreasing order of actually being related to the question:一些评论,实际上与问题相关的或多或少的递减顺序:

  • grep PACKAGE_ config.h might reveal more interesting information, especially if you read https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Initializing-configure.html and use more than two arguments to AC_INIT . grep PACKAGE_ config.h可能会揭示更多有趣的信息,特别是如果您阅读https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Initializing-configure.html并使用两个以上AC_INIT参数.

  • It can be useful to put the char build_version_string[] into its separate compilation unit (C or C++) like build-version.c with a corresponding build-version.h , as this can help avoid potentially expensive rebuilds of a potentially large main.cc file due to changes in config.h .char build_version_string[]放入其单独的编译单元(C 或 C++)中会很有用,例如带有相应 build- build-version.cbuild-version.h ,因为这可以帮助避免对潜在的大型main.cc文件由于config.h的变化。

  • This avoids macros or symbols starting with _ or __ , as those usually are reserved by C or C++ language standards.这避免了以___开头的宏或符号,因为它们通常由 C 或 C++ 语言标准保留。

  • If configure calls macros not shipped by Autoconf or Automake, I recommend to explicitly m4_pattern_forbid them.如果configure调用 Autoconf 或 Automake 未提供的宏,我建议明确地m4_pattern_forbid它们。 This will make autoreconf runs fail early, if any of the necessary m4 macros cannot be found and therefore unexpanded macro invocations like PKG_* or LT_* or AX_* might appear in the generated configure script:如果找不到任何必要的 m4 宏,这将使autoreconf运行提前失败,因此未扩展的宏调用(如PKG_*LT_*AX_*可能会出现在生成的configure脚本中:

     m4_pattern_forbid([PKG_PROG_PKG_CONFIG]) PKG_PROG_PKG_CONFIG
  • The Autoconf release 2.69 you require was released 2012-04-25.您需要的 Autoconf 版本 2.69 于 2012 年 4 月 25 日发布。 The Automake release 1.10 you require was released 2006-10-15.您需要的 Automake 版本 1.10 于 2006 年 10 月 15 日发布。 The Automake release 1.11 which introduced the silent-rules option to AM_INIT_AUTOMAKE and the AM_SILENT_RULES macro was released 2009-05-17. Automake 1.11 版向AM_INIT_AUTOMAKEAM_SILENT_RULES宏引入了silent-rules选项,于 2009 年 5 月 17 日发布。 So you can reasonably presume that any system with autoconf 2.69 will probably have an automake version which is less than three years older, and remove the conditional around AM_SILENT_RULES and just use因此,您可以合理地假设任何具有 autoconf 2.69 的系统都可能具有不到三年的 automake 版本,并删除AM_SILENT_RULES周围的条件并使用

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

    or或者

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

    instead of代替

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

    but this is starting to get off-topic.但这开始离题了。

To help others I'll post this as a suggested answer, credit goes to ndim really, this is just putting their answer into a Bitbake format.为了帮助其他人,我会将其作为建议的答案发布,这确实归功于ndim ,这只是将他们的答案放入 Bitbake 格式。 My recipe layout is as follows:我的食谱布局如下:

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

helloworld.c is based on the Yocto manual example: 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;
}

config.h:配置.h:

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

& finally helloworld_0.1.bb: & 最后是 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}
}

This compiles without issue but I need to try it on a board.这编译没有问题,但我需要在板上尝试。

For an autotools build I think the do_compile may need to be replaced with EXTRA_OECONF but I need to try it out.对于自动工具构建,我认为 do_compile 可能需要替换为 EXTRA_OECONF,但我需要尝试一下。

If anyone comes up with a better way I'd be grateful to see it.如果有人提出更好的方法,我将不胜感激。

Thanks for all the help!感谢所有的帮助!

A possible further refinement on this answer is below using sed.下面使用 sed 对此答案进行可能的进一步改进。

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

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

& in the Yocto recipe: &在 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 -)

}

I haven't tested this (but something similar does work) but I think the idea is fairly straightforward.我还没有测试过这个(但类似的东西确实有效),但我认为这个想法相当简单。

暂无
暂无

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

相关问题 C ++ PE注入-远程位置的EXE文件(例如HTTP) - C++ PE injection - EXE file from remote location (e.g. HTTP) C/C++ Open Source Project(eg SFML) 编译和运行问题 - C/C++ Open Source Project(e.g. SFML) compilation and run question 如何构建外部 C++ 库以与 R/Rcpp 一起使用(例如 Boost) - How to build an external C++ library to use with R/Rcpp (e.g. Boost) C ++文件容器(例如zip),方便访问 - C++ file container (e.g. zip) for easy access 当使用 SAST 工具时,为什么我们必须为编译语言(例如 C/C++)使用“构建包装器”? - When using a SAST tool, why do we have to use a "build wrapper" for compiled languages (e.g. C/C++)? 为什么Qt有标准C ++对象的&#39;Q&#39;版本(例如QVector,QString等)? - Why does Qt have a 'Q' version of standard C++ objects (e.g. QVector, QString, etc.)? 如何在C ++项目(IDE:Eclipse)中包含C / C ++库(例如libcurl)? - How to include a C/C++ lib (e.g. libcurl) in a C++ project (IDE: Eclipse)? 检测可移动驱动器(例如USB闪存驱动器)C / C ++ - Detect removable drive (e.g. USB flash drive) C/C++ C / C ++中的typedef是否真的通过组合复合类型(例如int *)来创建一个NEW类型? - Does typedef in C/C++ really create a NEW type by combining the compound type (e.g. int*)? C / C ++中整数类型别名的标准保证? 例如:“unsigned”是否总是等于“unsigned int”? - Standard guarantees for aliases of integer types in C/C++? E.g.: Is “unsigned” always equal to “unsigned int”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM