[英]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
,甚至允许调用configure
和make
的打包脚本添加更多版本信息。 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.c
的build-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_AUTOMAKE
和AM_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.