ulib: Provide an example of how to build with ulib
Add an example Makefile which shows how to build against U-Boot from outside the U-Boot source tree. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
18
Makefile
18
Makefile
@@ -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,19 @@ test/ulib/ulib_test_static: test/ulib/ulib_test.o libu-boot.a \
|
||||
$(LIB_STATIC_LDS) FORCE
|
||||
$(call if_changed,ulib_test_static)
|
||||
|
||||
# abspath is used since many paths are relative
|
||||
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="$(abspath $(srctree))" \
|
||||
CC="$(CC)" \
|
||||
CFLAGS="$(CFLAGS)" \
|
||||
PLATFORM_LIBS="$(PLATFORM_LIBS)" \
|
||||
LIB_STATIC_LDS="$(abspath $(LIB_STATIC_LDS))"
|
||||
|
||||
quiet_cmd_sym ?= SYM $@
|
||||
cmd_sym ?= $(OBJDUMP) -t $< > $@
|
||||
u-boot.sym: u-boot FORCE
|
||||
@@ -2339,6 +2355,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' \
|
||||
|
||||
72
examples/ulib/Makefile
Normal file
72
examples/ulib/Makefile
Normal file
@@ -0,0 +1,72 @@
|
||||
# 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)
|
||||
|
||||
# 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
|
||||
74
examples/ulib/README
Normal file
74
examples/ulib/README
Normal file
@@ -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+
|
||||
61
examples/ulib/demo.c
Normal file
61
examples/ulib/demo.c
Normal file
@@ -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;
|
||||
}
|
||||
19
examples/ulib/static.lds
Normal file
19
examples/ulib/static.lds
Normal file
@@ -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;
|
||||
Reference in New Issue
Block a user