From: Simon Glass <simon.glass@canonical.com> Refactor demo.c so it builds as a standalone sandbox binary (using ulib_init/ulib_uninit and os_* helpers) or as an example linked into U-Boot (providing a strong ulib_has_main() and main()). Extract demo_run() for the common path and use IS_ENABLED(CONFIG_SANDBOX) to gate the sandbox-specific initialisation and /proc/version reading. Update demo_helper.c to use printf() directly when built as part of U-Boot (CONFIG_ULIB) rather than the u-boot-api shim. Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- examples/ulib/demo.c | 87 +++++++++++++++++++++---------------- examples/ulib/demo_helper.c | 5 +++ test/py/tests/test_ulib.py | 10 +++-- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/examples/ulib/demo.c b/examples/ulib/demo.c index 5077fcda0a6..0dbe5d233f5 100644 --- a/examples/ulib/demo.c +++ b/examples/ulib/demo.c @@ -2,66 +2,79 @@ /* * Demo program showing U-Boot library functionality * - * This demonstrates using U-Boot library functions in sandbox like os_* - * from external programs. + * This demonstrates using U-Boot library functions from external programs + * (sandbox) or as a standalone example linked into U-Boot. * * Copyright 2025 Canonical Ltd. * Written by Simon Glass <simon.glass@canonical.com> */ -#include <inttypes.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - #include <os.h> +#include <stdio.h> #include <u-boot-lib.h> #include <version_string.h> #include "demo_helper.h" +#ifndef CONFIG_SANDBOX +bool ulib_has_main(void) +{ + return true; +} +#endif + +static const char *get_version(void) +{ + if (IS_ENABLED(CONFIG_SANDBOX)) + return ulib_get_version(); + return version_string; +} + +static int demo_run(void) +{ + demo_show_banner(); + printf("U-Boot version: %s\n", get_version()); + printf("\n"); + + demo_add_numbers(42, 13); + demo_show_footer(); + + return 0; +} + +#ifdef CONFIG_SANDBOX int main(int argc, char *argv[]) { - int fd, result, lines = 0; + int fd, lines = 0; char line[256]; + int ret; - /* Init U-Boot library */ if (ulib_init(argv[0]) < 0) { fprintf(stderr, "Failed to initialize U-Boot library\n"); return 1; } - demo_show_banner(); - printf("U-Boot version: %s\n", ulib_get_version()); - printf("\n"); + ret = demo_run(); - /* Use U-Boot's os_open to open a file */ + /* Also demonstrate using U-Boot's os_* functions to read a file */ fd = os_open("/proc/version", 0); - if (fd < 0) { - fprintf(stderr, "Failed to open /proc/version\n"); - ulib_uninit(); - return 1; - } - - printf("System version:\n"); - - /* Use U-Boot's os_fgets to read lines */ - while (os_fgets(line, sizeof(line), fd)) { - printf(" %s", line); - lines++; + if (fd >= 0) { + printf("\nSystem version:\n"); + while (os_fgets(line, sizeof(line), fd)) { + printf(" %s", line); + lines++; + } + os_close(fd); + printf("\nRead %d line(s) using U-Boot library functions.\n", + lines); } - os_close(fd); - - printf("\nRead %d line(s) using U-Boot library functions.\n", lines); - - /* Test the helper function */ - result = demo_add_numbers(42, 13); - printf("Helper function result: %d\n", result); - - demo_show_footer(); - - /* Clean up */ ulib_uninit(); - return 0; + return ret; +} +#else +int main(void) +{ + return demo_run(); } +#endif diff --git a/examples/ulib/demo_helper.c b/examples/ulib/demo_helper.c index e3a2c6bdcfb..167bbd26f64 100644 --- a/examples/ulib/demo_helper.c +++ b/examples/ulib/demo_helper.c @@ -6,7 +6,12 @@ * Written by Simon Glass <simon.glass@canonical.com> */ +#ifndef CONFIG_ULIB #include <u-boot-api.h> +#else +#include <stdio.h> +#define ub_printf printf +#endif void demo_show_banner(void) { diff --git a/test/py/tests/test_ulib.py b/test/py/tests/test_ulib.py index 9b8b7097db4..9e46d529c87 100644 --- a/test/py/tests/test_ulib.py +++ b/test/py/tests/test_ulib.py @@ -53,18 +53,22 @@ def check_demo_output(ubman, out): with open('/proc/version', 'r', encoding='utf-8') as f: proc_version = f.read().strip() + # demo.c uses U-Boot's printf (compiled with U-Boot headers) while + # demo_helper.c uses glibc's printf, so their output streams are + # buffered separately. The helper output appears first, then the + # U-Boot printf output is flushed at exit. expected = [ 'U-Boot Library Demo Helper\r', '==========================\r', - 'System version:helper: Adding 42 + 13 = 55\r', + 'helper: Adding 42 + 13 = 55\r', '=================================\r', 'Demo complete\r', - f'U-Boot version: {ubman.u_boot_version_string}', + '\r', + f'System version:U-Boot version: {ubman.u_boot_version_string}', '', f' {proc_version}', '', 'Read 1 line(s) using U-Boot library functions.', - 'Helper function result: 55', '' ] -- 2.43.0