@@ -1048,6 +1048,9 @@ ifneq ($(cc-name),clang)
ifeq ($(NO_LIBS),)
INPUTS-$(CONFIG_ULIB) += libu-boot.so test/ulib/ulib_test
INPUTS-$(CONFIG_ULIB) += libu-boot.a test/ulib/ulib_test_static
+ifdef CONFIG_EXAMPLES
+INPUTS-$(CONFIG_ULIB) += examples_ulib
+endif
endif
endif
endif
@@ -1911,6 +1914,18 @@ test/ulib/ulib_test_static: test/ulib/ulib_test.o libu-boot.a \
$(LIB_STATIC_LDS) FORCE
$(call if_changed,ulib_test_static)
+PHONY += examples_ulib
+examples_ulib: libu-boot.a libu-boot.so FORCE
+ $(Q)$(MAKE) -C $(srctree)/examples/ulib \
+ UBOOT_BUILD=$(abspath $(obj)) \
+ EXAMPLE_DIR=. \
+ OUTDIR=$(abspath $(obj)/examples/ulib) \
+ srctree="$(srctree)" \
+ CC="$(CC)" \
+ CFLAGS="$(CFLAGS)" \
+ PLATFORM_LIBS="$(PLATFORM_LIBS)" \
+ LIB_STATIC_LDS="$(LIB_STATIC_LDS)"
+
quiet_cmd_sym ?= SYM $@
cmd_sym ?= $(OBJDUMP) -t $< > $@
u-boot.sym: u-boot FORCE
@@ -2339,6 +2354,8 @@ $(clean-dirs):
clean: $(clean-dirs)
$(call cmd,rmdirs)
$(call cmd,rmfiles)
+ @$(MAKE) -C $(srctree)/examples/ulib clean \
+ OUTDIR=$(abspath $(obj)/examples/ulib)
@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '*.ko.*' -o -name '*.su' -o -name '*.pyc' \
new file mode 100644
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Standalone Makefile for U-Boot library examples
+#
+# Copyright 2025 Canonical
+# Written by Simon Glass <simon.glass@canonical.com>
+
+# This Makefile can be used to build the examples. See doc/develop/ulib.rst
+#
+# Usage: cd examples/ulib; make UBOOT_BUILD=/tmp/b/sandbox/ srctree=../..
+#
+# This Makefile is also called from the main U-Boot Makefile when CONFIG_ULIB
+# and CONFIG_EXAMPLES are enabled. It receives these variables, many of which
+# are needed to ensure that the output goes to the right place:
+#
+# UBOOT_BUILD - Build directory (e.g., /tmp/b/sandbox)
+# EXAMPLE_DIR - Source tree path for these examples
+# OUTDIR - Output directory for object files and executables
+# srctree - U-Boot source tree
+#
+# Also these may be provided:
+# CC - C compiler
+# CFLAGS - C compiler flags
+# SDL_CONFIG - Name of sdl2-config program
+# PLATFORM_LIBS - Platform-specific libraries
+# LIB_STATIC_LDS - Linker script for static library
+
+# For standalone builds, provide default values
+EXAMPLE_DIR ?= .
+OUTDIR ?= .
+CC ?= gcc
+SDL_CONFIG ?= sdl2-config
+PLATFORM_LIBS ?= $(shell $(SDL_CONFIG) --libs)
+LIB_STATIC_LDS ?= static.lds
+# The main Makefile passes in Q=@ for quiet output
+Q ?=
+
+DEMO_SRC := $(EXAMPLE_DIR)/demo.c
+DEMO_BINS := $(OUTDIR)/demo $(OUTDIR)/demo_static
+
+# Default target builds both programs
+all: $(DEMO_BINS)
+ @echo "Build complete: demo and demo_static in $(OUTDIR)"
+
+# Create the output directory if it doesn't exist
+$(OUTDIR):
+ @mkdir -p $@
+
+# The U-Boot library must be built before we can link against it. This is
+# signalled by the presence of the $(UBOOT_BUILD)/examples/ulib directory.
+# This is an order-only prerequisite, so it does not trigger a rebuild if the
+# timestamp of the directory changes.
+$(DEMO_BINS): | $(UBOOT_BUILD)/examples/ulib $(OUTDIR)
+
+# Build demo (dynamically linked with libu-boot.so)
+$(OUTDIR)/demo: $(DEMO_SRC)
+ $(CC) $(CFLAGS) \
+ -idirafter$(srctree)/include -o $@ $< \
+ -L$(UBOOT_BUILD) -lu-boot \
+ -Wl,-rpath,$(UBOOT_BUILD)
+
+# Build demo_static (statically linked with libu-boot.a)
+$(OUTDIR)/demo_static: $(DEMO_SRC)
+ $(CC) $(CFLAGS) \
+ -idirafter$(srctree)/include -o $@ $< \
+ -Wl,-T,$(LIB_STATIC_LDS) \
+ -Wl,--whole-archive $(UBOOT_BUILD)/libu-boot.a -Wl,--no-whole-archive \
+ -lpthread -ldl $(PLATFORM_LIBS) -Wl,-z,noexecstack
+
+clean:
+ $(Q)rm -f $(DEMO_BINS)
+
+.PHONY: all clean
new file mode 100644
@@ -0,0 +1,74 @@
+U-Boot Library Example
+======================
+
+This directory contains example programs showing how to use the U-Boot library
+(libu-boot.so) in external C programs.
+
+Building U-Boot Library
+-----------------------
+
+First, build U-Boot with library support:
+
+ make O=/tmp/b/sandbox -j$(nproc) sandbox_defconfig all
+
+This creates:
+- /tmp/b/sandbox/libu-boot.so (shared library)
+- /tmp/b/sandbox/libu-boot.a (static library)
+
+Example Programs
+----------------
+
+The examples are built automatically as part of the U-Boot build. So far there
+is only one.
+
+**demo.c** - Demonstrates using U-Boot library functions
+
+- Shows how to init the library with ulib_init()
+- Uses U-Boot's OS functions (os_open(), os_fgets(), os_close())
+- Reads and displays system information
+- Shows the U-Boot version
+
+Building Examples
+-----------------
+
+The examples are built automatically when U-Boot has these options enabled::
+
+ CONFIG_ULIB=y
+ CONFIG_EXAMPLES=y
+
+To build manually:
+
+ # From this directory examples/ulib
+ make UBOOT_BUILD=/tmp/b/sandbox/ srctree=../..
+
+Running Examples
+----------------
+
+ # Run the demo
+ LD_LIBRARY_PATH=/tmp/b/sandbox ./demo
+
+ # Run the demo (static version)
+ ./demo_static
+
+Key Points
+----------
+
+- Avoid including U-Boot headers that conflict with system headers. This
+ Makefile gives priority to the system headers
+- Use ulib_init() to init the library
+- Use ulib_uninit() to clean up
+- Set LD_LIBRARY_PATH when running dynamically linked programs
+
+Copying for External Use
+-------------------------
+
+This directory can be copied elsewhere and used independently:
+
+ cp -r examples/ulib ~/my-project/
+ cd ~/my-project/ulib
+ make UBOOT_BUILD=/path/to/u-boot-build srctree=/path/to/u-boot-source
+
+License
+-------
+
+All examples are licensed under GPL-2.0+
new file mode 100644
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Demo program showing U-Boot library functionality
+ *
+ * This demonstrates using U-Boot library functions in sandbox like os_*
+ * from external programs.
+ *
+ * Copyright 2025 Canonical
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <os.h>
+#include <u-boot-lib.h>
+#include <version_string.h>
+
+int main(int argc, char *argv[])
+{
+ int fd, lines = 0;
+ char line[256];
+
+ /* Init U-Boot library */
+ if (ulib_init(argv[0]) < 0) {
+ fprintf(stderr, "Failed to initialize U-Boot library\n");
+ return 1;
+ }
+
+ printf("1U-Boot Library Demo\n");
+ printf("================================\n");
+ printf("U-Boot version: %s\n", version_string);
+ printf("\n");
+
+ /* Use U-Boot's os_open to open 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++;
+ }
+
+ os_close(fd);
+
+ printf("\nRead %d line(s) using U-Boot library functions.\n", lines);
+
+ /* Clean up */
+ ulib_uninit();
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Linker script for ulib_test_static binary
+ *
+ * This ensures proper alignment for linker-lists when linking with libu-boot.a
+ */
+
+SECTIONS
+{
+ /* Ensure proper alignment for linker lists */
+ . = ALIGN(32);
+ __u_boot_list : {
+ __u_boot_list_start = .;
+ KEEP(*(SORT(__u_boot_list*)));
+ __u_boot_list_end = .;
+ }
+}
+
+INSERT AFTER .rodata;